Only you at the very early debug step will see ( the exceptions )

A successful application needs constant maintenance. Each week I receive several requests from clients to modify the GUIs for my applications. I need to see the errors that can be introduced by maintenance work throughout the life cycle of an application.

Error handling of GUI code is critical. Please explain how you intend the exceptions thrown by nana library code to be handled.

> Only you at the very early debug step will see ( the exceptions ) A successful application needs constant maintenance. Each week I receive several requests from clients to modify the GUIs for my applications. I need to see the errors that can be introduced by maintenance work throughout the life cycle of an application. Error handling of GUI code is critical. Please explain how you intend the exceptions thrown by nana library code to be handled.

The scope of the question is getting lost here. This should be about how to correctly design and now how to debug correctly the div text.

For me, personally, I switched to nana almost entirely for the div text. You can say that sometimes it's not the most stable or can be confusing to write to. But IMHO dealing with absolute positions make the program feel squared, without any beauty flow on the management. But everyone can have their agreement in this.

Yet, using the same controls nana provides you can make a form that has a simple textbox with specialized formatting for the div text, which then includes identing and syntax highlighting. On the construction the form would bind to either a place, form, group or even a panel. Then just a simple button to collocate or saving to the clipboard to easy source management. I'll share a snippet whenever I have time. This makes easy for layout management in the run-time so you can actually see the slightest changes you make in real time. A nice addition would be a list of that shows all the fields on the current place objects, but IDK if it is possible to list all the fields with widgets yet.

The beauty of the Div text is not to be exposable to the end-user but to the developer use a run-time layout management without needing to recompile for just a single spacing tweaking.

On the error throwing: are you building nana on release or on debug? On release sometimes it does not throw errors and just keep it silent, and debug.... Er' it's for debugging. It shows errors and even the tracebacks if you manage to do it correctly (with catching exceptions or creating minidumps). I agree that it should implement a counter of the brackets open and closing on parse. Multiple field names IDK how one could reuse the same field name in the same place, but could be another improvement. In LUA library SOL when you have a non validating script it gives you a nice information when you have a broken string, giving the exact location(pretty much as how @qPCR4vir posted with the ^~~~~), it could be another implementation.

The scope of the question is getting lost here. This should be about how to correctly design and now how to debug correctly the div text. For me, personally, I switched to nana almost entirely for the div text. You can say that sometimes it's not the most stable or can be confusing to write to. But IMHO dealing with absolute positions make the program feel squared, without any beauty flow on the management. But everyone can have their agreement in this. Yet, using the same controls nana provides you can make a form that has a simple textbox with specialized formatting for the div text, which then includes identing and syntax highlighting. On the construction the form would bind to either a place*, form*, group* or even a panel*. Then just a simple button to collocate or saving to the clipboard to easy source management. I'll share a snippet whenever I have time. This makes easy for layout management in the run-time so you can actually see the slightest changes you make in real time. A nice addition would be a list of that shows all the fields on the current place objects, but IDK if it is possible to list all the fields with widgets yet. The beauty of the Div text is not to be exposable to the end-user but to the developer use a run-time layout management without needing to recompile for just a single spacing tweaking. On the error throwing: are you building nana on release or on debug? On release sometimes it does not throw errors and just keep it silent, and debug.... Er' it's for debugging. It shows errors and even the tracebacks if you manage to do it correctly (with catching exceptions or creating minidumps). I agree that it should implement a counter of the brackets open and closing on parse. Multiple field names IDK how one could reuse the same field name in the same place, but could be another improvement. In LUA library SOL when you have a non validating script it gives you a nice information when you have a broken string, giving the exact location(pretty much as how @qPCR4vir posted with the ^~~~~), it could be another implementation.

Surely the code should at least check for matching numbers of left and right brackets?

Fixed!

There is another issue about div-text syntax error, it throws inconsistent expcetions: std::runtime_error and std::invalid_argument. I will fix it and only throw std::invalid_argument if an error caused by invalid div-text.

>Surely the code should at least check for matching numbers of left and right brackets? Fixed! There is another issue about div-text syntax error, it throws inconsistent expcetions: `std::runtime_error` and `std::invalid_argument`. I will fix it and only throw `std::invalid_argument` if an error caused by invalid div-text.

Surely the code should at least check for matching numbers of left and right brackets?

It can be even better than that...

Fixed!

OK. Where is the fix?.

There is another issue about div-text syntax error, it throws inconsistent expcetions: std::runtime_error and std::invalid_argument. I will fix it and only throw std::invalid_argument if an error caused by invalid div-text.

