Hiding and editing dialogs.

May 29, 2013 at 9:31 AM
Edited May 29, 2013 at 9:53 AM
Hallo!
There are thousands of powerfull algorithms for many scientific tasks. Most are presented in a couple of paper in a science - journal and very few people actually use it. The main reason is very simple: they are implemented as a command line tools. Very user-unfriendly. But that is another history. The point is that I want to present Nana to the scientific community as a convenient tool to build a good, and simple to program, GUI – front end. This wills the first approximation, with a second – to build fully-GUI application powered by Nana.
In this first approximation I need a very simple, to learn and use, way of configuring a form for data input. My idea is that you make a first, inaccurate attempt during programming, mainly assigning each of your widget to a named field, and only at run time improve the GUI layout. You can send the application to users, and you could expect that some of them will customize it, and e-mail you back the simple text file with the new layout, with you can in a very simple way test and incorporate in future versions (of course, you can also self spend some time modifying the layout).
Here I have a draft implementation of my idea. Right clicking some selected widget you can open a dialog to edit in “real time” the layout of a whole form or of some CompoWidgets, and save or open these configurations. I have also my first working implementation of NumUpDown to input quantities. It is fully customizable too.
Image
Here the widgets Project:, Project2: and Layout: are of type OpenSaveBox, where Project2: have been customized to invert the order of the buttons.
The “user” code for this is:
#include <../temp/EditableForm.hpp>
#include <../temp/Numer.hpp>

class DemoForm: public nana::gui::form,public EditableForm 
{ public:
    nana::gui::button   but1 , but2, but3, but4;
    OpenSaveBox            osb  , osb2 ;
    nana::gui::NumerUpDown num1, num2;
    nana::gui::textbox    _num;
    nana::gui::button     _up, _down;
    nana::gui::label      _label;


   DemoForm(): nana::gui::form ( nana::rectangle( 
              nana::point(600,210), nana::size(500,250) )),
        EditableForm (*this, STR("Configurable Window"), 
                              STR("Layot_Demo.lay.txt")),
       but1 (*this), but2(*this), but3(*this), but4(*this),
        osb             (*this, STR("Project:") ), 
        osb2            (*this, STR("Project2:")),
        num1            (*this, STR("G:") , -5, -30, 30),
        num2            (*this, STR("Tm:"), 60,  30, 90),  
       _num(*this), _up(*this), _down(*this), _label(*this)
    {
       but1.caption (STR("But1"));
       but2.caption (STR("But2"));
       but3.caption (STR("But3"));
       but4.caption (STR("But4"));
        _up.caption (STR("^"));
        _down.caption (STR("v"));
        _label.caption (STR("Num out:"));
        _label.text_align(nana::align::right  ); 

     osb.add_filter (STR("Text File" ),STR("*.txt;*.doc"));
      osb.add_filter (STR("All File"  ), STR("*.*"));
      osb2.add_filter (STR("Text File" ), STR("*.txt"));
      osb2.add_filter (STR("Todos File"), STR("*.*"));

        InitMyLayout();
        AddMenuProgram();
        SelectClickableWidget( _menuBar);
        SelectClickableWidget( but2);

    }
    void SetDefLayout   () override
    {
        _DefLayout= "vertical                   \n\t"
                    "<weight=25>                \n\t" 
                    "<Project weight=22>        \n\t" 
                    "<gap=2 <b1> <b2> <b3> >    \n\t"
                    "<<b4> <weight=2>>          \n\t"
                    "<weight=20 <label weight=60 >"
                "<Num> <vertical weight=50 <UpDown>>> \n\t"
                    "<num  weight=20 >          \n\t"
                    "<Project2 weight=22>       \n\t" ;
    }
    void AsignWidgetToFields() override
    {
       _place.field("Project" ) <<osb;
       _place.field("Project2") <<osb2;
       _place.field("b1"      ) <<but1;
       _place.field("b2"      ) <<but2;
       _place.field("b3"      ) <<but3;
       _place.field("b4"      ) <<but4;
       _place.field("num"     ) <<num1 << num2;
       _place.field("Num"     ) << _num ;
        _place.field("UpDown"  ) << _up << _down ;
        _place.field("label"   ) << _label;
    }
 };

