Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] Clicking on a Checkbox should give focus to the checkbox. #959

Open
rerdavies opened this issue Nov 28, 2024 · 2 comments
Open

[bug] Clicking on a Checkbox should give focus to the checkbox. #959

rerdavies opened this issue Nov 28, 2024 · 2 comments

Comments

@rerdavies
Copy link

rerdavies commented Nov 28, 2024

Clicking on a Checkbox should give focus to the checkbox. It's a particularly unpleasant UX experience, because of the current ambiguity between rendering of focus state and hover state in checkboxes.

Having TWO checkboxes in apparent focused state is unsettling to begin with (one actually actually focused, and the other actually in hover state). It would be mostly forgivable if the focus issue were to resolve itself after a mouse click. Failing to clear focus on the non-hover Checkbox after a mouse click feels like a serious bug, and it is. Because it happens so often, it violates users' trust, giving them the strong impression that they're dealing with buggy software that can't be relied upon..

It doubly sucks for me, because I'm using your library to perform initial setup of a large package, and the very first impression users are going to get is that of broken checkboxes that are controlling settins for kernel commandline arguments! If there were ever a situation where violation of trust really counts, that would be it.

A one line fix:

Checkbox.cpp:71

  if (event.mouse().button == Mouse::Left &&
        event.mouse().motion == Mouse::Pressed) {
      *checked = !*checked;
      TakeFocus();   // <--- ADD THIS LINE
      on_change();
      return true;
    }

Not immediately clear whether it should actually be handled in ComponentBase instead. I'll let you be the judge of that. But Button should probably take focus on a mouse click as well (it does not currently). And Radiobuttons. And dropdowns. &c. The advantage of doing it this way is that it's nice to get state changes out of the way before potentially firing any events (in future implementations).

Note that handling it in a CheckBoxOptions::on_change handler is unworkable, since there's no sensible way for the lambda to capture a pointer to a Component that has not yet been created. You might want to think about changing CheckboxOptions::on_change from

  std::function<void()> on_change = [] {};

to

  std::function<bool(ComponentBase::ptr component)> on_change = [] (ComponentBase::ptr component) { return false; };

if you ever do a major release that has breaking changes.

@ArthurSonzogni
Copy link
Owner

Hello @rerdavies

Swapping the lines:

      on_change();
      TakeFocus();

sounds like a good idea to me!

Would you like to make a PR for the elements you described?


Note that handling it in a CheckBoxOptions::on_change handler is unworkable, since there's no sensible way for the lambda to capture a pointer to a Component that has not yet been created. You might want to think about changing CheckboxOptions::on_change from

I don't want to change it, because it would make it difficult for users to assign a lambda.

Maybe we could introduce some global:

// The component that is currently calling a callback.
// For instance MenuOption::on_change.
static ComponentBase::Active();

and we would call it like this:

  ScopedActiveComponent(this);
  on_change();

@rerdavies
Copy link
Author

rerdavies commented Dec 1, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants