Files
MuditaOS/module-gui
pholat 23df384c55 EGD-3087 SMS Search implemented (#374)
* EGD-3087 WIP adding SMS Querry

* EGD-3087 Added query virtual interface on Service top layer

Service shouldn't implement query logic and should be proxying that.

additionally:
- small fixes in includes
- shared service db name same way as apps and event manager

* EGD-3087 Query - want to work on interface not on db

* EGD-3087 Query gluecode works fine. Our query in SMS search calls getBySMSQuery

Changes cut off before any potential orm interface layer

* EGD-3087 WIP Interface in use

* EGD-3087 Query for SMS search works as designed

* EGD-3087 Query results should be on screen

* EGD-3087 BUG workaround - need to deep refresh display to show data

* EGD-3087 Searching for text from input works fine

* EGD-3087 Showing results / or empty results depending on query

* EGD-3087 Pre PR fixups

* EGD-3087 Empty search - getting back to prewious window ignore current

* EGD-3087 PR applied

* EGD-3087 PR - style fixed

* EGD-3087 Review - DB ListView handling moved to separate function

* EGD-3087 Workaround: crash on use after free fix

* EGD-3087 PR stylistic changes

* EGD-3087 PR cleanup applied

* EGD-3087 Added test for Query interface

* EGD-3087 renamed getByQuery to getQuery & finished tests

* EGD-3087 Post rebase fixup

* EGD-3087 PR - moved ListView request part to separate function

* EGD-3087 PR Fixups

* EGD-3087 Post rebase style fix

* EGD-3087 Added variable for DB service stack & const to getter function
2020-05-27 13:49:50 +02:00
..
2019-07-01 10:26:52 +02:00
2019-07-01 10:26:52 +02:00
2019-05-21 23:35:00 +02:00

UI README

@tableofcontents

schematics parts used:

  • [name : part] - name of module : part of code responsible
  • => / <=> - direction of communication
  • <> event on diagrams, name placeholder of element in text

introduction

How widgets are rendered

Our UI is split into:

[bsp] <=> [renderer] <=> [application : widgets]
  • All widgets are children of gui::Item
  • There are two major commands to trigger screen redraw:
    • gui::Item::buildDrawList in each gui::Item - uses gui::Items tree to builds draw commands
    • app::Application::refreshWindow in app::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::Item callbacks, which are in [callbacks](@ref callbacks "Item callbacks")
    • gui::Item virtual functions, [callback functions](@ref callbackCallers) When overriding please mind that you might want to use ancestor function inside too. I.e. to not loose key presses etc.
  • All gui::Item are able to handle keyPresses via gui::InputEvent
  • All gui::Item are able to traverse down on their gui::Item::children and know which child have gui::Item::focusItem at the time

How does it work from application

Please see app::Application, sapm::ApplicationManager for detailed information on how messages are handled between both. This is jus overall documentation.

[ApplicationManager]                 [Application]
               <=>    START       <=>
               <=>   Set focus    <=>
               <=> Set keyboard   <=>
               <=> Put background <=>
               <=>      kill      <=>

These actions are done on chained bus request between: app::Application, sapm::ApplicationManager and sapm::EventWorker There all of these are asynchronous and there is little state machine maintenance.

  1. app::Application has it's own state which is managed both in application and in manager (via setters and getters)
  2. sapm::ApplicationManager has it's own state which tells what exactly it's processing right now

Important all app::Application

  1. register and initialize their windows on start of application in app::Application::createUserInterface
  2. need to pass app::Application::DataReceivedHandler first to parent function call to properly handle bus messages
  3. have windows based on gui::AppWindow

Important gui::AppWindow

  1. gui::AppWindow::buildInterface has to call parent build interface first. Otherwise elements for child won't be created and it will crash
  2. gui::AppWindow::onInput has to call parent onInput, otherwise handling key presses might and most probably will fail
  3. Applications react on key releases actions, in most scenarios key press event is useless.
  4. All applications, if it wasn't overriden in gui::AppWindow will try to return to previous window or application on back

gui::Item key press handling

What happens when you press the key?

[bsp] <basic freertos pipe> => [EventWorker : basic key translation] < key press event> => [Application with focus]
  • bsp handles key press on I2C IRQ and sends Event to event worker on naked freertos pipe (on target rt1051, on linux gtk does that)
  • EventWorker worker of EventService
    • handles the press sends it to current Application
    • with focus warning when no application with focus this will stuck
  • application can either:
    • process gui::InputEvent with RawKey or gui::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::InputMode and process key however they want

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 calls inputCallback, if handled here, other calls wont be called
  • gui::Item::inputCallback - handles any key
  • gui::Item::activatedCallback - handles enter only
  • gui::Item::itemNavigation - handles up,down,left,right if next/previous elements are added for item

return true in any of callbacks ends processing for whole Items tree

There are 2 set of parameters for key press:

  • gui::InputEvent::State - tate of key, pressed, released, long released. In generall applications handle releases not presses!
  • gui::KeyCode - initially parsed key code
  • gui::RawKey - raw key code, to be processed in widget based on event. ( i.e. Translate 3 times 1 press to C in gui::Text mode ABC)

How to add key mapping when basic key maps are not enough?

  • Key maps are specific key translation mappings. I.e. 3 times press 1 to get C, 4 times press 1 to get A etc.
  • basic key maps are stored in: InputMode, right now there are InputMode::Modes: [ABC, abc, digit, phone]
  • key maps in gui::InputMode are changed in regards of lang settings

To add new key map, i.e. phone

  1. Add new file for your key map: cp image/assets/profiles/template.kprof image/assets/profiles/phone.kprof
  2. change your template according to your desires
  3. Pin new key map = add it to language support, add: "common_kbd_phone": "phone" to at least image/assets/lang/lang_en.json if it will differ per language, prepare one kprof per language
  4. Add new key map to gui::InputMode
    1. add InputMode::Mode enum i.e. InputMode::Mode::phone
    2. add new Mode to input mode mapping in InputMode.cpp (same as with other enums)
    3. test new added mode in: UITestWindow.cpp
    4. test new key map on phone
  5. load key map to phone, as you probably forgot

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.