aboutsummaryrefslogtreecommitdiff
path: root/src/ui/controls
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/controls')
-rw-r--r--src/ui/controls/text_box.cpp70
-rw-r--r--src/ui/controls/text_box.h8
-rw-r--r--src/ui/controls/text_control.cpp13
3 files changed, 73 insertions, 18 deletions
diff --git a/src/ui/controls/text_box.cpp b/src/ui/controls/text_box.cpp
index 30b9069a..54b2f7ab 100644
--- a/src/ui/controls/text_box.cpp
+++ b/src/ui/controls/text_box.cpp
@@ -67,16 +67,47 @@ namespace cru::ui::controls
Control::OnKeyDownCore(args);
if (args.GetVirtualCode() == VK_LEFT && caret_position_ > 0)
{
- ClearSelection();
- caret_position_--;
+ if (IsKeyDown(VK_SHIFT))
+ {
+ if (GetCaretSelectionSide())
+ ShiftLeftSelectionRange(-1);
+ else
+ ShiftRightSelectionRange(-1);
+ }
+ else
+ {
+ const auto selection = GetSelectedRange();
+ if (selection.has_value())
+ {
+ ClearSelection();
+ caret_position_ = selection.value().position;
+ }
+ else
+ caret_position_--;
+ }
Repaint();
}
if (args.GetVirtualCode() == VK_RIGHT && caret_position_ < GetText().size())
{
- ClearSelection();
- caret_position_++;
- Repaint();
+ if (IsKeyDown(VK_SHIFT))
+ {
+ if (GetCaretSelectionSide())
+ ShiftLeftSelectionRange(1);
+ else
+ ShiftRightSelectionRange(1);
+ }
+ else
+ {
+ const auto selection = GetSelectedRange();
+ if (selection.has_value())
+ {
+ ClearSelection();
+ caret_position_ = selection.value().position + selection.value().count;
+ }
+ else
+ caret_position_++;
+ }
}
}
@@ -138,4 +169,33 @@ namespace cru::ui::controls
caret_position_ = position;
Repaint();
}
+
+ bool TextBox::GetCaretSelectionSide() const
+ {
+ const auto selection = TextRange::ToTwoSides(GetSelectedRange(), caret_position_);
+ if (selection.first == caret_position_)
+ return true;
+ if (selection.second == caret_position_)
+ return false;
+ assert(false);
+ return true;
+ }
+
+ void TextBox::ShiftLeftSelectionRange(const int count)
+ {
+ const auto selection_range_side = TextRange::ToTwoSides(GetSelectedRange(), caret_position_);
+ int new_left = selection_range_side.first + count;
+ new_left = new_left < 0 ? 0 : new_left; // at least 0
+ caret_position_ = new_left;
+ SetSelectedRange(TextRange::FromTwoSides(static_cast<unsigned>(new_left), selection_range_side.second));
+ }
+
+ void TextBox::ShiftRightSelectionRange(const int count)
+ {
+ const auto selection_range_side = TextRange::ToTwoSides(GetSelectedRange(), caret_position_);
+ int new_right = selection_range_side.second + count;
+ new_right = new_right < 0 ? 0 : new_right; // at least 0
+ caret_position_ = new_right;
+ SetSelectedRange(TextRange::FromTwoSides(selection_range_side.first, static_cast<unsigned>(new_right)));
+ }
}
diff --git a/src/ui/controls/text_box.h b/src/ui/controls/text_box.h
index 540ac758..37e04835 100644
--- a/src/ui/controls/text_box.h
+++ b/src/ui/controls/text_box.h
@@ -36,7 +36,13 @@ namespace cru::ui::controls
void OnKeyDownCore(events::KeyEventArgs& args) override final;
void OnCharCore(events::CharEventArgs& args) override final;
- void RequestChangeCaretPosition(unsigned position) override;
+ void RequestChangeCaretPosition(unsigned position) override final;
+
+ private:
+ // return true if left
+ bool GetCaretSelectionSide() const;
+ void ShiftLeftSelectionRange(int count);
+ void ShiftRightSelectionRange(int count);
private:
unsigned caret_position_ = 0;
diff --git a/src/ui/controls/text_control.cpp b/src/ui/controls/text_control.cpp
index ee5b253d..3c5d7c33 100644
--- a/src/ui/controls/text_control.cpp
+++ b/src/ui/controls/text_control.cpp
@@ -162,18 +162,7 @@ namespace cru::ui::controls
{
const auto hit_test_result = TextLayoutHitTest(text_layout_.Get(), args.GetPoint(this), false).value();
RequestChangeCaretPosition(hit_test_result);
- if (hit_test_result > mouse_down_position_)
- {
- selected_range_ = TextRange(mouse_down_position_, hit_test_result - mouse_down_position_);
- }
- else if (hit_test_result < mouse_down_position_)
- {
- selected_range_ = TextRange(hit_test_result, mouse_down_position_ - hit_test_result);
- }
- else
- {
- selected_range_ = std::nullopt;
- }
+ selected_range_ = TextRange::FromTwoSides(hit_test_result, mouse_down_position_);
Repaint();
}
}