dw::core::SelectionState Class Reference

This class handles selections, as well as activation of links, which is closely related. More...

#include <selection.hh>

List of all members.

Public Types

enum  { END_OF_WORD = 1 << 30 }
enum  EventType { BUTTON_PRESS, BUTTON_RELEASE, BUTTON_MOTION }

Public Member Functions

 SelectionState ()
 ~SelectionState ()
void setLayout (Layout *layout)
void reset ()
bool buttonPress (Iterator *it, int charPos, int linkNo, EventButton *event)
bool buttonRelease (Iterator *it, int charPos, int linkNo, EventButton *event)
bool buttonMotion (Iterator *it, int charPos, int linkNo, EventMotion *event)
bool handleEvent (EventType eventType, Iterator *it, int charPos, int linkNo, MousePositionEvent *event)
 General form of dw::core::SelectionState::buttonPress, dw::core::SelectionState::buttonRelease and dw::core::SelectionState::buttonMotion.

Private Types

enum  { NONE, SELECTING, SELECTED }
enum  { LINK_NONE, LINK_PRESSED }

Private Member Functions

void resetSelection ()
void resetLink ()
void switchLinkToSelection (Iterator *it, int charPos)
 This method is called when the user decides not to activate a link, but instead select text.
void adjustSelection (Iterator *it, int charPos)
 This method is used by core::dw::SelectionState::buttonMotion and core::dw::SelectionState::buttonRelease, and changes the second limit of the already existing selection region.
void highlight (bool fl, int dir)
void highlight0 (bool fl, DeepIterator *from, int fromChar, DeepIterator *to, int toChar, int dir)
void copy ()

Static Private Member Functions

static int correctCharPos (DeepIterator *it, int charPos)
 This method deals especially with the case that a widget passes dw::core::SelectionState::END_OF_WORD.

Private Attributes

Layoutlayout
enum
dw::core::SelectionState:: { ... }  
selectionState
DeepIteratorfrom
DeepIteratorto
int fromChar
int toChar
enum
dw::core::SelectionState:: { ... }  
linkState
int linkButton
DeepIteratorlink
int linkChar
int linkNumber


Detailed Description

This class handles selections, as well as activation of links, which is closely related.

General Overview

dw::core::SelectionState is associated with dw::core::Layout. The selection state is controlled by "abstract events", which are sent by single widgets by calling one of the following methods:

The widget must construct simple iterators (dw::core::Iterator), which will be transferred to deep iterators (dw::core::DeepIterator), see below for more details. All event handling methods have the same signature, the arguments in detail are:

dw::core::Iterator *it the iterator pointing on the item under the mouse pointer; this iterator must be created with dw::core::Content::SELECTION_CONTENT as mask
int charPos the exact (character) position within the iterator,
int linkNo if this item is associated with a link, its number (see dw::core::Layout::LinkReceiver), otherwise -1
dw::core::EventButton *event the event itself; only the button is used

Look also at dw::core::SelectionState::handleEvent, which may be useful in some circumstances.

In some cases, charPos would be difficult to determine. E.g., when the dw::Textblock widget decides that the user is pointing on a position at the end of an image (DwImage), it constructs a simple iterator pointing on this image widget. In a simple iterator, that fact that the pointer is at the end, would be represented by charPos == 1. But when transferring this simple iterator into an deep iterator, this simple iterator is discarded and instead the stack has an iterator pointing to text at the top. As a result, only the first letter of the ALT text would be copied.

To avoid this problem, widgets should in this case pass dw::core::SelectionState::END_OF_WORD as charPos, which is then automatically reduced to the actual length of the deep(!) iterator.

The return value is the same as in DwWidget event handling methods. I.e., in most cases, they should simply return it. The events dw::core::Layout::LinkReceiver::press, dw::core::Layout::LinkReceiver::release and dw::core::Layout::LinkReceiver::click (but not dw::core::Layout::LinkReceiver::enter) are emitted by these methods, so that widgets which let dw::core::SelectionState handle links, should only emit dw::core::Layout::LinkReceiver::enter for themselves.

Selection State