It could be better to derive some nana::place_error from std::invalid_argument with more structured info than just what(). If you give me a few days a can do that. It can try to report the position in which the error was found.

>>Surely the code should at least check for matching numbers of left and right brackets? It can be even better than that... >Fixed! OK. Where is the fix?. >There is another issue about div-text syntax error, it throws inconsistent expcetions: `std::runtime_error` and `std::invalid_argument`. I will fix it and only throw `std::invalid_argument` if an error caused by invalid div-text. It could be better to derive some `nana::place_error` from `std::invalid_argument` with more structured info than just what(). If you give me a few days a can do that. It can try to report the position in which the error was found.

OK. Where is the fix?.

I will commit the fix today later

It could be better to derive some nana::place_error from std::invalid_argument with more structured info than just what(). If you give me a few days a can do that. It can try to report the position in which the error was found.

I’m looking forward to it.

>OK. Where is the fix?. I will commit the fix today later >It could be better to derive some `nana::place_error` from `std::invalid_argument` with more structured info than just what(). If you give me a few days a can do that. It can try to report the position in which the error was found. I’m looking forward to it.

How do you design the GUI?

Two aspects:

It's a big question.

That is: How to organize the interaction GUI-model?

an interesting way to align the different widgets.

This is an smaller question, a very particular problem inside the big question. And here we have seen 3 preferences (you need to find the best fit for your needs and yours skills):

  1. Low level, direct control of each widget coordinate, even during moving and resizing. Easy to make errors letting to longer debugging time, and probably difficult to make changes or additions (figure you want to add some address field before the name to the screen posted by Jbec). But everything is under your control and it is up to you to implement anything you like exactly how do you like (if you have the patience for that).
  2. Use an external code generator like nana-creator. Also a good option. Of course, it add a dependency to your project. It may be a good idea if you fork the code of the creator and you are able to fix and develop it contributing back to that project. Depending on how the creator works, you may significantly lost control over your code.
  3. Use the advanced place feature offered by nana. You just add a bunch of widgets to it and it will arrange ("colocate", "layout") the widgets for you according to the div_string you provide. In order to gain control back on the layout you need to add more and more fields with margins, gaps, height, width, dock, splitter, grid, etc. Like the low-level setting, here you will probably need to try and debug the corresponding div_string. You will be assisted by place, which detects and reports currently more than 30 different errors. Once it runs correctly, that div_string is an static part of your code, just like the coordinates you would need to choose for the low-level coding, and thus your users are not expected to see the exceptions thrown by place.

Nevertheless, and unlike the low_level setting, place let you create simple tools to edit and set at run-time, during the debugging the div_stringdynamically. This functions in fact, like a "rapid development tool", but you keep (almost) as much control over your code as you like, and don't introduce external dependencies.

>How do you design the GUI? Two aspects: >It's a big question. That is: How to organize the interaction GUI-model? >an interesting way to align the different widgets. This is an smaller question, a very particular problem inside the big question. And here we have seen 3 preferences (you need to find the best fit for your needs and yours skills): 1. Low level, direct control of each widget coordinate, even during moving and resizing. Easy to make errors letting to longer debugging time, and probably difficult to make changes or additions (figure you want to add some address field before the name to the screen posted by Jbec). But everything is under your control and it is up to you to implement anything you like exactly how do you like (if you have the patience for that). 2. Use an external code generator like nana-creator. Also a good option. Of course, it add a dependency to your project. It may be a good idea if you fork the code of the creator and you are able to fix and develop it contributing back to that project. Depending on how the creator works, you may significantly lost control over your code. 3. Use the advanced `place` feature offered by nana. You just add a bunch of widgets to it and it will arrange ("colocate", "layout") the widgets for you according to the `div_string` you provide. In order to gain control back on the layout you need to add more and more fields with margins, gaps, height, width, dock, splitter, grid, etc. Like the low-level setting, here you will probably need to try and debug the corresponding `div_string`. You will be assisted by `place`, which detects and reports currently more than 30 different errors. Once it runs correctly, that `div_string` is an static part of your code, just like the coordinates you would need to choose for the low-level coding, and thus your users are not expected to see the exceptions thrown by place. Nevertheless, and unlike the low_level setting, place let you create simple tools to edit and set **at run-time**, during the debugging the `div_string`dynamically. This functions in fact, like a "rapid development tool", but you keep (almost) as much control over your code as you like, and don't introduce external dependencies.
edited Apr 9 at 1:49 pm

