Skip to content

Commit

Permalink
gui2/ttext_: Add a public method for setting the selection range
Browse files Browse the repository at this point in the history
Unlike the internal (protected) methods, this makes sure to call
update_canvas() when done so that e.g. text_box's highlight rectangle
is properly updated on the canvas with the right variables so that it's
drawn after we're done handling events.
  • Loading branch information
irydacea committed Oct 5, 2016
1 parent 0f83718 commit 3fa0fc9
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/gui/widgets/text.cpp
Expand Up @@ -23,6 +23,8 @@

#include "utils/functional.hpp"

#include <limits>

#define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
#define LOG_HEADER LOG_SCOPE_HEADER + ':'

Expand Down Expand Up @@ -197,6 +199,38 @@ void ttext_::set_selection_length(const int selection_length)
}
}

void ttext_::set_selection(size_t start, int length)
{
const size_t text_size = text_.get_length();

if(start >= text_size) {
start = text_size;
}

if(length == 0) {
set_cursor(start, false);
return;
}

// The text pos/size type differs in both signedness and size with the
// selection length. Such is life.
const int sel_start = std::min<size_t>(start, std::numeric_limits<int>::max());
const int sel_max_length = std::min<size_t>(text_size - start, std::numeric_limits<int>::max());

const bool backwards = length < 0;

if(backwards && -length > sel_start) {
length = -sel_start;
} else if(!backwards && length > sel_max_length) {
length = sel_max_length;
}

set_selection_start(start);
set_selection_length(length);

update_canvas();
}

void ttext_::set_state(const tstate state)
{
if(state != state_) {
Expand Down
22 changes: 22 additions & 0 deletions src/gui/widgets/text.hpp
Expand Up @@ -90,6 +90,28 @@ class ttext_ : public tcontrol
text_changed_callback_ = cb;
}

/**
* Sets or clears the text selection.
*
* Setting the selection range will re-position the cursor depending on the
* selection direction, specified by the length's sign. Selecting beyond the
* start or end of the text is safe; the final selection will be limited
* accordingly.
*
* @note The range extents are measured in Unicode characters, not bytes.
* Using byte offsets may produce unexpected results depending on the
* text contents.
*
* @param start Start offset, in characters.
* @param length Selection length, in characters. If zero, the
* current selection is canceled. If negative, the
* selection extends towards the start of the text
* and the cursor will be re-positioned in that
* direction as well; otherwise the selection and
* cursor extend towards the end.
*/
void set_selection(size_t start, int length);

protected:
/**
* Moves the cursor to the end of the line.
Expand Down

0 comments on commit 3fa0fc9

Please sign in to comment.