Checkbox checkmark is not updated when linking controls. #347
Replies: 20 comments
-
I suggest either 1) placing the controls in a composite (e.g. a pane or something) and refreshing the whole composite |
Beta Was this translation helpful? Give feedback.
-
Thanks!
I will try it out.
Bill Berry
…On Thu, Jul 9, 2020 at 5:01 PM Joel de Guzman ***@***.***> wrote:
I suggest either 1) placing the controls in a composite (e.g. a pane or
something) and refreshing the whole composite window_view.refresh(a_pane)
or 2) simply refreshing the whole view window_view.refresh().
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#179 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOKC7SW6TMGDGXCVKAOD6LR2Y42BANCNFSM4OV7VUTA>
.
|
Beta Was this translation helpful? Give feedback.
-
Feel free to ask more questions, or even suggest improvements. |
Beta Was this translation helpful? Give feedback.
-
@wsberry were you able to solve your issue? Is it good to close this now? |
Beta Was this translation helpful? Give feedback.
-
I was working on a presentation for work and will be trying the fix later
this week.
Thanks
Bill
…On Tue, Jul 14, 2020 at 6:21 PM Joel de Guzman ***@***.***> wrote:
@wsberry <https://github.com/wsberry> were you able to solve your issue?
Is it good to close this now?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#179 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOKC7VDNFRBIQZ3DYRU4E3R3TSAJANCNFSM4OV7VUTA>
.
|
Beta Was this translation helpful? Give feedback.
-
Joel,
The following did not work:
check_box1.on_click =
[&](bool) mutable
{
check_box1.value(!check_box1.value());
// Does not work:
window_view.refresh();
// also does not work
window_view.refresh(check_box1);
}
I did not have time to test a 'panel' since I need to look up how to use
it...i.e. I was hoping to do something like this:
check_box_panel =
top_margin(25,
vtile(
top_margin(10, align_left(check_box1)),
top_margin(10, align_left(check_box2)),
top_margin(10, align_left(check_box3))
)
);
The above code is not supported. I plan to take a look at this tomorrow
when I have more time.
Also, I will have time to trace through the code tomorrow to see why a
standard refresh won't work on the control itself. This will give me an
opportunity to learn better what I am doing with the elements framework.
Thanks,
Bill Berry
…On Tue, Jul 14, 2020 at 8:56 PM William Berry ***@***.***> wrote:
I was working on a presentation for work and will be trying the fix later
this week.
Thanks
Bill
On Tue, Jul 14, 2020 at 6:21 PM Joel de Guzman ***@***.***>
wrote:
> @wsberry <https://github.com/wsberry> were you able to solve your issue?
> Is it good to close this now?
>
> —
> You are receiving this because you were mentioned.
>
>
> Reply to this email directly, view it on GitHub
> <#179 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ABOKC7VDNFRBIQZ3DYRU4E3R3TSAJANCNFSM4OV7VUTA>
> .
>
|
Beta Was this translation helpful? Give feedback.
-
Hrmmm... Well, if you post an MVCE (as minimal as you can get it to be), I can try it out myself to see what's happening. The view refresh mechanism should work. The radio buttons and menus do something similar to what you are doing. |
Beta Was this translation helpful? Give feedback.
-
@wsberry is this still an issue and will you post an MVCE if it is? |
Beta Was this translation helpful? Give feedback.
-
Yes I had looked into and your prior suggestions did not work for me.
I am using elements to write some support tools so fixing it has been on
the bottom of my list. I.e. I am tracing through the problem during some of
break times.
This said I can certainly post an MVCE and will try to do so today.
Bill Berry
…On Wed, Aug 26, 2020 at 2:13 AM Joel de Guzman ***@***.***> wrote:
@wsberry <https://github.com/wsberry> is this still an issue and will you
post an MVCE if it is?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#179 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOKC7U4OBAGZQBV3ZJYVYTSCSYX5ANCNFSM4OV7VUTA>
.
|
Beta Was this translation helpful? Give feedback.
-
Appreciated! |
Beta Was this translation helpful? Give feedback.
-
Any update? |
Beta Was this translation helpful? Give feedback.
-
Joel,
Attached is a minimal test program. I have not had the time to debug the
code but will if some time frees up for me.
I did try your earlier suggestions but none of them worked.
Thanks
Bill Berry
On Sun, Sep 13, 2020 at 7:25 AM Joel de Guzman ***@***.***> wrote:
Any update?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#179 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOKC7RAUFNVRCFPXS3COI3SFS22LANCNFSM4OV7VUTA>
.
#include <string>
#include <iostream>
#include <elements.hpp>
namespace colors
{
constexpr auto default_dark = cycfi::elements::rgba(32, 32, 32,/*alpha:*/155);
auto constexpr bkd_color = colors::default_dark;
}
// Basic check box type
//
using check_box_t = cycfi::elements::basic_toggle_button<cycfi::elements::proxy<cycfi::elements::check_box_element, cycfi::elements::basic_button>>;
class test_options_dialog final
{
const cycfi::elements::box_element background = cycfi::elements::box(colors::bkd_color);
check_box_t check_box1 = cycfi::elements::check_box("A");
check_box_t check_box2 = cycfi::elements::check_box("B");
check_box_t check_box3 = cycfi::elements::check_box("C");
check_box_t check_box_select_all = cycfi::elements::check_box("Select All");
void run_selected_options() const
{
using namespace cycfi::elements;
std::string args = "-ignore";
if (check_box1.value())
{
std::cout << "1 selected\n";
}
if (check_box2.value())
{
std::cout << "2 selected\n";
}
if (check_box3.value())
{
std::cout << "1 selected\n";
}
}
auto options_button_layout(cycfi::elements::view& window_view)
{
using namespace cycfi::elements;
auto run_options_button = button("Run Selected Options");
run_options_button.on_click =
[&](bool) mutable
{
run_selected_options();
};
return
margin({ 20, 0, 20, 20 },
vtile(
top_margin(20, run_options_button),
top_margin(10, check_box_select_all)
)
);
}
auto create_view_models(cycfi::elements::view& window_view)
{
using namespace cycfi::elements;
check_box1.value(false);
check_box2.value(false);
check_box3.value(false);
// TODO: Not Working
//
check_box_select_all.on_click =
[&](bool) mutable
{
check_box_select_all.value(!check_box_select_all.value());
const auto update = check_box_select_all.value();
// *** The following code is not working. The check_boxes are
// in a checked state, but do not reflect the state on
// the GUI (i.e. the box is not checked).
//
check_box1.on_click(update);
check_box2.on_click(update);
check_box3.on_click(update);
window_view.refresh();
return true;
};
check_box1.on_click =
[&](bool) mutable
{
check_box1.value(!check_box1.value());
};
check_box2.on_click =
[&](bool) mutable
{
check_box2.value(!check_box2.value());
};
check_box3.on_click =
[&](bool) mutable
{
check_box3.value(!check_box3.value());
};
auto check_boxes =
group("Components",
margin({ 10, 10, 20, 20 },
top_margin(25,
vtile(
top_margin(10, align_left(check_box1)),
top_margin(10, align_left(check_box2)),
top_margin(10, align_left(check_box3))
)
)
)
);
return
vtile(
htile(
options_button_layout(window_view),
vtile(
margin({ 20, 20, 20, 20 }, check_boxes)
)
)
);
}
public:
auto show(const int argc = 0, char* argv[] = nullptr)
{
using namespace cycfi::elements;
app app_instance(argc, argv, "Checkbox Tester", "anyar.research.experimental");
window window_model(app_instance.name());
window_model.on_close = [&app_instance]() { app_instance.stop(); };
view window_view(window_model);
window_view.content(
create_view_models(window_view),
background
);
app_instance.run();
}
};
inline int show_dialog(const int argc, char* argv[])
{
test_options_dialog dialog;
dialog.show(argc, argv);
return 0;
}
int main(const int argc, char* argv[])
{
return show_dialog(argc, argv);
}
|
Beta Was this translation helpful? Give feedback.
-
OK, got it. Thanks for the MVCE. It really helps! The main issue here is that: if you want an element to interact with other elements, you need to "share" it and "hold" the shared element in the composition. There are a couple of unrelated changes I made to your code which I shall explain below. Here's the correct code: #include <string>
#include <iostream>
#include <elements.hpp>
using namespace cycfi::elements;
namespace colors
{
constexpr auto default_dark = rgba(32, 32, 32, 255);
auto constexpr bkd_color = ::colors::default_dark;
}
// Basic check box type
//
using check_box_t = decltype(share(check_box("name")));
class test_options_dialog final
{
const box_element background = box(::colors::bkd_color);
check_box_t check_box1 = share(check_box("A"));
check_box_t check_box2 = share(check_box("B"));
check_box_t check_box3 = share(check_box("C"));
check_box_t check_box_select_all = share(check_box("Select All"));
void run_selected_options() const
{
std::string args = "-ignore";
if (check_box1->value())
{
std::cout << "1 selected\n";
}
else
{
std::cout << "1 not selected\n";
}
if (check_box2->value())
{
std::cout << "2 selected\n";
}
else
{
std::cout << "2 not selected\n";
}
if (check_box3->value())
{
std::cout << "3 selected\n";
}
else
{
std::cout << "3 not selected\n";
}
}
auto options_button_layout(view& window_view)
{
auto run_options_button = button("Run Selected Options");
run_options_button.on_click =
[&](bool) mutable
{
run_selected_options();
};
return
margin({ 20, 0, 20, 20 },
vtile(
top_margin(20, run_options_button),
top_margin(10, hold(check_box_select_all))
)
);
}
auto create_view_models(view& window_view)
{
check_box1->value(false);
check_box2->value(false);
check_box3->value(false);
check_box_select_all->on_click =
[&](bool) mutable
{
const auto update = check_box_select_all->value();
check_box1->value(update);
check_box2->value(update);
check_box3->value(update);
window_view.refresh();
return true;
};
auto check_boxes =
group("Components",
margin({ 10, 10, 20, 20 },
top_margin(25,
vtile(
top_margin(10, align_left(hold(check_box1))),
top_margin(10, align_left(hold(check_box2))),
top_margin(10, align_left(hold(check_box3)))
)
)
)
);
return
vtile(
htile(
options_button_layout(window_view),
vtile(
margin({ 20, 20, 20, 20 }, check_boxes)
)
)
);
}
public:
auto show(const int argc = 0, char* argv[] = nullptr)
{
app app_instance(argc, argv, "Checkbox Tester", "anyar.research.experimental");
window window_model(app_instance.name());
window_model.on_close = [&app_instance]() { app_instance.stop(); };
view window_view(window_model);
window_view.content(
create_view_models(window_view),
background
);
app_instance.run();
}
};
inline int show_dialog(const int argc, char* argv[])
{
test_options_dialog dialog;
dialog.show(argc, argv);
return 0;
}
int main(const int argc, char* argv[])
{
return show_dialog(argc, argv);
} A couple of things:
Aside: I removed the code where you changed the value of the button in the I hope this helps! This will be clarified in the documentation currently WIP. |
Beta Was this translation helpful? Give feedback.
-
The reason why you need to "share" and "hold" interacting elements is that the elements uses value semantics everywhere. So, when you make a composition, the elements are actually copied. Therefore, if you do not share the element, it will not be the same element that is actually held in the composition. "share" and "hold" changes value semantics to reference semantics. |
Beta Was this translation helpful? Give feedback.
-
I'll close this now. Feel free to reopen if you are not satisfied with the answer. |
Beta Was this translation helpful? Give feedback.
-
Hmmm... actually, I'll reopen this for the sake of others who have the same problem, pending proper documentation. |
Beta Was this translation helpful? Give feedback.
-
Thanks Joel!
This is a great help!
Thank you also for the tips, corrections, and other suggestions.
I am looking forward to getting deeper into elements.
- Bill Berry
…On Mon, Sep 14, 2020 at 7:45 PM Joel de Guzman ***@***.***> wrote:
OK, got it. Thanks for the MVCE. It really helps!
The main issue here is that: if you want an element to interact with other
elements, you need to "share" it and "hold" the shared element in the
composition. There are a couple of unrelated changes I made to your code
which I shall explain below. Here's the correct code:
#include <string>
#include <iostream>
#include <elements.hpp>
using namespace cycfi::elements;
namespace colors
{
constexpr auto default_dark = rgba(32, 32, 32, 255);
auto constexpr bkd_color = ::colors::default_dark;
}
// Basic check box type//using check_box_t = decltype(share(check_box("name")));
class test_options_dialog final
{
const box_element background = box(::colors::bkd_color);
check_box_t check_box1 = share(check_box("A"));
check_box_t check_box2 = share(check_box("B"));
check_box_t check_box3 = share(check_box("C"));
check_box_t check_box_select_all = share(check_box("Select All"));
void run_selected_options() const
{
std::string args = "-ignore";
if (check_box1->value())
{
std::cout << "1 selected\n";
}
else
{
std::cout << "1 not selected\n";
}
if (check_box2->value())
{
std::cout << "2 selected\n";
}
else
{
std::cout << "2 not selected\n";
}
if (check_box3->value())
{
std::cout << "3 selected\n";
}
else
{
std::cout << "3 not selected\n";
}
}
auto options_button_layout(view& window_view)
{
auto run_options_button = button("Run Selected Options");
run_options_button.on_click =
[&](bool) mutable
{
run_selected_options();
};
return
margin({ 20, 0, 20, 20 },
vtile(
top_margin(20, run_options_button),
top_margin(10, hold(check_box_select_all))
)
);
}
auto create_view_models(view& window_view)
{
check_box1->value(false);
check_box2->value(false);
check_box3->value(false);
// TODO: Not Working
//
check_box_select_all->on_click =
[&](bool) mutable
{
// check_box_select_all->value(!check_box_select_all->value());
const auto update = check_box_select_all->value();
check_box1->value(update);
check_box2->value(update);
check_box3->value(update);
window_view.refresh();
return true;
};
auto check_boxes =
group("Components",
margin({ 10, 10, 20, 20 },
top_margin(25,
vtile(
top_margin(10, align_left(hold(check_box1))),
top_margin(10, align_left(hold(check_box2))),
top_margin(10, align_left(hold(check_box3)))
)
)
)
);
return
vtile(
htile(
options_button_layout(window_view),
vtile(
margin({ 20, 20, 20, 20 }, check_boxes)
)
)
);
}
public:
auto show(const int argc = 0, char* argv[] = nullptr)
{
app app_instance(argc, argv, "Checkbox Tester", "anyar.research.experimental");
window window_model(app_instance.name());
window_model.on_close = [&app_instance]() { app_instance.stop(); };
view window_view(window_model);
window_view.content(
create_view_models(window_view),
background
);
app_instance.run();
}
};inline int show_dialog(const int argc, char* argv[])
{
test_options_dialog dialog;
dialog.show(argc, argv);
return 0;
}
int main(const int argc, char* argv[])
{
return show_dialog(argc, argv);
}
A couple of things:
1. Use decltype. It will make your life so much easier. See line 15.
2. The interacting check-boxes are "shared".
3. The interacting elements are held ("hold"). Lines 73 and 108-110.
4. Don't set the value via on_click. Do it via btn->value(val); line
94-96
Aside: I removed the code where you changed the value of the button in the
on_click (e.g. check_box3.value(!check_box3.value());). That is not
necessary and is incorrect.
I hope this helps! This will be clarified in the documentation currently
WIP.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#179 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOKC7TR2IPX7OT7IT3IUCTSF22KPANCNFSM4OV7VUTA>
.
|
Beta Was this translation helpful? Give feedback.
-
@djowel have you thought about different implementations of the event handling/bounds calculation? Something of ECS type or signal-slot? These are very far from elements implementation but I'm curious if you have considered them and if yes - what are your thoughts on them. IMO I have a feeling that ECS can have much more efficient handling (although every element would need to be connected to sort of cerntral registry - many elements require view anyway) and signal-slot can scale much better (instead of iterating over elemens, it's iterating over signals and connected slots). |
Beta Was this translation helpful? Give feedback.
-
I was inclined to flag this as OT, but I didn't do it because it is tangentially related. I'll give my reply, but I'll make it short. If you want to discuss design issues further, well, this is not the place for it. There's the discord group chat for that. Anyway, my answer will also be irrelevant primarily because at this point, it's too late in the design cycle to change things the way they are. As I pointed out elsewhere, I am no longer inclined to entertain substantial design changes. But answering for the sake of answering... Focusing on the on_* handlers only as relevant in this discussion, I prefer direct communication between components. Signals-and-slots has its place, for sure, but in terms of design, the analogy is a bulletin board where one posts messages and interested parties connect to be notified of such posts they are interested in. Essentially a one-to-many relationship. For elements, I prefer a one-to-one relationship, because generally that's what's happening. Moreover, direct communication via the on_* handlers does not preclude one-to-many relationships. For instance, an on_click function is generic enough and can connect to an app specific signals/slots or "event bus". It's up to you, the app designer, if you want that. There is no system-wide "way of doing things" that is forced into the user. That follows the keep-it-simple design principle. If you are thinking about replying further, please don't. Instead, move the discussion over to the discord chat group. I do not want to veer too much from the topic. |
Beta Was this translation helpful? Give feedback.
-
Ok, thanks for the response. This answer is enough. |
Beta Was this translation helpful? Give feedback.
-
I may be using the control incorrectly.
The workflow is such that when a checkbox is clicked then I would like other checkboxes to also be updated.
i.e. Click checkbox A and have checkbox B reflect the same checked state as A.
Example Code:
#pragma once
#include <elements.hpp>
#include <memory_resource>
namespace experimental::elements
{
namespace colors_rgba
{
constexpr auto alpha = 200;
constexpr auto default_dark = cycfi::elements::rgba(32, 32, 32, alpha);
constexpr auto slate_gray = cycfi::elements::rgba(112, 128, 144, alpha);
constexpr auto antique_white = cycfi::elements::rgba(250, 235, 215, alpha);
constexpr auto doger_blue = cycfi::elements::rgba(16, 78, 139, alpha);
}
namespace colors_rgb
{
constexpr auto default_dark = cycfi::elements::rgb(32, 32, 32);
constexpr auto slate_gray = cycfi::elements::rgb(112, 128, 144);
constexpr auto antique_white = cycfi::elements::rgb(250, 235, 215);
constexpr auto doger_blue = cycfi::elements::rgb(16, 78, 139);
}
using check_box_t = cycfi::elements::basic_toggle_button<cycfi::elements::proxy<cycfi::elements::check_box_element, cycfi::elements::basic_button>>;
namespace grpc::controller
{
// TODO: Load from config file.
//
auto constexpr default_path = "";
}
} // using namespace experimental::elements;
//#include "grpc-startup-controller.hh"
using namespace experimental::elements::grpc;
/**
/
int main(const int argc, char argv[])
{
return controller::show_dialog(argc, argv);
}
Again, this is awesome work you are doing. Thanks so so much!
Beta Was this translation helpful? Give feedback.
All reactions