Keypad Button Press App

The example app described here, aims for users who want to integrate the WiPhone's keypad in their custom apps. It will help enable Users to develop different sort of applications which utilize WiPhone keypad and having full control over the keypad by recognizing a specific button press event in code.

After completing this Example, user will learn how to:
  • Handle button press events within WiPhone firmware
  • Get the name/ ID of button that is pressed
  • Write the name of a button on label widget

How it works in WiPhone Interface

This example can be found in WiPhone interface like; Tools -> Development -> Software Examples -> Button Press Example. Once you select that app, the main activity page will open and display "Button Press App" in header section and "Back" in bottom right corner of footer seciton. When you press any specific button on WiPhone keypad, a text "{Button} is pressed" will get display in center of the App activity screen, where {Button} corresponds to the specific key pressed . WiPhone's screenshot for this App activity is given below.

ButtonPress App image1

Implementation in Firmware

Identify Major Files & Functions

  1. GUI.h
  2. GUI.cpp
  3. typedef enum ActionID : uint16_t {}
  4. GUIMenuItem menu[xx] PROGMEM = {}
  5. void GUI::enterApp (ActionID_t app)
  6. processEvent (EventType event)
  7. showButtonPress(String showString)
  8. redrawScreen (bool redrawAll)

Declaring a unique name for your app in GUI.h file

