How do I connect a checkbox and radio buttons to my code?

I assume I must add a id to any widget in my main.xml that I wish to receive events for.

My main.xml looks like:

<vbox style="padding: 5px;" width="100%" height="100%">
    <hbox>
        <checkbox id="check1" text="check 1" />
        <checkbox id="check2" text="check 2" />
        <checkbox id="check3" text="check 3" />
    </hbox>
    <hbox>
        <optionbox id="radio1" text="radio 1" />
        <optionbox id="radio2" text="radio 2" />
        <optionbox id="radio3" text="radio 3" />
    </hbox>
</vbox>

What do I pass to main.findComponent("the-id", ?) to find the checkboxes and also for the radio buttons?

How can I tell when:

  • a checkbox is checked, and unchecked?
  • a radio button is selected?

Also, is there anything special required to group these radio buttons? They seem to automatically be grouped together, but I didn’t put them into any sort of “<buttongroup>” element.

Thanks!

I see that, for the checkbox, I get an event:

var widget = main.findComponent("check2", CheckBox);
widget.registerEvent(MouseEvent.CLICK, handleWidget);

but my handleWidget function

public static function handleWidget(e) {
    trace("clicked!");
}

gets called upon checking and also unchecking.

Also, what is the type of e in that handler function? I tried $type(e) but it gives me Unknown<0>.

Thanks!

