cancel
Showing results for 
Search instead for 
Did you mean: 

Example: Grouping of Views with Common Functionality.

Martin KJELDSEN
Chief III

Hi everyone,

It's not unknown to people that TouchGFX designer is missing a key functionality: Grouping of views that have shared functionality, and separating the shared code into some interface. It's a feature that will appear in the Designer since it is currently not able to do this.

So far people are adding the same custom container to different views to achieve "shared" functionality, but this only takes care of the UI definitions and not code that could also be shared, like handlers for buttons (which had to be written again in each view).

A proper solution requires modifying the generated files, which will get overwritten again during the next code generation. Still, i've put together an example that you can look at to get a general overview. I'm attaching it here now, and will follow up with a detailed description of what's going on. I suppose we could consider this a pre-cursor to what will happen in the designer at some point and then you'll be READY and understand everything! =)

I will also write some scripts that you can use in your post-generate commands to modify groups of screens to inherit some common View AND presenter code. (e.g. A status bar and a presenter that can receive updates for it, completely abstracted away from the concrete views you're working on.

The Base View and Presenter must be written by hand, but i'll lay this out in what you need to consider here. You could use the designer to generate the view code and simply copy it. I'll build up the example as i go. This won't be required when the real features hits the designer, of course !: )

My plan is something like:

  1. Provide example that shows how to abstract shared View UI (Done)
  2. Modify example to show how to abstract shared Presenter logic (e.g. gotoScreen(X), showOverlay(), etc)
  3. Provide guidelines and script that can modify view code, post-generate, to inherit this functionality.
  4. Modify example to show how to abstract common helper functions into different interface that will be usable from all views.
  5. ....

Let me know if there are other requests.

I'll update this thread as i go with improved functionality and project attachments. For now please find attached a project that will take you from screen1 to screen 2 to screen 3 to screen 1... (interactions and buttons for now) but using a shared BaseView interface that lets each screen set the color of their inherited TopBar. I'll get into details later.

Instructions:

Do not generate code from the TouchGFX designer or you'll overwrite the changes. I will come up with a script at some later time that you will insert into the post-generate-command to fix up all generated view groups.

To simply run the project without generating view code simply run this command from your TouchGFX environment:

make -f simulator/gcc/Makefile

Note: I removed anything but the win32 mingw simulator library to keep it small.

Below screenshots show two of the three screens in the application where each concrete View class calls a function defined in their base view to set the color of the inherited/shared top-bar.

0693W000000UzbcQAC.png

0693W000000UzbhQAC.png

/Martin

1 ACCEPTED SOLUTION

Accepted Solutions
Martin KJELDSEN
Chief III

Screen1View calls a goto method through it's BasePresenter after 100 ticks.

presenter->gotoScreen2();

/Martin

View solution in original post

27 REPLIES 27
Martin KJELDSEN
Chief III
 
Martin KJELDSEN
Chief III

Screen1View calls a goto method through it's BasePresenter after 100 ticks.

presenter->gotoScreen2();

/Martin

@Martin KJELDSEN​ your BaseViewTest_BasePresenter example works for me on my target. I have a post-generation step outside of Designer that patches my base classes using Python as per your example.

Unfortunately the example fails to build in the simulator (using Designer 4.14.0). Could you describe what needs changing to get it to build? The "Run Simulator" button causes the patched base classes to be overwritten. Is there a way to change this behaviour, or allow the base classes to be patched with your changes as an interim step in the simulator build process? I know there's a post-generate command in the build config menu, but it's not clear to me what this means.

Run Simulator
    Generate
        Done
    Generate Assets
        make -f simulator/gcc/Makefile assets -j8
        Reading ./application.config
        Done
    Post Generate
        touchgfx update_project --project-file=simulator/msvs/Application.vcxproj
        Done
    Compile
        make -f simulator/gcc/Makefile -j8
        Reading ./application.config
        Compiling gui/src/screen1_screen/Screen1Presenter.cpp
        Compiling gui/src/screen3_screen/Screen3View.cpp
        Compiling gui/src/model/Model.cpp
        Compiling gui/src/screen2_screen/Screen2View.cpp
        Compiling gui/src/screen3_screen/Screen3Presenter.cpp
        Compiling gui/src/screen2_screen/Screen2Presenter.cpp
        Compiling gui/src/screen1_screen/Screen1View.cpp
        Compiling gui/src/common/BasePresenter.cpp
        Compiling gui/src/common/FrontendApplication.cpp
        gui/src/screen1_screen/Screen1View.cpp: In member function 'virtual void Screen1View::setupScreen()':
        gui/src/screen1_screen/Screen1View.cpp:13:5: error: 'BaseView' has not been declared
             BaseView::setTopBarColor(touchgfx::Color::getColorFrom24BitRGB(255, 0, 255));
             ^~~~~~~~
        gui/src/screen1_screen/Screen1View.cpp:13:40: error: 'touchgfx::Color' has not been declared
             BaseView::setTopBarColor(touchgfx::Color::getColorFrom24BitRGB(255, 0, 255));
                                                ^~~~~
        gui/src/screen1_screen/Screen1Presenter.cpp: In constructor 'Screen1Presenter::Screen1Presenter(Screen1View&)':
        gui/src/screen1_screen/Screen1Presenter.cpp:5:31: error: no matching function for call to 'BasePresenter::BasePresenter(Screen1View&)'
             : BasePresenter(v), view(v)
                                       ^
        In file included from gui/include/gui/screen1_screen/Screen1Presenter.hpp:6:0,
                         from generated/gui_generated/include/gui_generated/screen1_screen/Screen1ViewBase.hpp:9,
                         from gui/include/gui/screen1_screen/Screen1View.hpp:4,
                         from gui/src/screen1_screen/Screen1Presenter.cpp:1:
        gui/include/gui/common/BasePresenter.hpp:14:5: note: candidate: BasePresenter::BasePresenter(BaseViewInterface&)
             BasePresenter(BaseViewInterface& view);
             ^~~~~~~~~~~~~
        gui/include/gui/common/BasePresenter.hpp:14:5: note:   no known conversion for argument 1 from 'Screen1View' to 'BaseViewInterface&'
        gui/include/gui/common/BasePresenter.hpp:11:7: note: candidate: constexpr BasePresenter::BasePresenter(const BasePresenter&)
         class BasePresenter : public Presenter, public ModelListener
               ^~~~~~~~~~~~~
        gui/include/gui/common/BasePresenter.hpp:11:7: note:   no known conversion for argument 1 from 'Screen1View' to 'const BasePresenter&'
        gui/include/gui/common/BasePresenter.hpp:11:7: note: candidate: constexpr BasePresenter::BasePresenter(BasePresenter&&)
        gui/include/gui/common/BasePresenter.hpp:11:7: note:   no known conversion for argument 1 from 'Screen1View' to 'BasePresenter&&'
        generated/simulator/gcc/Makefile:190: recipe for target 'build/MINGW32_NT-6.2/gui/src/screen1_screen/Screen1View.o' failed
        make[2]: *** [build/MINGW32_NT-6.2/gui/src/screen1_screen/Screen1View.o] Error 1
        make[2]: *** Waiting for unfinished jobs....
        generated/simulator/gcc/Makefile:190: recipe for target 'build/MINGW32_NT-6.2/gui/src/screen1_screen/Screen1Presenter.o' failed
        make[2]: *** [build/MINGW32_NT-6.2/gui/src/screen1_screen/Screen1Presenter.o] Error 1
        generated/simulator/gcc/Makefile:149: recipe for target 'generate_assets' failed
        make[1]: *** [generate_assets] Error 2
        simulator/gcc/Makefile:32: recipe for target 'all' failed
        make: *** [all] Error 2
        Failed
    Failed

​You have to patch as part of the "post-geneate" step which you can define in your .touchgfx project file. Then the changes will applied after the designer "cleans" (your changes) and re-generates.

How is the post-generate changed to insert a Python script or batch file to run? These are my default settings:-

  "GenerateAssetsCommand": "make -f simulator/gcc/Makefile assets -j8",

  "PostGenerateCommand": "touchgfx update_project --project-file=simulator/msvs/Application.vcxproj",

  "PostGenerateTargetCommand": "touchgfx update_project --project-file=../***.ioc --platform=m4",

  "CompileSimulatorCommand": "make -f simulator/gcc/Makefile -j8",

  "RunSimulatorCommand": "build\\bin\\simulator.exe",

​Just type it out:

"PostGenerateCommand": "python script.py"

The only thing here may be that python is not on your path. Modify "profile" inside this folder to make python available from the touchgfx environment.

e.g.

C:\TouchGFX\4.16.0\env\MinGW\msys\1.0\etc\profile

Great. What about the original line? Is this needed and can it be appended?

"touchgfx update_project --project-file=simulator/msvs/Application.vcxproj"

​This entire command would just be thrown to the shell, so standard rules apply - e.g.

"PostGenerateCommand": "python script.py && touchgfx update_project... && myscript"

​Also, i can happily tell you that base-view support is being considered for the designer now :)