Search for "typedef enum ActionID" method in GUI.h and put your app name "GUI_APP_ButtonPressApp" as Action ID at designated place`.

Adding App ID into Menu

Search for GUIMenuItem menu[xx] PROGMEM in Gui.h and add an array line with following arguments in GUI Menu Item Method.

  1. Index for ButtonPressApp -> 41
  2. Index of Main Menu -> 39
  3. Menu Name -> Button Press Example
  4. argument empty -> ""
  5. argument empty -> ""
  6. Enumeration ID -> GUI_APP_ButtonPressApp

{ 41, 39, "Button Press Example", "", "", GUI_APP_ButtonPressApp }

Adding App Class into Header File

Insert following class code into GUI.h file.

GUI.h

class ButtonPressApp : public WindowedApp {
 public:
  ButtonPressApp( LCD& disp, ControlState& state, HeaderWidget* header, FooterWidget* footer);
  virtual ~ButtonPressApp();
  ActionID_t getId() { return GUI_APP_ButtonPressApp; };
  appEventResult processEvent(EventType event);
  void redrawScreen(bool redrawAll = false);
  void showButtonPress(String showString);
 protected:
  bool anyKeyPressed;
  bool screenInited = false;
  LabelWidget* label;
};

Instantiating the App

Before defining the App classes, search for GUI::enterApp(ActionID_t app) in GUI.cpp file and append below line in switch statement to instantiate the App object.

case GUI_APP_ButtonPressApp:
   // NOTE : THIS IS AN EXAMPLE BUTTON APP
   runningApp = new ButtonPressApp(*screen, state, header, footer);
   break;

The designated place to add above line within the switch statement in code can be found at enterApp Method in GUI.cpp.

Define App Constructor

A constructor method that we already instantiated in step above, needs to be defined first in GUI.CPP. After that, other related functions to follow in order to fully implement our example App. Let’s add constructor function for class ButtonPressApp.

GUI.cpp

ButtonPressApp::ButtonPressApp( LCD& lcd, ControlState& state, HeaderWidget* header, FooterWidget* footer)
  : WindowedApp(lcd, state, header, footer) {
  header->setTitle("Button Press APP");

  footer->setButtons(NULL, "Back");

  label = new LabelWidget(0, (lcd.height()-fonts[AKROBAT_EXTRABOLD_22]->height())/2, lcd.width(), fonts[AKROBAT_EXTRABOLD_22]->height(),
                          "Button Press App", WHITE, BLACK, fonts[AKROBAT_EXTRABOLD_22], LabelWidget::CENTER);
}

Declare and Define other Methods

This segments will show us a way of adding source code of other functions/ methods used in Button Press Example. We declare and define these methods within the firmware code to fully implement our example App and subsequently put in place in GUI.cpp file. These functions are defined outside the ButtonPressApp class and thus presented here with scope resolution operator (::) as below:

  1. ButtonPressApp::~ButtonPressApp()
  2. ButtonPressApp::showButtonPress(String showString)
  3. ButtonPressApp::processEvent(EventType event);
  4. ButtonPressApp::redrawScreen(bool redrawAll);

ButtonPressApp::~ButtonPressApp(); This function defines ButtonPressApp's destructor to release memory after usage. All widgets must be registered and deleted by WiPhoneApp destructor.

ButtonPressApp::~ButtonPressApp() {
delete label;
}

ButtonPressApp::showButtonPress(String showString); This function is responsible for displaying a pressed key event in WiPhone. Format of display label on screen used for this app is "{key pressed} is Pressed". This function takes a pressed key as argument and gets call withiin the processEvent method. To release the occupied memory used in this method, "delete label;" is used to delete the latest created "label".

void ButtonPressApp::showButtonPress(String showString) {
log_d("");
String to_show = showString + " Is Pressed.";
delete label;
label = new LabelWidget(0, (lcd.height()-fonts[AKROBAT_EXTRABOLD_22]->height())/2, lcd.width(), fonts[AKROBAT_EXTRABOLD_22]->height(),
                     to_show.c_str(), WHITE, BLACK, fonts[AKROBAT_EXTRABOLD_22], LabelWidget::CENTER);
this->screenInited = false;
}

ButtonPressApp::processEvent(EventType event); This function defines the app events that are detected when a button is pressed on WiPhone Keypad. Whenever user presses any key, the callback event invokes. User is required to handle any key press-related functions here.

     appEventResult ButtonPressApp::processEvent(EventType event) {
      if (LOGIC_BUTTON_BACK(event) ) {
    return EXIT_APP;
     }
     appEventResult res = DO_NOTHING;
     if (IS_KEYBOARD(event)) {
    anyKeyPressed = true;
    int i;
    switch (event) {
      case WIPHONE_KEY_UP:
        showButtonPress("UP");
        break;
      case WIPHONE_KEY_SELECT:
        showButtonPress("SELECT");
        break;
      case WIPHONE_KEY_LEFT:
        showButtonPress("LEFT");
        break;
      case WIPHONE_KEY_OK:
        showButtonPress("OK");
        break;
      case WIPHONE_KEY_RIGHT:
        showButtonPress("RIGHT");
        break;
      case WIPHONE_KEY_BACK:
        showButtonPress("BACK");
        break;
      case WIPHONE_KEY_CALL:
        showButtonPress("CALL");
        break;
      case WIPHONE_KEY_DOWN:
        showButtonPress("DOWN");
        break;
      case WIPHONE_KEY_END:
        showButtonPress("END");
        break;
      case '1':
        showButtonPress("1");
        break;
      case '2':
        showButtonPress("2");
        break;
      case '3':
        showButtonPress("3");
        break;
      case '4':
        showButtonPress("4");
        break;
      case '5':
        showButtonPress("5");
        break;
      case '6':
        showButtonPress("6");
        break;
      case '7':
        showButtonPress("7");
        break;
      case '8':
        showButtonPress("8");
        break;
      case '9':
        showButtonPress("9");
        break;
      case '*':
        showButtonPress("*");
        break;
      case '0':
        showButtonPress("0");
        break;
      case '#':
        showButtonPress("#");
        break;
      case WIPHONE_KEY_F1:
        showButtonPress("F1");
        break;
      case WIPHONE_KEY_F2:
        showButtonPress("F2");
        break;
      case WIPHONE_KEY_F3:
        showButtonPress("F3");
        break;
      case WIPHONE_KEY_F4:
        showButtonPress("F4");
        break;
      default:
        break;
    }
    res |= REDRAW_SCREEN;
  }
  return res;
}

ButtonPressApp::redrawScreen(bool redrawAll);

This method is used whenever user wants to update/ clear GUI for this app. Calling this method will redraw the empty main activity screen of App without any key pressed lable.

void ButtonPressApp::redrawScreen(bool redrawAll) {
  if (!this->screenInited) {
    redrawAll = true;
  }

  if (redrawAll) {
    lcd.fillRect(0, header->height(), lcd.width(), lcd.height() - header->height() - footer->height(), TFT_BLACK);
  }
  ((GUIWidget *) label)->redraw(lcd);
  screenInited = true;
}