Dillo
Public Types | Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
dw::core::SelectionState Class Reference

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

#include <selection.hh>

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. More...
 

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. More...
 
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. More...
 
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. More...
 

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):

dot_inline_dotgraph_15.png

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

Links are handled by a different state machine:

dot_inline_dotgraph_16.png

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 ( )

References DBG_OBJ_CREATE, and layout.

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

References DBG_OBJ_DELETE.

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(), dw::core::DeepIterator::createVariant(), dw::core::DeepIterator::highlight(), and dw::core::HIGHLIGHT_SELECTION.

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 
)
staticprivate
bool dw::core::SelectionState::handleEvent ( EventType  eventType,
Iterator it,
int  charPos,
int  linkNo,
MousePositionEvent event 
)
void dw::core::SelectionState::highlight ( bool  fl,
int  dir 
)
inlineprivate

References highlight0().

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

References layout.

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.

Member Data Documentation

DeepIterator* dw::core::SelectionState::from
private
int dw::core::SelectionState::fromChar
private
Layout* dw::core::SelectionState::layout
private

Referenced by setLayout().

DeepIterator* dw::core::SelectionState::link
private
int dw::core::SelectionState::linkButton
private
int dw::core::SelectionState::linkChar
private
int dw::core::SelectionState::linkNumber
private
enum { ... } dw::core::SelectionState::linkState
enum { ... } dw::core::SelectionState::selectionState
DeepIterator * dw::core::SelectionState::to
private
int dw::core::SelectionState::toChar
private

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