Hello

I think method 1 and 3 of doing the GUI I think they require more testing time and it is easy to make mistakes, and if something needs to be modified, it is practically starting. Although I think you have to know that way of doing it, to know how everything works.

The other way is faster to develop and modify, but requires that the program used for it is continuously updated.

Currently, with the libraries I work with, I use an editor to design the GUI, the example image I put is made with it, and when I generate the code I create 500 lines of code, writing and testing all that by hand would take a long time .

Maybe I'm too used to doing it like that. With nana I am trying with the "<> <>" strings, but it requires many tests to make the GUI as you want.

a greeting

Hello I think method 1 and 3 of doing the GUI I think they require more testing time and it is easy to make mistakes, and if something needs to be modified, it is practically starting. Although I think you have to know that way of doing it, to know how everything works. The other way is faster to develop and modify, but requires that the program used for it is continuously updated. Currently, with the libraries I work with, I use an editor to design the GUI, the example image I put is made with it, and when I generate the code I create 500 lines of code, writing and testing all that by hand would take a long time . Maybe I'm too used to doing it like that. With nana I am trying with the "<> <>" strings, but it requires many tests to make the GUI as you want. a greeting
edited Apr 11 at 2:19 pm

Jbec congratulaions, you have found your way.
Based on my experience I can add a few good things about your choice, and also a few bad things. But I will not try to convince you, because I know many people like it that way. And it is great that we have all three types of users.

In fact, it will be great if nana not only allows all those variants, but also actively supports it.
I will add better error diagnostic to place, and I will try to clean up my tool for run-time debuging of the div-string (here ). I hope the creators of the nana creators will suggest how nana can supports him and his users. And surelly ravenspoint will have some recomendations for easy doing the coordenate maintenance.

