-
-
Notifications
You must be signed in to change notification settings - Fork 90
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
library: Add Check Button demo #337
Conversation
So I think what you'll have to do is store a bit of state in an object/dictionary. Usually you'd have GSettings for this stuff somewhere, or state in your application. These aren't used very often anymore, but they usually happen in a situation like this:
It's not really important how you store the state for the demo, but something like this could work: const state = {
'checkbox': 0.5,
'checkbox_child1': 1.0,
'checkbox_child2': 0.0,
};
This is the only tricky part about this, because you have to return the checkboxes to their original state. So my suggestion would be use the actual checkbox In other words, if the parent is toggled you should only update Does that makes sense? |
@andyholmes could you help @AkshayWarrier with this one? |
Here's what I came up with, but check it out because I may have missed a corner case: import GObject from "gi://GObject";
const checkbox_all = workbench.builder.get_object("checkbox_all");
const checkbox2 = workbench.builder.get_object("checkbox2");
const checkbox3 = workbench.builder.get_object("checkbox3");
// Define some mock settings and perform setup
const settings = {
checkbox_all: false,
checkbox2: false,
checkbox3: true,
};
checkbox_all.active = settings.checkbox_all;
checkbox_all.inconsistent = settings.checkbox2 !== settings.checkbox3;
checkbox2.active = settings.checkbox2;
checkbox3.active = settings.checkbox3;
/* GNOME HIG for inconsistent checkbox states
*
* Behaviour pattern starts from an inconsistent state
*/
function toggleAllCallback(checkbutton) {
console.log(`toggleAllCallback(${checkbutton.label})`);
GObject.signal_handlers_block_by_func(checkbox2, toggleOneCallback);
GObject.signal_handlers_block_by_func(checkbox3, toggleOneCallback);
// Once: check the box and apply the setting to all the
// selected objects.
if (!settings.checkbox_all && checkbox_all.inconsistent) {
checkbox_all.active = true;
checkbox_all.inconsistent = false;
checkbox2.active = true;
checkbox3.active = true;
// Twice: uncheck the box and unset the setting to all
// the selected objects.
} else if (settings.checkbox_all && !checkbox_all.inconsistent) {
checkbox_all.active = false;
checkbox_all.inconsistent = false;
checkbox2.active = false;
checkbox3.active = false;
// Three times: return the box to its mixed state, restoring
// each selected object’s original value for that setting.
} else {
checkbox_all.active = settings.checkbox2 && settings.checkbox2;
checkbox_all.inconsistent = settings.checkbox2 !== settings.checkbox3;
checkbox2.active = settings.checkbox2;
checkbox3.active = settings.checkbox3;
}
// Update the mock setting
settings.checkbox_all = checkbox_all.active;
GObject.signal_handlers_unblock_by_func(checkbox2, toggleOneCallback);
GObject.signal_handlers_unblock_by_func(checkbox3, toggleOneCallback);
}
function toggleOneCallback(checkbutton) {
console.log(`toggleOneCallback(${checkbutton.label})`);
GObject.signal_handlers_block_by_func(checkbox_all, toggleAllCallback);
if (checkbox2.active && checkbox3.active) {
settings.checkbox_all = true;
checkbox_all.active = true;
checkbox_all.inconsistent = false;
} else if (checkbox2.active || checkbox3.active) {
settings.checkbox_all = false;
checkbox_all.active = false;
checkbox_all.inconsistent = true;
} else {
settings.checkbox_all = false;
checkbox_all.active = false;
checkbox_all.inconsistent = false;
}
// Update the mock settings
settings.checkbox2 = checkbox2.active;
settings.checkbox3 = checkbox3.active;
GObject.signal_handlers_unblock_by_func(checkbox_all, toggleAllCallback);
}
checkbox_all.connect("toggled", toggleAllCallback);
checkbox2.connect("toggled", toggleOneCallback);
checkbox3.connect("toggled", toggleOneCallback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks almost good to go, now that we're waiting on the "inconsistent" state. Let's get this one cleaned up for the standard use and merge what we have.
I decided to individually log the states of the checkboxes to show their independence from each other, also it makes the demo more copiable :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty much good to go.
A few formatting cleanups, also the last LinkButton
I couldn't add a suggestion for, but the properties need to be indented.
After that looks good.
Co-authored-by: Andy Holmes <1265208+andyholmes@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well done, very clean and understandable. 👍
* library: Add Check Button demo * Check Button: Attempt at making inconsistent checkbox work * Check Button: Removed inconsistent buttons because they were inconsistent :) * Apply suggestions from code review Co-authored-by: Andy Holmes <1265208+andyholmes@users.noreply.github.com> * Minor change * Another minor change * Last one --------- Co-authored-by: Andy Holmes <1265208+andyholmes@users.noreply.github.com>
Closes #336
Right now the inconsistent checkbox is not functioning properly, after it has completed one cycle of inconsistent -> on -> off -> inconsistent, the next time the check button turns on "Mark as Done: On" is logged twice because of
checkbutton3.active = true
under case 0, the button triggers::toggled
again.A review would be appreciated.