int main()
{
     DemoForm form;
     form.show();
     nana::gui::exec();
     return 0;
}
The full code is in my fork of nana, in the branch new_master.
And here are some of my questions:
1.- I would like to see yours comments on alternative, right nana-way of doing these things.
2.- I also want to know if there is a way to add an item in the system menu of a form.
3.- When using place, a very natural constructor for many widget will be:
    my_widget ( parent , "caption text" )
4.- I wanted to make the Edit dialog (for each edited widget) a window that the user can call many times, conserving the last state. I imagine changing the close event to a hide event, but I think it could break the normal function of the program. My code is now very naïve: (in class EditableWidget)
std::unique_ptr <EditLayout_Form> _myEdLayForm;
void EditableWidget::EditMyLayout()
{
    if (!_myEdLayForm) 
        _myEdLayForm.reset (new EditLayout_Form ( this ));
    _myEdLayForm->show ();
}
Finally, it will be great if this graft inspire you to implement it in a correct way in nana.
Coordinator
May 30, 2013 at 8:57 PM
Hi,
It would be great if the nana library presents in a professional field for scientific program. For a scientific program, I think a GUI library would provide a component for customizing the GUI layout by users if it is an ordinary demand.

1.- I would like to see yours comments on alternative, right nana-way of doing these things.

Before you open this discussion, I thought a program should not provide an interface for user to configure the layout of GUI, becuase users maight mess it up. In my opinion, the EditableWidget should be defined for aggregation, not for inheritance.

class Myform
{
public:
    Myform()
    {
        create widgets...

        place_.div(xxx);
        place_.field<<widgets...

        ecp_.bind(place_);
        ecp_.clickable(widgets)....
    }
private:
    place place_;
    editable_capacity_provider ecp_;    //A component like EditableWidget

    //widgets...
};
2.- I also want to know if there is a way to add an item in the system menu of a form.

Now, the nana does not provide a method to add an item in the system menu, but you can achieve it by using system API.
//Get the HWND of the form,
HWND wd = reinterpret_cast<HWND>(nana::gui::API::root(form_obj));
HMENU sysmenu = GetSystemMenu(wd, FALSE);
AppendMenu(sysmenu, ....);

//Then subclass the window for processing the menu message
3.- When using place, a very natural constructor for many widget.

Yes, agree with you.

4.-
_myEdLayForm.make_event<events::unload>([this](const eventinfo& ei)
{
    ei.unload.cancel = true;    //Stop closing and then
    _myEdLayForm->hide();
});

//And
menuProgram.append(STR("&Edit this windows Layout"),[this](nana::gui::menu::item_proxy& ip)
{
    _myEdLayForm->show();
});
Regards!
Jinhao
Jun 24, 2013 at 2:26 PM
Hallo !
I’m very sorry I have not reply yet.
The reason for using inheritance and not aggregation was to minimize the amount of “boiler-plate" or preparation-code need to use it. The idea is some kind of Interface added to the new forms, with already works. But maybe I revise that if I find a way of encapsulating all the “editable_capacity” into a member.
I’m aware of the problem with the users messing things with the layout. That is why my first lines of code were a set of global (static) and local variables to disable (user, run-time) dynamic edition of layout and also the use of “*.lay.txt” files. But I have not implemented it use yet. Also, for mature programs one could simple not inherit anymore from EditableWidget. Nevertheless, you are right, and I have added two more buttons to the form for editing others forms layouts. The “Panic!” button is used to immediately, (and without affecting the text you are editing) reapply the layout that is hard-coded in the original executable file. The user has no way of changing that, and can at any moment and very simple reapply it. You don’t need to be afraid of making changes because you can always very simple undo it. I have find this button very useful simple to rapidly switch between what I’m editing and the original, safe variant, with make a very evident illustrations of the changes. A second button will load the default layout into the editor, but this variant is more intrusive, and you will need to save your editing if you want to return to it latter. You can also open the default “*.lay.txt” file using the open menu or button. Note that the programmer has the liberty of providing two different “default” layouts: one hard coded and the other in the form of a file. The latter have normally priority, but if it is missing or corrupt the hard coded layout will be use.
I also used your recommendation to implement the “hide” behavior and it work good: thank!
Image
In this example screen I have changed a <num weight=23> for a <num weight=80> obtaining something undesirable. In the next screen you see I use the “Panic!” button to rapidly restore a working layout. In this second screen you can note that the form for editing is also edited, and the positions of the buttons adjusted.
Image
Sep 23, 2014 at 1:45 PM
Actual:
Image