Hello

Nana has an interesting way to align the different widgets. I found this article:

http://nanapro.org/en-us/blog/2016/05/an-introduction-to-nana-c-library/

Using colors offers a very clear vision of how widgets are distributed on the screen.

For simple designs it is fine, but for more complex ones it can be a real chaos.

Using nana-creator I recreate a complex window (about 40 widgets) of one of my programs in just 2 hours (without previous knowledge about nana-creator) which I think is very good.

But nana-creator is not up-to-date and unintuitive. I think that this program should be improved and updated. Having good tools surely attracts more users.

How do you do to design the windows?

a greeting

Hello Nana has an interesting way to align the different widgets. I found this article: http://nanapro.org/en-us/blog/2016/05/an-introduction-to-nana-c-library/ Using colors offers a very clear vision of how widgets are distributed on the screen. For simple designs it is fine, but for more complex ones it can be a real chaos. Using nana-creator I recreate a complex window (about 40 widgets) of one of my programs in just 2 hours (without previous knowledge about nana-creator) which I think is very good. But nana-creator is not up-to-date and unintuitive. I think that this program should be improved and updated. Having good tools surely attracts more users. How do you do to design the windows? a greeting

It's a big question.

For a brief answer describing my own approach, take a look at https://github.com/qPCR4vir/nana-docs/wiki/Introductory-Usage-Example-Code

IMHO, using 'form designer' tools should be avoided. They are like crutches for people who do not know what they are doing. The snag is that they generate vast amounts of code which the user does not understand. They are great for rapidly developing a quick prototype of a toy application. However, one day one of your applications may grow up into a successful product which needs to be maintained. Guess what? The tools are limited and buggy, and cannot be used to maintain a GUI of any real complexity or sophistication. So, all that un-maintainable code generated by the tool has to be rewrittenn by someone who has been using the tool and so has not learnt how to write GUI code!

This process happened to me a couple of times, back in the days when GUIs first became popular. Then I learnt that there is no substitute for learning how to code a GUI, and the only way to do that is to roll up your sleeves and write the code.

I do understand why form builder tools are so popular. Many GUI frameworks are a major pain to code for: requiring reams of code specifying the top left and bottom right pixel position of every last control - all of which have to be changed whenever anything is moved around. It is tempting to skip all that tedious work and rely on a form designer tool, but if you hope to make a success of GUI design you should resist the temptation and actually do the work yourself.