This might help clear things up a little:

    <!-- normal checkboxes, you can use onChange or registerEvent in code rather than script -->
    <hbox>
        <checkbox text="Check 1a" onchange="trace('check 1a changed')" />
        <checkbox text="Check 2a" onchange="trace('check 2a changed')" />
        <checkbox text="Check 3a" onchange="trace('check 3a changed')" />
    </hbox>
    
    <!-- using a group container, you will be notified when any children 'change' -->
    <group layout="horizontal" onchange="trace('group b changed')">
        <checkbox text="Check 1b" />
        <checkbox text="Check 2b" />
        <checkbox text="Check 3b" />
    </group>

    <!-- options using a default group -->
    <hbox>
        <optionbox text="Option 1c" onchange="trace('option 1c changed')" />
        <optionbox text="Option 2c" onchange="trace('option 2c changed')" />
        <optionbox text="Option 3c" onchange="trace('option 3c changed')" />
    </hbox>
    
    <!-- options using a specific group name -->
    <hbox>
        <optionbox text="Option 1d" componentGroup="myGroup" onchange="trace('option 1d changed')" />
        <optionbox text="Option 2d" componentGroup="myGroup" onchange="trace('option 2d changed')" />
        <optionbox text="Option 3d" componentGroup="myGroup" onchange="trace('option 3d changed')" />
    </hbox>
    
    `<!-- using a group container, you can specify a 'componentGroup' if you want, if not one will be assigned to options (only) for you -->
    <group layout="horizontal" onchange="trace('group e changed')">
        <optionbox text="Option 1e" />
        <optionbox text="Option 2e" />
        <optionbox text="Option 3e" />
    </group>
    
    <!-- you can use a group container for any interactive children that will emit a change event -->
    <group layout="horizontal" onchange="trace('a slider changed!')">
        <slider direction="vertical" />
        <slider direction="vertical" />
        <slider direction="vertical" />
        <vbox>
            <slider direction="horizontal" />
            <slider direction="horizontal" />
            <slider direction="horizontal" />
        </vbox>
    </group>

The group component is really useful - written by @intoxopox :slight_smile:

Cheers,
Ian

Thanks, Ian. I see that, in my Main.hx, I can assign a handler function to a checkbox or optionbox with:

widget.onChange = handleWidget;

as your sample suggests, but how can I discern whether the checkbox was just checked vs unchecked?

How can I tell if the option button was just selected? That is, which in the group was selected?

And, in my widget event handler function (public static function handleWidget(e) {...}) what is that e argument that HaxeUI passes in, and how do I use it (what info can I get out of it)?

e for a change event would be a UIEvent, so it should have a target property which would be the item in question, and you could from that get its id and its selected poperty, though you may need a cast which i dont like, eg:

e.target.id and cast(e.target, CheckBox).selected, i wonder if a new SelectionChangedEvent makes sense… ill have to think about it.

Cheers,
Ian

Sorry, I had a typo in my most recent reply, so edited it (myFunc() --> handleWidget).

Ok, I see that cast(e.target, CheckBox).selected gets me that checkbox selected status in my handleWidget function. This seems like a common operation for a checkbox.

Thanks.

I guess ive usually done it something like:

<group layoutName="horizontal" id="optionboxes">
    <optionbox id="option1" text="Option 1" />
    <optionbox id="option2" text="Option 2" />
    <optionbox id="option3" text="Option 3" />
</group>

and

@:build(haxe.ui.macros.ComponentMacros.build("assets/myview.xml"))
class MyView extends Box {
    @:bind(optionboxes, UIEvent.CHANGE)
    function onOptionChange(e) {
        if (option1.selected) {
            trace("option1");
        } else if (option2.selected) {
            trace("option2");
        } else if (option3.selected) {
            trace("option3");
        }
    }
}

But thats using a custom component / view - so all my options are OptionBox member vars. So i appriciate there isnt a nice event / way to just get the selected option - ill have a think about the best way expose that info in a nice event, hopefully for all components.

In the mean time, im still trying to convince you of the powers of custom components, heh heh :smiley:

Though i also appreciate for a tutorial / guide they are waaaaay out of scope and will likely confuse people as there is too much “magic” going on.

Cheers,
Ian

Ok, regarding the option buttons (no custom component): I’ve got the option buttons grouped — my main.xml is:

<vbox style="padding: 5px;" width="100%" height="100%">
    <group id="optionGroup1" layout="horizontal">
        <optionbox id="option1" text="Option 1" />
        <optionbox id="option2" text="Option 2" />
        <optionbox id="option3" text="Option 3" />
    </group>
</vbox>

In my Main.main function I need a couple more imports:

import haxe.ui.components.OptionBox;
import haxe.ui.containers.Group;

and I can receive the event (in my main function):

var widget = main.findComponent("optionGroup1", Group);
widget.onChange = handleWidget;

but in my Main.handleWidget function is where I need help:

public static function handleWidget(e) {
    var grp = cast(e.target, Group); // Should be that Group, no?
    trace(grp.id); // I expect this to be optionGroup1
    // and then how do I get at the option buttons?
}

But as soon as I click an option button it dies with “invalid cast”.

Is e's target not that Group object?

How do I get at those option boxes from e?

Thanks!

So the e.target for a group change event will be the component that has changed, so in the case of your example, something like:

trace(e.target.id);
trace(e.target.userData);
trace(cast(e.target, OptionBox).selected);

Ian

Thanks, Ian. That worked:

http://www.unexpected-vortices.com/haxe/haxeui-tut/more-widget-examples/option-boxes.html

(corrections/suggestions always appreciated)

Though, without the width and height “100%”'s in that <vbox style="padding: 5px;" width="100%" height="100%"> the resulting app still starts up too tiny to see the option boxes. Shall I file a bug for that?

Above you wrote e.target.userData. What does that evaluate to? On my system I just get null.

userData is just that… its an arbitrary bit of data that you (the user) set / get. It just means you can have “something” in the component that you can later user (it can by anything as its a Dynamic)

EDIT: ill check out the 100% w/h - it should be needed and i think wxWidgets on windows is fine, but maybe .fit() in wxwidgets on other platforms isnt so precise… ill check it out.

Ian

So yeah, you xml above, without the 100%'s leads to:

image

Which looks completely correct, so i think it might be a wxWidgets “thing”… ill check out other platforms.

Thanks. On Debian Testing, without the w/h 100% the app opens up like:

option-boxes-flat

1 Like

Im installing debian now, though not debian testing (hopefully not too different)… any other specific about your system that might help?

Also, what does the app look like if your main.xml is:

<vbox>
    <button text="Button 1" />
    <button text="Button 2" />
    <button text="Button 3" />
</vbox>

What about:

<vbox>
    <button text="Button 1" />
    <button text="Button 2" height="100"/>
    <button text="Button 3" />
</vbox>

Cheers,
Ian

So i just ran the option boxes on debian and i get:

image

Which looks right to me. What version of wx are you using? Any info you can give me? Or what you think it could be?

I just updated my hxWidgets and haxeui-hxwidgets.

My Debian Testing system has:

Haxe 4.0.0-rc.2
GTK3
wxWidgets 3.0.4
g++ (Debian 8.3.0-19) 8.3.0

via haxelib:
haxeui-core: [git]
haxeui-hxwidgets: [git]
hscript: [2.3.0]
hxcpp: [4.0.19]
hxWidgets: [1.0.8]

With main.xml:

<vbox>
    <group id="optionGroup1" layout="horizontal">
        <optionbox id="option1" text="Option 1" selected="true" />
        <optionbox id="option2" text="Option 2" />
        <optionbox id="option3" text="Option 3" />
    </group>
</vbox>

I get:

Screenshot_2019-08-07_11-53-20

but with this error in the terminal:

(Main:2262): Gtk-CRITICAL **: 11:52:54.042: gtk_window_resize: assertion 'height > 0' failed

With the xml:

<vbox>
    <button text="Button 1" />
    <button text="Button 2" />
    <button text="Button 3" />
</vbox>

Screenshot_2019-08-07_11-56-37

and with xml:

<vbox>
    <button text="Button 1" />
    <button text="Button 2" height="100"/>
    <button text="Button 3" />
</vbox>

Screenshot_2019-08-07_11-58-01

This is interesting. If I put back into the optionbox xml the

<vbox style="padding: 5px;" ...

it’s squashed again, but no error message.

If I remove that bit, it opens with all three optionboxes showing, like my screenshot, but again with that “height > 0” error.

Can you try to upgrade you wxWidgets to 3.1.2? You’ll need to build it from source, but its really simple:

  • download source .zip
  • unzip
  • create subfolder (eg: gtk-build)
  • enter sub folder and use ../configure --with-opengl
  • make … … … wait
  • test with cd samples/widgets (use make in that folder then ./widgets)
  • back to gtk-build dir and make install
  • new terminal: wx-config --version, should be 3.1.2, if not PATH=/full/path/to/that/wx-config:$PATH
  • rebuild app, ie, delete build folder and rebuild the lot

Most of that info is from here: https://wiki.wxwidgets.org/Compiling_and_getting_started

I feel like there are all types of issues with 3.0.X using gtk.

Cheers,
Ian

Ok. I apt uninstalled wx and downloaded and built wx 3.1.2. Wow wx is big, and took a little while to build.

Upon the …/configure step, I used --prefix=/home/john/opt/local, and so now have:

$ wx-config --version
3.1.2

$ wx-config --prefix
/home/john/opt/local

$ wx-config --list

    Default config is gtk3-unicode-3.1

  Default config will be used for output

I built and ran the samples/widgets, and it ran — wx supports a lot of widgets.

Anyhow, I created a new hxwidgets project to test. It seemed to build fine (haxe hxwidgets.hxml).

Using a main.xml file containing no extra padding or h/w 100% in that main vbox:

<vbox>
    <group id="optionGroup1" layout="horizontal">
        <optionbox id="option1" text="Option 1" selected="true" />
        <optionbox id="option2" text="Option 2" />
        <optionbox id="option3" text="Option 3" />
    </group>
</vbox>

Running the app

LD_LIBRARY_PATH=~/opt/local/lib ./build/hxwidgets/Main

it runs and the window looks like it should:

Screenshot_2019-08-07_11-53-20

but I still get that error message:

(Main:806): Gtk-CRITICAL **: 19:47:12.372: gtk_window_resize: assertion 'height > 0' failed

(Note, it doesn’t crash the app — just displays that message upon app startup.)

Hope that helps. My goal is to have a tutorial aimed at easily creating native apps with Haxe on GNU/Linux. It would be nice if readers didn’t have to build their own wx in the process, though to the wx devs credit, it’s not difficult, and it’s nice that wx builds in its own directory (gtk-build) and can easily install into its own directory (in this case, ~/opt/local) so as not to add lots of files to /usr/local.

What about the buttons example? That work also? Its strange abotu the assertion as haxeui-hxwidgets explicity doesnt size anything if its less that or equal to 0…

So that must be coming from somewhere else, which is bizarre… i also dont get that on debian… that “Main:806”… that a line number? Any chance to paste the Main.cpp file?