Skip to content

Commit

Permalink
Fix cursor.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArthurSonzogni committed Jan 21, 2025
1 parent 1a7fe5e commit c9e0b2b
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 76 deletions.
2 changes: 2 additions & 0 deletions include/ftxui/dom/requirement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define FTXUI_DOM_REQUIREMENT_HPP

#include "ftxui/screen/box.hpp"
#include "ftxui/screen/screen.hpp"

namespace ftxui {

Expand All @@ -22,6 +23,7 @@ struct Requirement {
// Focus management to support the frame/focus/select element.
bool is_focused = false;
Box focused_box;
Screen::Cursor::Shape cursor_shape = Screen::Cursor::Shape::Hidden;
};

} // namespace ftxui
Expand Down
87 changes: 43 additions & 44 deletions src/ftxui/component/slider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,53 +134,52 @@ class SliderBase : public SliderOption<T>, public ComponentBase {
return ComponentBase::OnEvent(event);
}

bool OnMouseEvent(Event event) {
if (captured_mouse_) {
if (event.mouse().motion == Mouse::Released) {
captured_mouse_ = nullptr;
return true;
}
bool OnCapturedMouseEvent(Event event) {
if (event.mouse().motion == Mouse::Released) {
captured_mouse_ = nullptr;
return true;
}

T old_value = this->value();
switch (this->direction) {
case Direction::Right: {
this->value() = this->min() + (event.mouse().x - gauge_box_.x_min) *
(this->max() - this->min()) /
(gauge_box_.x_max - gauge_box_.x_min);

T old_value = this->value();
switch (this->direction) {
case Direction::Right: {
this->value() =
this->min() + (event.mouse().x - gauge_box_.x_min) *
(this->max() - this->min()) /
(gauge_box_.x_max - gauge_box_.x_min);

break;
}
case Direction::Left: {
this->value() =
this->max() - (event.mouse().x - gauge_box_.x_min) *
(this->max() - this->min()) /
(gauge_box_.x_max - gauge_box_.x_min);
break;
}
case Direction::Down: {
this->value() =
this->min() + (event.mouse().y - gauge_box_.y_min) *
(this->max() - this->min()) /
(gauge_box_.y_max - gauge_box_.y_min);
break;
}
case Direction::Up: {
this->value() =
this->max() - (event.mouse().y - gauge_box_.y_min) *
(this->max() - this->min()) /
(gauge_box_.y_max - gauge_box_.y_min);
break;
}
break;
}
case Direction::Left: {
this->value() = this->max() - (event.mouse().x - gauge_box_.x_min) *
(this->max() - this->min()) /
(gauge_box_.x_max - gauge_box_.x_min);
break;
}
case Direction::Down: {
this->value() = this->min() + (event.mouse().y - gauge_box_.y_min) *
(this->max() - this->min()) /
(gauge_box_.y_max - gauge_box_.y_min);
break;
}
case Direction::Up: {
this->value() = this->max() - (event.mouse().y - gauge_box_.y_min) *
(this->max() - this->min()) /
(gauge_box_.y_max - gauge_box_.y_min);
break;
}
}

this->value() =
std::max(this->min(), std::min(this->max(), this->value()));
this->value() = std::max(this->min(), std::min(this->max(), this->value()));

if (old_value != this->value() && this->on_change) {
this->on_change();
}
return true;
if (old_value != this->value() && this->on_change) {
this->on_change();
}
return true;
}

bool OnMouseEvent(Event event) {
if (captured_mouse_) {
return OnCapturedMouseEvent(event);
}

if (event.mouse().button != Mouse::Left) {
Expand All @@ -198,7 +197,7 @@ class SliderBase : public SliderOption<T>, public ComponentBase {

if (captured_mouse_) {
TakeFocus();
return true;
return OnCapturedMouseEvent(event);
}

return false;
Expand Down
10 changes: 3 additions & 7 deletions src/ftxui/dom/frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,9 @@ class FocusCursor : public Focus {
: Focus(std::move(children)), shape_(shape) {}

private:
void Render(Screen& screen) override {
Focus::Render(screen); // NOLINT
screen.SetCursor(Screen::Cursor{
box_.x_min,
box_.y_min,
shape_,
});
void ComputeRequirement() override {
Focus::ComputeRequirement(); // NOLINT
requirement_.cursor_shape = shape_;
}
Screen::Cursor::Shape shape_;
};
Expand Down
2 changes: 2 additions & 0 deletions src/ftxui/dom/hbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class HBox : public Node {
requirement_.flex_shrink_x = 0;
requirement_.flex_shrink_y = 0;
requirement_.is_focused = false;
requirement_.cursor_shape = Screen::Cursor::Shape::Hidden;
int index = 0;
for (auto& child : children_) {
child->ComputeRequirement();
Expand All @@ -40,6 +41,7 @@ class HBox : public Node {
requirement_.focused_box = child->requirement().focused_box;
requirement_.focused_box.x_min += requirement_.min_x;
requirement_.focused_box.x_max += requirement_.min_x;
requirement_.cursor_shape = child->requirement().cursor_shape;
}
requirement_.min_x += child->requirement().min_x;
requirement_.min_y =
Expand Down
59 changes: 34 additions & 25 deletions src/ftxui/dom/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,31 +88,6 @@ void Render(Screen& screen, Node* node, Selection& selection) {
box.x_max = screen.dimx() - 1;
box.y_max = screen.dimy() - 1;

// Setting the cursor to the right position allow folks using CJK (China,
// Japanese, Korean, ...) characters to see their [input method editor]
// displayed at the right location. See [issue].
//
// [input method editor]:
// https://en.wikipedia.org/wiki/Input_method
//
// [issue]:
// https://github.com/ArthurSonzogni/FTXUI/issues/2#issuecomment-505282355
//
// Unfortunately, Microsoft terminal do not handle properly hidding the
// cursor. Instead the character under the cursor is hidden, which is a big
// problem. As a result, we can't enable setting cursor to the right
// location. It will be displayed at the bottom right corner.
// See:
// https://github.com/microsoft/terminal/issues/1203
// https://github.com/microsoft/terminal/issues/3093
#if !defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
screen.SetCursor(Screen::Cursor{
box.x_min,
box.y_min,
Screen::Cursor::Shape::Hidden,
});
#endif

Node::Status status;
node->Check(&status);
const int max_iterations = 20;
Expand All @@ -134,6 +109,40 @@ void Render(Screen& screen, Node* node, Selection& selection) {
node->Select(selection);
}

// Setting the cursor to the right position allow folks using CJK (China,
// Japanese, Korean, ...) characters to see their [input method editor]
// displayed at the right location. See [issue].
//
// [input method editor]:
// https://en.wikipedia.org/wiki/Input_method
//
// [issue]:
// https://github.com/ArthurSonzogni/FTXUI/issues/2#issuecomment-505282355
//
// Unfortunately, Microsoft terminal do not handle properly hiding the
// cursor. Instead the character under the cursor is hidden, which is a big
// problem. As a result, we can't enable setting cursor to the right
// location. It will be displayed at the bottom right corner.
// See:
// https://github.com/microsoft/terminal/issues/1203
// https://github.com/microsoft/terminal/issues/3093
const Requirement requirement = node->requirement();
int cursor_x = requirement.focused_box.x_max;
int cursor_y = requirement.focused_box.y_max;
if (!requirement.is_focused
#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
|| requirement.cursor_shape == Screen::Cursor::Shape::Hidden
#endif
) {
cursor_x = box.x_max;
cursor_y = box.y_max;
}
screen.SetCursor(Screen::Cursor{
cursor_x,
cursor_y,
requirement.cursor_shape,
});

// Step 4: Draw the element.
screen.stencil = box;
node->Render(screen);
Expand Down
2 changes: 2 additions & 0 deletions src/ftxui/dom/vbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class VBox : public Node {
requirement_.flex_shrink_x = 0;
requirement_.flex_shrink_y = 0;
requirement_.is_focused = false;
requirement_.cursor_shape = Screen::Cursor::Shape::Hidden;
int index = 0;
for (auto& child : children_) {
child->ComputeRequirement();
Expand All @@ -40,6 +41,7 @@ class VBox : public Node {
requirement_.focused_box = child->requirement().focused_box;
requirement_.focused_box.y_min += requirement_.min_y;
requirement_.focused_box.y_max += requirement_.min_y;
requirement_.cursor_shape = child->requirement().cursor_shape;
}
requirement_.min_y += child->requirement().min_y;
requirement_.min_x =
Expand Down

0 comments on commit c9e0b2b

Please sign in to comment.