The nana library does offer a sort of half way house called a place class ( http://nanapro.org/en-us/documentation/page.php?u=/utilities/place ) which purports to handle layout of widgets. I do not use it very often, mostly for laying out many small widgets in large regular grids. For normal higgledy-piggledy GUI layouts all that mucking around with nested angle brackets quickly drives me mad. A big problem is if you make a single mistake with the nesting of the brackets then your application will crash without giving a clue where the problem is.

It's a big question. For a brief answer describing my own approach, take a look at https://github.com/qPCR4vir/nana-docs/wiki/Introductory-Usage-Example-Code IMHO, using 'form designer' tools should be avoided. They are like crutches for people who do not know what they are doing. The snag is that they generate vast amounts of code which the user does not understand. They are great for rapidly developing a quick prototype of a toy application. However, one day one of your applications may grow up into a successful product which needs to be maintained. Guess what? The tools are limited and buggy, and cannot be used to maintain a GUI of any real complexity or sophistication. So, all that un-maintainable code generated by the tool has to be rewrittenn by someone who has been using the tool and so has not learnt how to write GUI code! This process happened to me a couple of times, back in the days when GUIs first became popular. Then I learnt that there is no substitute for learning how to code a GUI, and the only way to do that is to roll up your sleeves and write the code. I do understand why form builder tools are so popular. Many GUI frameworks are a major pain to code for: requiring reams of code specifying the top left and bottom right pixel position of every last control - all of which have to be changed whenever anything is moved around. It is tempting to skip all that tedious work and rely on a form designer tool, but if you hope to make a success of GUI design you should resist the temptation and actually do the work yourself. The nana library does offer a sort of half way house called a place class ( http://nanapro.org/en-us/documentation/page.php?u=/utilities/place ) which purports to handle layout of widgets. I do not use it very often, mostly for laying out many small widgets in large regular grids. For normal higgledy-piggledy GUI layouts all that mucking around with nested angle brackets quickly drives me mad. A big problem is if you make a single mistake with the nesting of the brackets then your application will crash without giving a clue where the problem is.
edited Apr 5 at 10:37 pm

I like to design the gui in figma and use panels and place to sort out the components of the gui.

I like to design the gui in figma and use panels and place to sort out the components of the gui.

Hello

It's a big question.

Yes it is smile

Interesting your proposal. But I still see the same problem: good for simple things, but for complex designs I think it's crazy to manually calculate the position of all the widgets.

Also, if you want to redesign the window / change / remove some widgets it would be complicated. Use "<> <> ...." or position manually I see it well for small designs.

An example, the following image is a capture of a design view of one of the windows of my application (it is not finished, it still needs a lot):

5ca8ec2f39244.png

It is something more complex than an example. Designing that with any of the two previous methods would be very complicated.

Personally I like the programs that help you design the GUI (that is made with one). They have their advantages and disadvantages, but I think they help a lot.

a greeting

Hello >It's a big question. Yes it is :) Interesting your proposal. But I still see the same problem: good for simple things, but for complex designs I think it's crazy to manually calculate the position of all the widgets. Also, if you want to redesign the window / change / remove some widgets it would be complicated. Use "<> <> ...." or position manually I see it well for small designs. An example, the following image is a capture of a design view of one of the windows of my application (it is not finished, it still needs a lot): ![5ca8ec2f39244.png](serve/attachment&path=5ca8ec2f39244.png) It is something more complex than an example. Designing that with any of the two previous methods would be very complicated. Personally I like the programs that help you design the GUI (that is made with one). They have their advantages and disadvantages, but I think they help a lot. a greeting

Use "<> <> ...."

The big problem here is that if you make a mistake nesting the angle brackets, which is very easy to do with a complex GUI, then you do not get an error message but the application just mysteriously crashes. Finding the mistake is tough enough, but when you have no clue where to look ...

I think it's crazy to manually calculate the position of all the widgets.

I do understand why you feel that. For me juggling those angle brackets is what drives me crazy. A big help is to make generous use of panels to hold small groups of widgets. Then you can move the panel and the layout of the widgets in the panel remains, but in the new position.

For comparison, here is a screenshot of the GUI I have been working on

5ca8ee188fd2d.png

Each panel has just a few widgets, and the app window is made up of a number of panels, so there is not much to do when something needs to be moved.

FYI here is the top level move function that places the panels in their correct positions. The individual calls to *Widget.Move() look after the layout of the widgets in each panel.

void cPPEForm::Move()
{
    const int widget_inc = 100;

    int xgp = 5;
    int ygp = 20;
    myApplyWidget.Move( xgp, ygp );

    ygp += 45;
    myEMISWidget.Move( xgp, ygp );


    xgp += widget_inc;
    ygp = 30;
    myDetectorWidget.Move( xgp, ygp );
    ygp = 150;
    myEnableWidget.Move( xgp, ygp );


    xgp += widget_inc;
    ygp = 30;
    myChannelWidget.Move( xgp, ygp );

    xgp += widget_inc;
    myAverageWidget.Move( xgp, ygp );

    xgp += widget_inc;
    myAlgorithmWidget.Move( xgp, ygp );

    xgp += widget_inc;
    myPolarityWidget.Move( xgp, ygp );

    xgp += widget_inc;
    mySeparationWidget.Move( xgp, ygp );

    xgp += widget_inc;
    myHeightWidget.Move( xgp, ygp );

    xgp += widget_inc;
    myWidthWidget.Move( xgp, ygp );

    xgp += widget_inc;
    myRangeWidget.Move( xgp, ygp );

    xgp += widget_inc;
    mySlopeMinWidget.Move( xgp, ygp );

    xgp += widget_inc;
    mySlopeMaxWidget.Move( xgp, ygp );
}
> Use "<> <> ...." The big problem here is that if you make a mistake nesting the angle brackets, which is very easy to do with a complex GUI, then you do not get an error message but the application just mysteriously crashes. Finding the mistake is tough enough, but when you have no clue where to look ... > I think it's crazy to manually calculate the position of all the widgets. I do understand why you feel that. For me juggling those angle brackets is what drives me crazy. A big help is to make generous use of panels to hold small groups of widgets. Then you can move the panel and the layout of the widgets in the panel remains, but in the new position. For comparison, here is a screenshot of the GUI I have been working on ![5ca8ee188fd2d.png](serve/attachment&path=5ca8ee188fd2d.png) Each panel has just a few widgets, and the app window is made up of a number of panels, so there is not much to do when something needs to be moved. FYI here is the top level move function that places the panels in their correct positions. The individual calls to *Widget.Move() look after the layout of the widgets in each panel. ```C++ void cPPEForm::Move() { const int widget_inc = 100; int xgp = 5; int ygp = 20; myApplyWidget.Move( xgp, ygp ); ygp += 45; myEMISWidget.Move( xgp, ygp ); xgp += widget_inc; ygp = 30; myDetectorWidget.Move( xgp, ygp ); ygp = 150; myEnableWidget.Move( xgp, ygp ); xgp += widget_inc; ygp = 30; myChannelWidget.Move( xgp, ygp ); xgp += widget_inc; myAverageWidget.Move( xgp, ygp ); xgp += widget_inc; myAlgorithmWidget.Move( xgp, ygp ); xgp += widget_inc; myPolarityWidget.Move( xgp, ygp ); xgp += widget_inc; mySeparationWidget.Move( xgp, ygp ); xgp += widget_inc; myHeightWidget.Move( xgp, ygp ); xgp += widget_inc; myWidthWidget.Move( xgp, ygp ); xgp += widget_inc; myRangeWidget.Move( xgp, ygp ); xgp += widget_inc; mySlopeMinWidget.Move( xgp, ygp ); xgp += widget_inc; mySlopeMaxWidget.Move( xgp, ygp ); } ```
edited Apr 6 at 7:30 pm

then you do not get an error message but the application just mysteriously crashes.

Actually, it is caused by uncatched exception. To obtain the error, cath the std::runtime_error and see what()

>then you do not get an error message but the application just mysteriously crashes. Actually, it is caused by uncatched exception. To obtain the error, cath the `std::runtime_error` and see `what()`

Are you sure? Have you tested it? The docs contain no mention that place::div() throws exceptions.

I tried some experiments to test your theory. It turns out to be surprisingly hard to reproduce the problem. All sort of malformed div-texts are accepted, and result in weird and wonderful displays. e.g.

  plc.div("p1 <a> <b> > p2 <a> <d> >");

This contains two fields names "a" and two unmatched right angle brackets, yet is accepted without complaint. Surely the code should at least check for matching numbers of left and right brackets?

Anyway, I finally found a way to reproduce the problem. The following code does not throw a runtime_errror exception, but something else!

#include <iostream>
#include <nana/gui.hpp>
#include <nana/gui/widgets/checkbox.hpp>

int main()
{
    try
    {
        // construct application form
        nana::form fm( nana::rectangle( 100,100, 300, 300 ));

        nana::checkbox cb1( fm);
        cb1.caption("one");
        nana::checkbox cb2(fm);
        cb2.caption("two");
        nana::checkbox cb3(fm);
        cb3.caption("three");
        nana::checkbox cb4(fm);
        cb4.caption("four");

        try
        {
            nana::place plc{fm}; //fm is an instance of nana::form
            plc.div("p1 <a> <a> > p2 <a> <d> >");
            plc["a"]<<cb1;
            plc["b"]<<cb2;
            plc["c"]<<cb3;
            plc["d"]<<cb4;
            plc.collocate();
        }
        catch( std::runtime_error& e )
        {
            std::cout << e.what();
            nana::msgbox m( e.what() );
            m.show();
            throw;
        }

        // show & run
        fm.show();
        nana::exec();
    }
    catch( std::runtime_error& e )
    {
        std::cout << e.what();
    }
    catch( ... )
    {
        std::cout << "unknown exception thrown\n";
    }
}

I have added a warning about the error handling difficulties in using place to https://github.com/qPCR4vir/nana-docs/wiki/Using-place-for-layouts

Are you sure? Have you tested it? The docs contain no mention that place::div() throws exceptions. I tried some experiments to test your theory. It turns out to be surprisingly hard to reproduce the problem. All sort of malformed div-texts are accepted, and result in weird and wonderful displays. e.g. plc.div("p1 <a> <b> > p2 <a> <d> >"); This contains two fields names "a" and two unmatched right angle brackets, yet is accepted without complaint. Surely the code should at least check for matching numbers of left and right brackets? Anyway, I finally found a way to reproduce the problem. The following code does not throw a runtime_errror exception, but something else! ```C++ #include <iostream> #include <nana/gui.hpp> #include <nana/gui/widgets/checkbox.hpp> int main() { try { // construct application form nana::form fm( nana::rectangle( 100,100, 300, 300 )); nana::checkbox cb1( fm); cb1.caption("one"); nana::checkbox cb2(fm); cb2.caption("two"); nana::checkbox cb3(fm); cb3.caption("three"); nana::checkbox cb4(fm); cb4.caption("four"); try { nana::place plc{fm}; //fm is an instance of nana::form plc.div("p1 <a> <a> > p2 <a> <d> >"); plc["a"]<<cb1; plc["b"]<<cb2; plc["c"]<<cb3; plc["d"]<<cb4; plc.collocate(); } catch( std::runtime_error& e ) { std::cout << e.what(); nana::msgbox m( e.what() ); m.show(); throw; } // show & run fm.show(); nana::exec(); } catch( std::runtime_error& e ) { std::cout << e.what(); } catch( ... ) { std::cout << "unknown exception thrown\n"; } } ``` I have added a warning about the error handling difficulties in using place to https://github.com/qPCR4vir/nana-docs/wiki/Using-place-for-layouts
edited Apr 7 at 9:14 pm

I'm sorry to say that I'm in my free days with my family and I dindt have time for this. This is very interesting. I hope I will have the time to talk about this, just like the others.
And I thought it will be difficult to find the errors, and very possible you find a real error in place, with is a very compicate piece of code.
But after 10 s of reading your example - pleace revise your c++:
your place object plc is local to the try block and non existing at the moment of the show and execute.
An unrelate, but, please document the parts of nana that you already know (which we all really apreaciate!), not the parts that you dont yet.

I'm sorry to say that I'm in my free days with my family and I dindt have time for this. This is very interesting. I hope I will have the time to talk about this, just like the others. And I thought it will be difficult to find the errors, and very possible you find a real error in place, with is a very compicate piece of code. But after 10 s of reading your example - pleace revise your c++: your place object `plc` is local to the try block and non existing at the moment of the show and execute. An unrelate, but, please document the parts of nana that you already know (which we all really apreaciate!), not the parts that you dont yet.

Of course, if you find that Nana is crashing your program, report it immediately, since it is a serious error. No part of nana causes a crash "by design", but only by mistake, which are usually fixed very quickly

Of course, if you find that Nana is crashing your program, report it immediately, since it is a serious error. No part of nana causes a crash "by design", but only by mistake, which are usually fixed very quickly

your place object plc is local to the try block and non existing at the moment of the show and execute.

Good point!

I moved it outside the inner try block. Program still dies.

#include <iostream>
#include <nana/gui.hpp>
#include <nana/gui/widgets/checkbox.hpp>

int main()
{
    try
    {
        // construct application form
        nana::form fm( nana::rectangle( 100,100, 300, 300 ));

        nana::checkbox cb1( fm);
        cb1.caption("one");
        nana::checkbox cb2(fm);
        cb2.caption("two");
        nana::checkbox cb3(fm);
        cb3.caption("three");
        nana::checkbox cb4(fm);
        cb4.caption("four");

        nana::place plc{fm}; //fm is an instance of nana::form
        try
        {

            plc.div("p1 <a> <a> > p2 <a> <d> >");
            plc["a"]<<cb1;
            plc["b"]<<cb2;
            plc["c"]<<cb3;
            plc["d"]<<cb4;
            plc.collocate();
        }
        catch( std::runtime_error& e )
        {
            std::cout << e.what();
            nana::msgbox m( e.what() );
            m.show();
            throw;
        }
        catch( std::invalid_argument& e )
        {
            throw;
        }

        // show & run
        fm.show();
        nana::exec();
    }
    catch( std::runtime_error& e )
    {
        std::cout << e.what();
    }
    catch( std::invalid_argument& e )
    {
        std::cout << "invalid argument " << e.what() << "\n";
    }
    catch( ... )
    {
        std::cout << "unkown exception thrown\n";
    }
}
> your place object plc is local to the try block and non existing at the moment of the show and execute. Good point! I moved it outside the inner try block. Program still dies. ```C++ #include <iostream> #include <nana/gui.hpp> #include <nana/gui/widgets/checkbox.hpp> int main() { try { // construct application form nana::form fm( nana::rectangle( 100,100, 300, 300 )); nana::checkbox cb1( fm); cb1.caption("one"); nana::checkbox cb2(fm); cb2.caption("two"); nana::checkbox cb3(fm); cb3.caption("three"); nana::checkbox cb4(fm); cb4.caption("four"); nana::place plc{fm}; //fm is an instance of nana::form try { plc.div("p1 <a> <a> > p2 <a> <d> >"); plc["a"]<<cb1; plc["b"]<<cb2; plc["c"]<<cb3; plc["d"]<<cb4; plc.collocate(); } catch( std::runtime_error& e ) { std::cout << e.what(); nana::msgbox m( e.what() ); m.show(); throw; } catch( std::invalid_argument& e ) { throw; } // show & run fm.show(); nana::exec(); } catch( std::runtime_error& e ) { std::cout << e.what(); } catch( std::invalid_argument& e ) { std::cout << "invalid argument " << e.what() << "\n"; } catch( ... ) { std::cout << "unkown exception thrown\n"; } } ```

?? copy /pasted exactly from here

C:\Prog\ExtLib\cmake-build-nana-demo-msys-release\place_runtime_error.exe
invalid argument place, the name 'a' is redefined.

are you closing your windows too fast?

?? copy /pasted exactly from here ```` C:\Prog\ExtLib\cmake-build-nana-demo-msys-release\place_runtime_error.exe invalid argument place, the name 'a' is redefined. ```` are you closing your windows too fast?

ahh, I see, this is another c++ error: you

        catch( std::invalid_argument& e )
        {
            throw;
        }

why not?:

        catch( std::invalid_argument& e )
        {
            std::cout << e.what();
            nana::msgbox m( e.what() );
            m.show();
            throw;
        }

After this unrelated to nana c++ errors were corrected, it works as claimed by nana.

ahh, I see, this is another c++ error: you ```` catch( std::invalid_argument& e ) { throw; } ```` why not?: ```` catch( std::invalid_argument& e ) { std::cout << e.what(); nana::msgbox m( e.what() ); m.show(); throw; } ```` After this unrelated to nana c++ errors were corrected, it works as claimed by nana.
edited Apr 8 at 11:18 am

Are you sure? Have you tested it?

smile sorry, but here ... of course it has been tested a lot, and used intensively in soft that run very well.
But bugs are expected to appear. Keep testing.

The docs contain no mention that place::div() throws exceptions.

Yes, it is only mentioned here:http://nanapro.org/en-us/documentation/page.php?u=/utilities/place
coming from https://github.com/cnjinhao/nana-refman/blob/master/en-us/content/utilities/place.txt#L143
It definitively need more attention.

I tried some experiments to test your theory.

smile

It turns out to be surprisingly hard to reproduce the problem. All sort of malformed div-texts are accepted, and result in weird and wonderful displays. e.g.

Yes, a second philosophy of nana is to be "benevolent" and ignore errors when there is some more or less acceptable alternative. Maybe for the div string of place we can introduce an "strict" keyword to throw always.

>Are you sure? Have you tested it? :D sorry, but here ... of course it has been tested a lot, and used intensively in soft that run very well. But bugs are expected to appear. Keep testing. >The docs contain no mention that place::div() throws exceptions. Yes, it is only mentioned here:http://nanapro.org/en-us/documentation/page.php?u=/utilities/place coming from https://github.com/cnjinhao/nana-refman/blob/master/en-us/content/utilities/place.txt#L143 It definitively need more attention. >I tried some experiments to test your theory. :D >It turns out to be surprisingly hard to reproduce the problem. All sort of malformed div-texts are accepted, and result in weird and wonderful displays. e.g. Yes, a second philosophy of nana is to be "benevolent" and ignore errors when there is some more or less acceptable alternative. Maybe for the div string of place we can introduce an "strict" keyword to throw always.

Thinking on adding a new nana-demo test:

/**
* Created by ravenspoint on 08.04.2019 to illustrate place error checking.
* Modiffied by qPCR4vir
*/

#include <iostream>
#include <nana/gui.hpp>
#include <nana/gui/widgets/checkbox.hpp>

int main()try
{
    // construct application form
    nana::form fm( nana::rectangle( 100,100, 300, 300 ));

    nana::checkbox  cb1{fm, "one"  },
                    cb2{fm, "two"  },
                    cb3{fm, "three"},
                    cb4{fm, "four" };

        nana::place plc{fm}; //fm is an instance of nana::form
        try
        {
            plc.div("p1 <a> <b> > p2 <a> <d> >");
            plc["a"]<<cb1;
            plc["b"]<<cb2;
            plc["c"]<<cb3;
            plc["d"]<<cb4;
            plc.collocate();
        }
        catch( std::runtime_error& e )
        {
            std::cout <<"We have a runtime_error: "<< e.what();
            nana::msgbox m( "Sorry... we have a runtime_error !!");
            m<<e.what() ;
            m.show();
            throw;
        }
        catch( std::invalid_argument& e )
        {
            std::cout <<"We have a invalid_argument: " << e.what();
            nana::msgbox m( "Sorry... we have an invalid_argument error !!");
            m<<e.what() ;
            m.show();
            throw;
        }
        catch( std::exception& e )
        {
            std::cout <<"We have an exception: " << e.what();
            nana::msgbox m( "Sorry... we have an exception error !!");
            m<<e.what() ;
            m.show();
            throw;
        }
        // show & run
        fm.show();
        nana::exec();
}
catch( std::runtime_error& e )
{
    std::cout << "\nruntime_error: " << e.what();
}
catch( std::invalid_argument& e )
{
    std::cout << "\ninvalid argument: " << e.what() << "\n";
}
catch( std::exception& e )
{
    std::cout << "\nexception: " << e.what() << "\n";
}
catch( ... )
{
    std::cout << "\nunkown exception thrown\n";
}
Thinking on adding a new nana-demo test: ```` /** * Created by ravenspoint on 08.04.2019 to illustrate place error checking. * Modiffied by qPCR4vir */ #include <iostream> #include <nana/gui.hpp> #include <nana/gui/widgets/checkbox.hpp> int main()try { // construct application form nana::form fm( nana::rectangle( 100,100, 300, 300 )); nana::checkbox cb1{fm, "one" }, cb2{fm, "two" }, cb3{fm, "three"}, cb4{fm, "four" }; nana::place plc{fm}; //fm is an instance of nana::form try { plc.div("p1 <a> <b> > p2 <a> <d> >"); plc["a"]<<cb1; plc["b"]<<cb2; plc["c"]<<cb3; plc["d"]<<cb4; plc.collocate(); } catch( std::runtime_error& e ) { std::cout <<"We have a runtime_error: "<< e.what(); nana::msgbox m( "Sorry... we have a runtime_error !!"); m<<e.what() ; m.show(); throw; } catch( std::invalid_argument& e ) { std::cout <<"We have a invalid_argument: " << e.what(); nana::msgbox m( "Sorry... we have an invalid_argument error !!"); m<<e.what() ; m.show(); throw; } catch( std::exception& e ) { std::cout <<"We have an exception: " << e.what(); nana::msgbox m( "Sorry... we have an exception error !!"); m<<e.what() ; m.show(); throw; } // show & run fm.show(); nana::exec(); } catch( std::runtime_error& e ) { std::cout << "\nruntime_error: " << e.what(); } catch( std::invalid_argument& e ) { std::cout << "\ninvalid argument: " << e.what() << "\n"; } catch( std::exception& e ) { std::cout << "\nexception: " << e.what() << "\n"; } catch( ... ) { std::cout << "\nunkown exception thrown\n"; } ````

The problem here (not necessary a nana error, but we can think about):

plc.div("p1 <a> <b> > p2 <a> <d> >");
                    ^~~~~~

is that this is matching the optional opening < of the implicit higher level horizontal field named "p1", which immediately terminate the parsing of the div-string, effectively ignoring the rest of it, making no place for cb3 and cb4. This implicit field is necessary to allow things like this:

plc.div("p1  grid=[3,3]");

yes, it can be improved

The problem here (not necessary a nana error, but we can think about): ```` plc.div("p1 <a> <b> > p2 <a> <d> >"); ^~~~~~ ```` is that this is matching the optional opening `<` of the implicit higher level horizontal field named "p1", which immediately terminate the parsing of the div-string, effectively ignoring the rest of it, making no place for `cb3` and `cb4`. This implicit field is necessary to allow things like this: ```` plc.div("p1 grid=[3,3]"); ```` yes, it can be improved

of course it has been tested a lot

It does not seem to be so. Did you do any "fuzz testing" at all? ( https://en.wikipedia.org/wiki/Fuzzing ) This kind of testing is vital for a feature that is designed to input highly structured human generated data.

Another important software quality measure that appears to have been neglected is firewalling or sanity checking. The first thing that should be done when the div-text is input is a count of open and close brackets. If the counts are not equal, then you can stop parsing immediatly and raise an exception.

Now that I have discovered that nana throws exceptions, I need some advice on how to handle them. The best I have come up with so far:


#include <nana/gui.hpp>


int main()
{
    // construct application form
    nana::form fm( nana::rectangle( 100,100, 300, 300 ));

    try
    {
        // do widget layout

        throw std::runtime_error("Simulated exception thrown by nana layout code\n");

    }
    catch( std::exception& e )
    {
        nana::msgbox m("Exception thrown during GUI construction");
        m << e.what();
        m.show();

        // what should be done here?
        // simply doing an exit causes en error window to pop-up talking about a memory leak
        // but we cannot let nana show a malformed form.
        // can we clear the form of any rubish that might be there and show a clean, empty form?
        exit(1);
    }

    // show & run
    fm.show();
    nana::exec();
}

I am not very happy with this. It adds a lot of complexity to the application code, the application coder needs to be very careful about what is outside and inside the try block and doing a clean shut down after reporting the error is not obvious to me.

Surely there is something better that could be done?

> of course it has been tested a lot It does not seem to be so. Did you do any "fuzz testing" at all? ( https://en.wikipedia.org/wiki/Fuzzing ) This kind of testing is vital for a feature that is designed to input highly structured human generated data. Another important software quality measure that appears to have been neglected is firewalling or sanity checking. The first thing that should be done when the div-text is input is a count of open and close brackets. If the counts are not equal, then you can stop parsing immediatly and raise an exception. Now that I have discovered that nana throws exceptions, I need some advice on how to handle them. The best I have come up with so far: ``` #include <nana/gui.hpp> int main() { // construct application form nana::form fm( nana::rectangle( 100,100, 300, 300 )); try { // do widget layout throw std::runtime_error("Simulated exception thrown by nana layout code\n"); } catch( std::exception& e ) { nana::msgbox m("Exception thrown during GUI construction"); m << e.what(); m.show(); // what should be done here? // simply doing an exit causes en error window to pop-up talking about a memory leak // but we cannot let nana show a malformed form. // can we clear the form of any rubish that might be there and show a clean, empty form? exit(1); } // show & run fm.show(); nana::exec(); } ``` I am not very happy with this. It adds a lot of complexity to the application code, the application coder needs to be very careful about what is outside and inside the try block and doing a clean shut down after reporting the error is not obvious to me. Surely there is something better that could be done?

Yes, a second philosophy of nana is to be "benevolent" and ignore errors when there is some more or less acceptable alternative. Maybe for the div string of place we can introduce an "strict" keyword to throw always.

The name for this is the robustness principle: “Be conservative in what you do, be liberal in what you accept from others.”

For an entertaining ( though long ) essay on the problems with it, take a look at this famous essay https://www.joelonsoftware.com/2008/03/17/martian-headsets/

After reading that, you may want to reconsider your choice.

> Yes, a second philosophy of nana is to be "benevolent" and ignore errors when there is some more or less acceptable alternative. Maybe for the div string of place we can introduce an "strict" keyword to throw always. The name for this is the robustness principle: “Be conservative in what you do, be liberal in what you accept from others.” For an entertaining ( though long ) essay on the problems with it, take a look at this famous essay https://www.joelonsoftware.com/2008/03/17/martian-headsets/ After reading that, you may want to reconsider your choice.

Thinking on adding a new nana-demo test:

So I tried compiling and running the code you posted. It compiles OK. Running it as a GUI program, no errors are shown, just a malformed form window. Running as a console program, no errors are shown.

I do not think an exception of any kind is being thrown.

> Thinking on adding a new nana-demo test: So I tried compiling and running the code you posted. It compiles OK. Running it as a GUI program, no errors are shown, just a malformed form window. Running as a console program, no errors are shown. I do not think an exception of any kind is being thrown.

Oh yes, very fortunate observation. That is the whole point of it in respect with your concern about what are you writing (the fuzzi thing and the standards):
this kind of error are non going to happen too your users. Only you at the very early debug step will see it, because always run the same. You fix it and it become part of your code, exactly like the code you write in your move() function. You make it work before and test it before you release the program.
In this case I saw the exception, fixed it ... and it is lost. To see it just set back:

plc.div("p1 <a> <a> > p2 <a> <d> >");

once again: I will be happy if we improve even more place
And of course, one can use place for dynamic layout, but that will be an unfair comparison with static code (I do it and works admirably, need time to show it).

Oh yes, very fortunate observation. That is the whole point of it in respect with your concern about what are you writing (the fuzzi thing and the standards): this kind of error are non going to happen too your users. Only you at the very early debug step will see it, because always run the same. You fix it and it become part of your code, exactly like the code you write in your move() function. You make it work before and test it before you release the program. In this case I saw the exception, fixed it ... and it is lost. To see it just set back: ```` plc.div("p1 <a> <a> > p2 <a> <d> >"); ```` once again: I will be happy if we improve even more `place` And of course, one can use place for dynamic layout, but that will be an unfair comparison with static code (I do it and works admirably, need time to show it).
edited Apr 8 at 5:29 pm
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