What is general method to add any gui element that user can interact with? - General Discussion and Assistance - CHDK Forum

What is general method to add any gui element that user can interact with?

  • 8 Replies
  • 3298 Views
Advertisements
Hello!

This is my 3rd hour of reading CHDK source and I'm really confused... What I want to achieve is to add anything that user could interact with by pressing keys. Let call this thing an applet. Just like games, file browser, menu and whole this stuff:)

I imagined, that this should work something like this:

  • some other part of code loads the applet (for example luascript.c):
Code: [Select]
applet_init();
  • applet now have to work in a loop: take kaypresses and redraw itself:
Code: [Select]
while (?what_here?) {
    switch (kbd_get_autoclicked_key() | get_jogdial_direction()) {
case KEY_DOWN:
            do_something_for_down_key();
            break;
    applet_draw()
}
  • and for specified key it should just return.

Nevertheless I can see that CHDK works in other way and I have no idea how I should add an interactive applet... I read fselect and calendar codes and they look not very complicated. I'm also reading gui.c and action_stack.h but I don't know when and what calls appropriate functions.  Where is the loop, that works until the end of applet usage?

I would be gratefull for any scratch of code, any description or maybe a very-very-limited part of working code.

PS. I'm working on virtual keyboard and try to use code from TobiMarg http://chdk.setepontos.com/index.php?topic=7272.msg78038#msg78038

I compiled code succesfully and I'm able to draw his keyboard but I'm unable to interact with it.
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

*

Offline philmoz

  • *****
  • 3332
    • Photos
Re: What is general method to add any gui element that user can interact with?
« Reply #1 on: 25 / December / 2011, 17:45:42 »
CHDK has two main tasks that control everything.
The keyboard task (core/kbd.c & kbd.c in each platform/camera directory) and the 'spytask' in core/main.c

The keyboard task mostly looks after button presses and the spytask takes care of drawing the U/I and processing scripts. It's not a clean seperation as there is code to process button presses in the gui code and gui drawing gets done in the keyboard task.

The gui operates in modes - set in the gui_mode variable in gui.c.
The drawing and keyboard routines specific to the mode defined in the guiHandlers table and are called as required.

The virtual keyboard will need to be a new mode - probably something like the file selector that has a callback routine to send the entered string back to.

Hope this helps.

Phil.
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

Re: What is general method to add any gui element that user can interact with?
« Reply #2 on: 25 / December / 2011, 18:13:49 »
Sure it helps:)

But now I have to translate this description in working code... And this will be hard task for me! I hope I'll do it. I'll ask in a case of problems.

Thank you!
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

*

Offline philmoz

  • *****
  • 3332
    • Photos
Re: What is general method to add any gui element that user can interact with?
« Reply #3 on: 25 / December / 2011, 18:20:22 »
Sure it helps:)

But now I have to translate this description in working code... And this will be hard task for me! I hope I'll do it. I'll ask in a case of problems.

Thank you!

Use the file selector as a base - once you can follow how it gets called and returns the file name to the caller the keyboard should be easy :)

I'm not near a PC for a while or I'd send code samples.

Phil.
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)


Re: What is general method to add any gui element that user can interact with?
« Reply #4 on: 26 / December / 2011, 03:57:01 »
Ok, I have figured out this:) There's so many files that need to be changed to add one small thing... But now I can interact with the applet. Now I can work with its layout:)
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

Re: What is general method to add any gui element that user can interact with?
« Reply #5 on: 26 / December / 2011, 04:23:19 »
For now in 1.1.0 you can use this pattern:

Code: [Select]
#include "stdlib.h"
#include "keyboard.h"
#include "platform.h"
#include "core.h"
#include "gui.h"
#include "gui_draw.h"

void gui_applet_draw_callback(int enforce_redraw);
void gui_applet_kbd_process();
void gui_applet_menu_kbd_process();

gui_handler GUI_MODE_APPLET =
       { gui_applet_draw_callback,   gui_applet_kbd_process,      gui_applet_menu_kbd_process, 0, GUI_MODE_MAGICNUM };


//-------------------------------------------------------------------
void gui_applet_init() {
    gui_set_mode( (unsigned int)&GUI_MODE_APPLET );
    applet_redraw = 2;
}

//-------------------------------------------------------------------
void gui_applet_draw_callback(int enforce_redraw) {
    if ( applet_redraw )
    {
        if ( applet_redraw==2 )
              some_initial_draws();
        partial_draws()
        applet_redraw=0;
    }
}

//-------------------------------------------------------------------
static void gui_applet_run() {
    somework();
    applet_redraw=1;
    somework();
    applet_redraw=1;
}

//-------------------------------------------------------------------
void gui_applet_kbd_process() {
    switch (kbd_get_autoclicked_key()) {
    case KEY_SET:
        gui_applet_run();
        break;
    }
}

void gui_applet_menu_kbd_process() {
        if ()
        your_action()
      else
gui_default_kbd_process_menu_btn();
}

This sample is for case If applet is build-in into the core. For modules some additional code is required. I'll write manual how to make deal with modules later.

Simple description:
- gui_applet_init() set gui mode to this applet. and set flag to this applet that full redraw required.
- each 20msec gui_applet_draw_callback is called until this gui mode is active. it check what kind of redraw required and do it.
- if non-menu button pressed, gui_applet_kbd_process() is called. For our case we catch SET pressing and start long processing which could display something in progress by raised redraw flag
- to finish applet we need just switch gui_mode. Fselector for example store previous gui_mode and restore it right after/before callback call and so exit.
 Here gui_applet_menu_kbd_process(), which is called when MENU pressed, we call in some condition gui_default_kbd_process_menu_btn() which just turn gui to menu.
« Last Edit: 26 / December / 2011, 04:29:26 by tsvstar »

Re: What is general method to add any gui element that user can interact with?
« Reply #6 on: 26 / December / 2011, 06:37:59 »
@tsvstar
Well, I already have working solution as I wrote above, but your code seems to be a little bit simpler.
I guess this still require to add code to gui.c and gui.h? Or gui_handler GUI_MODE_APPLET = ... does the same and no modification of gui.c and gui.h is needed?

At the moment I like to stay with TobiMarg's code to have some base to work with (especially because it works now and I will have not very much time soon to perform many experiments...).

Also thank you for your code, I'm sure that I'll use some parts of it;)
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

Re: What is general method to add any gui element that user can interact with?
« Reply #7 on: 26 / December / 2011, 06:53:05 »
Yes, that's correct. This is exactly same, no modification gui.[ch] required

Begining from trunk 1.1.x gui_handlers of most modes are separated from common list. Common list should include only system modes (like _NONE, _ALT), common modules which are widely used in the system (like _MBOX) and modes which require very specific handling (like fileselector, palette).

Moreover, if this will be separate into loadable flat module - it have to be done in this way


Re: What is general method to add any gui element that user can interact with?
« Reply #8 on: 26 / December / 2011, 07:26:45 »
Independence of your code looks like an important advantage and brings me now to use your code rather. Uh... and another time I have to rewrite my source...

Thank you very much for your patient and explanations!
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

 

Related Topics