Selection interferes with handling the activation of links, so the latter is also handled by the dw::core::SelectionState. Details are based on following guidelines:

  1. It should be simple to select links and to start selection in links. The rule to distinguish between link activation and selection is that the selection starts as soon as the user leaves the link. (This is, IMO, a useful feature. Even after drag and drop has been implemented in dillo, this should be somehow preserved.)

  2. The selection should stay as long as possible, i.e., the old selection is only cleared when a new selection is started.

The latter leads to a model with two states: the selection state and the link handling state.

The general selection works, for events not pointing on links, like this (numbers in parantheses after the event denote the button, "n" means arbitrary button):

inline_dotgraph_13.dot

The selected region is represented by two instances of dw::core::DeepIterator.

Links are handled by a different state machine:

inline_dotgraph_14.dot

Switching selection simply means that the selection state will eventually be SELECTED/SELECTING, with the original and the current position making up the selection region. This happens for button 1, events with buttons other than 1 do not affect selection at all.

Todo:
dw::core::SelectionState::buttonMotion currently always assumes that button 1 has been pressed (since otherwise it would not do anything). This should be made a bit cleaner.
Todo:
The selection should be cleared, when the user selects something somewhere else (perhaps switched into "non-active" mode, as e.g. Gtk+ does).

Member Enumeration Documentation

anonymous enum

Enumerator:
END_OF_WORD 

anonymous enum [private]

Enumerator:
NONE 
SELECTING 
SELECTED 

anonymous enum [private]

Enumerator:
LINK_NONE 
LINK_PRESSED 

Enumerator:
BUTTON_PRESS 
BUTTON_RELEASE 
BUTTON_MOTION 


Constructor & Destructor Documentation

dw::core::SelectionState::SelectionState (  ) 

dw::core::SelectionState::~SelectionState (  ) 

References reset().


Member Function Documentation

void dw::core::SelectionState::adjustSelection ( Iterator it,
int  charPos 
) [private]

This method is used by core::dw::SelectionState::buttonMotion and core::dw::SelectionState::buttonRelease, and changes the second limit of the already existing selection region.

References dw::core::DeepIterator::compareTo(), correctCharPos(), dw::core::DeepIterator::createVariant(), END_OF_WORD, from, highlight(), dw::core::DeepIterator::highlight(), highlight0(), dw::core::HIGHLIGHT_SELECTION, to, and toChar.

Referenced by buttonMotion(), and buttonRelease().

bool dw::core::SelectionState::buttonMotion ( Iterator it,
int  charPos,
int  linkNo,
EventMotion event 
)

bool dw::core::SelectionState::buttonPress ( Iterator it,
int  charPos,
int  linkNo,
EventButton event 
)

bool dw::core::SelectionState::buttonRelease ( Iterator it,
int  charPos,
int  linkNo,
EventButton event 
)

void dw::core::SelectionState::copy (  )  [private]

int dw::core::SelectionState::correctCharPos ( DeepIterator it,
int  charPos 
) [static, private]

bool dw::core::SelectionState::handleEvent ( EventType  eventType,
Iterator it,
int  charPos,
int  linkNo,
MousePositionEvent event 
)

void dw::core::SelectionState::highlight ( bool  fl,
int  dir 
) [inline, private]

void dw::core::SelectionState::highlight0 ( bool  fl,
DeepIterator from,
int  fromChar,
DeepIterator to,
int  toChar,
int  dir 
) [private]

void dw::core::SelectionState::reset (  ) 

void dw::core::SelectionState::resetLink (  )  [private]

void dw::core::SelectionState::resetSelection (  )  [private]

void dw::core::SelectionState::setLayout ( Layout layout  )  [inline]

void dw::core::SelectionState::switchLinkToSelection ( Iterator it,
int  charPos 
) [private]

This method is called when the user decides not to activate a link, but instead select text.

References dw::core::DeepIterator::cloneDeepIterator(), correctCharPos(), dw::core::DeepIterator::createVariant(), from, fromChar, highlight(), link, linkChar, resetLink(), resetSelection(), SELECTING, selectionState, to, and toChar.

Referenced by buttonMotion(), and buttonRelease().


Member Data Documentation

Referenced by buttonPress(), and buttonRelease().

enum { ... } dw::core::SelectionState::linkState [private]


The documentation for this class was generated from the following files:

Generated on Wed Sep 7 02:00:37 2011 for Dillo by  doxygen 1.5.9