* removed taglib doc build, main readme shown by default on start * made better diagrams for UI shown in doxygen * removed old docs for bluetooth
5.6 KiB
Graphic User Interface
This article includes details on how MuditaOS widgets are rendered and how the GUI handles key pressing.
Introduction
How widgets are rendered
- All widgets are children of
gui::Item - There are two major commands to trigger screen redraw:
gui::Item::buildDrawListin eachgui::Item- usesgui::Items tree to builds draw commandsapp::Application::refreshWindowinapp::Application- triggers update on display on message:gui::AppRefreshMessage(final draw on screen done with:app::Application::render)
- All interface actions can be made with either:
gui::Itemcallbacks, which are in [callbacks](@ref callbacks "Item callbacks"), orgui::Itemvirtual functions, [callback functions](@ref callbackCallers) When overriding please mind that you might want to use ancestor function inside too to i.e. not loose key presses etc.
- All
gui::Itemare able to handle keyPresses viagui::InputEvent - All
gui::Itemare able to traverse down on theirgui::Item::childrenand know which child hasgui::Item::focusItemat the time
How does it work on the application side
Please see app::Application, sapm::ApplicationManager for detailed information on how messages are handled between both. This is just general documentation.
These actions are done on a chained bus request between: app::Application, sapm::ApplicationManager and sapm::EventWorker
All of these are asynchronous and there is little state machine maintenance.
app::Applicationhas it's own state which is managed both in application and in manager (via setters and getters)sapm::ApplicationManagerhas it's own state which tells what exactly it's processing right now
Note: All app::Application:
- Register and initialize their windows on start of the application in
app::Application::createUserInterface - Need to pass
app::Application::DataReceivedHandlerfirst to parent function call to properly handle bus messages - Have windows based on
gui::AppWindow
Note: When it comes to gui::AppWindow:
gui::AppWindow::buildInterfacehas to call parent build interface first. Otherwise elements for child won't be created and it will crashgui::AppWindow::onInputhas to call parentonInput, otherwise handling key presses will fail- Applications react on key releases actions, in most scenarios key press event is useless
- all applications, if it hasn't been overriden in
gui::AppWindowwill try to return to previous window or application onback
gui::Item Key Press handling
What happens when you press a key?
bsphandles key press on I2C IRQ and sends Event to event worker on naked FreeRTOS pipe (on target RT1051, on Linuxgtkdoes that)EventWorkerworker ofEventService:- handles the press and sends it to current Application
- with focus (Note: when no application is in focus this will not work)
- application can either:
- process
gui::InputEventwithRawKeyorgui::KeyInputSimpleTranslation - use callbacks (see how to handle key press below)
- use widgets which override default key handling (see
gui::Item::onInput) - have own
gui::KeyInputMappedTranslation+gui::InputModeand process key press however they want
- process
How to handle key press
There are at least 3 ways to handle key press, listed in order of execution:
gui::Item::onInput- if not redefined callsinputCallback; if handled here, other calls wont be calledgui::Item::inputCallback- handles any keygui::Item::activatedCallback- handles Enter key onlygui::Item::itemNavigation- handles up,down,left,right if next/previous elements are added for an item
Note: return True when any of callbacks ends processing the whole Items tree
There are 2 set of parameters for key press:
gui::InputEvent::State- state of key (pressed, released, long released). In general applications handle key releases not pressesgui::KeyCode- initially parsed key codegui::RawKey- raw key code, to be processed in widget based on event i.e. translate pressing key13 times into C ingui::TextmodeABC
How to add key mapping when basic key maps are not enough?
- Key maps are specific key translation mappings. i.e. press
13 times to get C, press14 times to get A, etc. - basic key maps are stored in:
InputMode, right now there are followingInputMode::Modes: [ABC,abc,digit,phone] - key maps in
gui::InputModeare changed in regards of language settings
How to add a new key map, i.e. phone
- Add new file for your key map:
cp image/assets/profiles/template.kprof image/assets/profiles/phone.kprof - Change your template accordingly
- Pin new key map = add it to language support, add:
"common_kbd_phone": "phone"to at leastimage/assets/lang/lang_en.jsonif it will differ per language, prepare onekproffile per language - Add new key map to
gui::InputMode- Add
InputMode::Modeenum i.e.InputMode::Mode::phone - Add new Mode to input mode mapping in
InputMode.cpp(same as with other enums) - Test new added mode in:
UITestWindow.cpp - Test new key map on phone
- Add
- Load key map to phone
Now you can use InputMode::Mode::phone translation in gui::Text widget.
This means gui::Text will automatically change text on key press for you, same as in modes InputMode::Mode::phone etc.