Jbec congratulaions, you have found your way. Based on my experience I can add a few good things about your choice, and also a few bad things. But I will not try to convince you, because I know many people like it that way. And it is great that we have all three types of users. In fact, it will be great if nana not only allows all those variants, but also actively supports it. I will add better error diagnostic to place, and I will try to clean up my tool for run-time debuging of the div-string ([here](https://github.com/qPCR4vir/nana.ext/blob/master/include/EditableForm.hpp#L559) ). I hope the creators of the nana creators will suggest how nana can supports him and his users. And surelly ravenspoint will have some recomendations for easy doing the coordenate maintenance.
edited Apr 11 at 5:04 pm

And surely ravenspoint will have some recomendations for easy doing the coordenate maintenance.

smile

A big help is to use panels everywhere and then use variables for position, height and width, incrementing them as you move through the widgets in the panel. This way, you only deal with small integers and can insert a new widget amongst the others in a panel without having to adjust all the other widgets down and over.

Here is the first lines of a move function that produces the GUI in the following screenshot

    p1.move( {20, 15,  210, 650} );
    gp1.move( {5, 5, 200, 630} );
    int x = 20;
    int y = 30;
    int yinc = 25;
    unsigned int w = 180;
    unsigned int h = 25;
    cb1_1.move( { x,y, w, h } );
    y += yinc;
    cb1_2.move( { x,y, w, h } );
    y += yinc;
    cb1_3.move( { x,y, w, h } );
    y += yinc;
    cb1_4.move( { x,y, w, h } );
    y += yinc;
    lbDirective.move( { x,y, w, h } );
    y += yinc;
    cb1_5.move( { x,y, w, h } );
    y += yinc;
    cb1_6.move( { x,y, w, h } );
    y += yinc;
    cb1_7.move( { x,y, w, h } );
    y += yinc;

5caf7355cd4c5.png

> And surely ravenspoint will have some recomendations for easy doing the coordenate maintenance. :) A big help is to use panels everywhere and then use variables for position, height and width, incrementing them as you move through the widgets in the panel. This way, you only deal with small integers and can insert a new widget amongst the others in a panel without having to adjust all the other widgets down and over. Here is the first lines of a move function that produces the GUI in the following screenshot ```C++ p1.move( {20, 15, 210, 650} ); gp1.move( {5, 5, 200, 630} ); int x = 20; int y = 30; int yinc = 25; unsigned int w = 180; unsigned int h = 25; cb1_1.move( { x,y, w, h } ); y += yinc; cb1_2.move( { x,y, w, h } ); y += yinc; cb1_3.move( { x,y, w, h } ); y += yinc; cb1_4.move( { x,y, w, h } ); y += yinc; lbDirective.move( { x,y, w, h } ); y += yinc; cb1_5.move( { x,y, w, h } ); y += yinc; cb1_6.move( { x,y, w, h } ); y += yinc; cb1_7.move( { x,y, w, h } ); y += yinc; ``` ![5caf7355cd4c5.png](serve/attachment&path=5caf7355cd4c5.png)

Starting the road! A pity that I do not have much free time to dedicate to nana smile

The option of the string "<>" has seemed interesting to me from the beginning, and if you add a better diagnosis to find the errors, it will be much easier to use them.

The option of @ravenspoint is interesting and seeing the last image is amazing what has been achieved. But I think it's a bit more difficult, especially when I start, I do not know if it's because I never did it that way.

nana-creator I really liked it, and that's what I'm used to, pity it's not updated. Now that @jinhao has started an editor's project, I hope that the following is nana-creator smile

a greeting

Starting the road! A pity that I do not have much free time to dedicate to nana :( The option of the string "<>" has seemed interesting to me from the beginning, and if you add a better diagnosis to find the errors, it will be much easier to use them. The option of @ravenspoint is interesting and seeing the last image is amazing what has been achieved. But I think it's a bit more difficult, especially when I start, I do not know if it's because I never did it that way. nana-creator I really liked it, and that's what I'm used to, pity it's not updated. Now that @jinhao has started an editor's project, I hope that the following is nana-creator :) a greeting
edited Apr 11 at 6:45 pm

Thank ravenspoint !
I know you like the coordinate directly, but at the risk of insulting you I want to ask: have you reviewed the facilities in:

include\nana\basic_types.hpp ?

It can help with those calculations. The important thing is if you see a way to improve the API for
point, rectangle, widget.move(), etc., so that everything is easier and efficient. Approximately in this direction:

nana::point       p{ 20,30}, inc{0,25};
nana::size        z{180,25};
nana::rectangle   r{ p, z};

cb1_1.move        ( r );
cb1_2.move        ({p+=inc, z});
cb1_3.move        ({p+=inc, z});
cb1_4.move        ({p+=inc, z});
lbDirective.move  ({p+=inc, z});
cb1_5.move        ({p+=inc, z});
cb1_6.move        ({p+=inc, z});
cb1_7.move        ({p+=inc, z});

rectangle could have a .dy(int), so:

nana::point       p{ 20,30};
int             inc{25};
nana::size        z{180,25};
nana::rectangle   r{ p, z};

cb1_1.move        ( r );
cb1_2.move        ( r.dy(inc) );
cb1_3.move        ( r.dy(inc) );
cb1_4.move        ( r.dy(inc) );
lbDirective.move  ( r.dy(inc) );
cb1_5.move        ( r.dy(inc) );
cb1_6.move        ( r.dy(inc) );
cb1_7.move        ( r.dy(inc) );
Thank ravenspoint ! I know you like the coordinate directly, but at the risk of insulting you I want to ask: have you reviewed the facilities in: include\nana\basic_types.hpp ? It can help with those calculations. The important thing is if you see a way to improve the API for `point`, `rectangle`, `widget.move()`, etc., so that everything is easier and efficient. Approximately in this direction: ```` nana::point p{ 20,30}, inc{0,25}; nana::size z{180,25}; nana::rectangle r{ p, z}; cb1_1.move ( r ); cb1_2.move ({p+=inc, z}); cb1_3.move ({p+=inc, z}); cb1_4.move ({p+=inc, z}); lbDirective.move ({p+=inc, z}); cb1_5.move ({p+=inc, z}); cb1_6.move ({p+=inc, z}); cb1_7.move ({p+=inc, z}); ```` `rectangle` could have a .dy(int), so: ```` nana::point p{ 20,30}; int inc{25}; nana::size z{180,25}; nana::rectangle r{ p, z}; cb1_1.move ( r ); cb1_2.move ( r.dy(inc) ); cb1_3.move ( r.dy(inc) ); cb1_4.move ( r.dy(inc) ); lbDirective.move ( r.dy(inc) ); cb1_5.move ( r.dy(inc) ); cb1_6.move ( r.dy(inc) ); cb1_7.move ( r.dy(inc) ); ````

No insult taken!

Your proposal is to replace:

y += yinc;
cb1_3.move( { x,y, w, h } );

with

cb1_3.move( r.dy( yinc ) );

I cannot see much advantage to it. It saves one line of code. The line saved is easily understood, even by a person who knows nothing about the nana library. Instead we have a rather cryptic line which to be understood requires the reader to go hunting in obscure corners of the nana documentation.

I do like reducing the number of lines of code, but not when it makes the code harder to understand. Code readability is critically important for maintenance.

No insult taken! Your proposal is to replace: y += yinc; cb1_3.move( { x,y, w, h } ); with cb1_3.move( r.dy( yinc ) ); I cannot see much advantage to it. It saves one line of code. The line saved is easily understood, even by a person who knows nothing about the nana library. Instead we have a rather cryptic line which to be understood requires the reader to go hunting in obscure corners of the nana documentation. I do like reducing the number of lines of code, but not when it makes the code harder to understand. Code readability is critically important for maintenance.

I tried:

cb1_2.move        ({p+=inc, z});

but it does not compile

C:\Users\James\code\FOP1B\ConditionGUI\main.cpp:290:32:
 error: converting to 'const nana::rectangle' from initializer list 
would use explicit constructor 'nana::rectangle::rectangle(const point&, const nana::size&)'
     cb1_2.move( { p+=yinc, z } );
I tried: cb1_2.move ({p+=inc, z}); but it does not compile ```` C:\Users\James\code\FOP1B\ConditionGUI\main.cpp:290:32: error: converting to 'const nana::rectangle' from initializer list would use explicit constructor 'nana::rectangle::rectangle(const point&, const nana::size&)' cb1_2.move( { p+=yinc, z } ); ````

I introduced a new place::error derived from std::invalid_argument:

        class error :public std::invalid_argument
        {
        public:
            error(    const std::string& what,
                    const place& plc,
                    std::string            field = "unknown",
                    std::string::size_type pos = std::string::npos);
            std::string base_what;
            std::string owner_caption;  ///< truncate caption (title) of the "placed" widget
            std::string div_text;       ///< involved div_text
            std::string field;          ///< posible field where the error ocurred.  
            std::string::size_type pos; ///< posible position in the div_text where the error ocurred. npos if unknown
        };

The bad examples from this discussion now produce:

We have an invalid_argument: from widget 'Nana Window'; nana::place error failed
to set div('p1 <a> <b> > p2 <a> <d> >' ): the div-text ends prematurely from place implementation ' in field 'p1' at position 12 in div_text:

or

We have an invalid_argument: from widget 'Nana Window'; nana::place error failed
to set div('p1 <a> <b> p2 <a> <d> >' ): the div-text ends prematurely from place implementation ' in field 'p2' at position 24 in div_text:

or

We have an invalid_argument: from widget 'Nana Window'; nana::place error failed
to set div('p1 <a> <a> p2 <a> <d> ' ): place, the name 'a' is redefined.' in field 'unknown' in div_text:

This will need testing.

I introduced a new `place::error` derived from `std::invalid_argument`: ```` class error :public std::invalid_argument { public: error( const std::string& what, const place& plc, std::string field = "unknown", std::string::size_type pos = std::string::npos); std::string base_what; std::string owner_caption; ///< truncate caption (title) of the "placed" widget std::string div_text; ///< involved div_text std::string field; ///< posible field where the error ocurred. std::string::size_type pos; ///< posible position in the div_text where the error ocurred. npos if unknown }; ```` The bad examples from this discussion now produce: >We have an invalid_argument: from widget 'Nana Window'; nana::place error failed to set div('p1 <a> <b> > p2 <a> <d> >' ): the div-text ends prematurely from place implementation ' in field 'p1' at position 12 in div_text: or >We have an invalid_argument: from widget 'Nana Window'; nana::place error failed to set div('p1 <a> <b> p2 <a> <d> >' ): the div-text ends prematurely from place implementation ' in field 'p2' at position 24 in div_text: or > We have an invalid_argument: from widget 'Nana Window'; nana::place error failed to set div('p1 <a> <a> p2 <a> <d> ' ): place, the name 'a' is redefined.' in field 'unknown' in div_text: This will need testing.

I like the detailed error messages. I think they will make the place feature much more usable. ( I would just suggest removing "We have an " - these words are redundant. )

I like the detailed error messages. I think they will make the place feature much more usable. ( I would just suggest removing "We have an " - these words are redundant. )

We have .. Was added by the example. I hope to find time to make it better

We have .. Was added by the example. I hope to find time to make it better
12
214
views
35
replies
6
followers
live preview
enter atleast 10 characters
WARNING: You mentioned %MENTIONS%, but they cannot see this message and will not be notified
Saving...
Saved
All posts under this topic will be deleted ?
Pending draft ... Click to resume editing
Discard draft