Pictures Demo App

The example app described here, aims for users who want to display full-screen pictures to the WiPhone screen. To see next image, either wait for a pre-defined timeout or press any button on keypad.

How it works in WiPhone Interface

This example can be found in WiPhone menu like; Tools -> Development -> Pictures demo. Once you select that app, the main activity page will open containing a full-screen image without any header or footer. User can proceed to next image by pressing any key (excluding Back, or End/Power buttons) on keypad or waits until next picture appears after pre-defined timer expires. Pressing Back or End/Power buttons on WiPhone will exit the app.

image1 image2 image3

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. redrawScreen (bool redrawAll)

Including Images Arrays in Header File

WiPhone firmware supports RLE3 and I256 format images display. Displaying pictures on WiPhone works like this; put the whole image bytes in a byte array within a header file with the path "src/assets/MyImage_jpg.h". WiPhone handles pictures through arrays of supported formats instead of loading images from storage devices. For example, the picture with name "MyImage_jpg" is defined in array as in the code snippet below. To learn how to covert an image into C array, check out the procedure mentioned at how to convert an Image to a C-array and placed in firmware code.

const unsigned char rle3_image[4817] PROGMEM = {
  0x52, 0x4c, 0x45, 0x33, 0x81, 0x70, 0x82, 0x40, 0x88, 0x00, 0x01, 0x00, 0x00, 0x2f, 0x13, 0x6d,
  0xff, 0x08, 0x00, 0x8f, 0xff, 0x00, 0x21, 0xfb, 0xff, 0xa1, 0x05, 0x50, 0xff, 0xff, 0x00, 0x00,
  ...
  0x41, 0x67, 0x41, 0x21, 0x0d, 0x49, 0x07, 0x49, 0x0c, 0x42, 0x69, 0x41, 0x21, 0x1f, 0xff, 0x14,
  0xb2,
};

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_PICS_DEMO" as Action ID at designated place`.

Adding App ID into Menu

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

  1. Index for Picrures Demo App -> 16
  2. Index of Parent Menu -> 28
  3. Menu Name -> Pictures demo
  4. argument empty -> ""
  5. argument empty -> ""
  6. Enumeration ID -> GUI_APP_PICS_DEMO

{ 16, 28, "Pictures demo", "", "", GUI_APP_PICS_DEMO }

Adding App Class into Header File

Insert following class code into GUI.h file.

GUI.h

class PicturesDemoApp : public WiPhoneApp {
public:
   PicturesDemoApp(LCD& disp, ControlState& state);
   virtual ~PicturesDemoApp();
   ActionID_t getId() {
     return GUI_APP_PICS_DEMO;
   };
   appEventResult processEvent(EventType event);
   void redrawScreen(bool redrawAll=false);
protected:
   uint8_t pic = 0;
};

Instantiating the App

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

case GUI_APP_PICS_DEMO:
  // NOTE : THIS IS AN EXAMPLE PICTURES DEMO APP
  runningApp = new PicturesDemoApp(*screen, state);
  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 PicturesDemoApp.

PicturesDemoApp::PicturesDemoApp( LCD& lcd, ControlState& state)
  : WindowedApp(lcd, state) {
   log_d("create PicturesDemoApp");
   pic = 1;
}

Declare and Define other Methods

This segments will show us a way of adding source code of other functions/ methods used in Pictures Demo 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 PicturesDemoApp class and thus presented here with scope resolution operator (::) as below:

  1. PicturesDemoApp::~PicturesDemoApp();
  2. PicturesDemoApp::processEvent(EventType event);
  3. PicturesDemoApp::redrawScreen(bool redrawAll);

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

    PicturesDemoApp::~PicturesDemoApp() {
  log_d("destroy PicturesDemoApp");
}

PicturesDemoApp::processEvent(EventType event); This function defines the app events that are detected when a button is pressed on WiPhone Keypad. In this method, it can be seen that pressing any key changes the picture number within the interval of one to three. Whenever user presses LOGIC_BUTTON_BACK, the app exits. User is required to handle any key press-related functions here.

 appEventResult PicturesDemoApp::processEvent(EventType event) {
    log_d("processEvent PicturesDemoApp");
if (LOGIC_BUTTON_BACK(event)) {
  return EXIT_APP;
}
pic++;
if (pic>3) {
  pic = 1;
}
return REDRAW_SCREEN;
 }

PicturesDemoApp::redrawScreen(bool redrawAll); This method is used whenever user wants to update/ clear GUI for this app. Calling this method will redraw the default main activity screen designed for the App.

void PicturesDemoApp::redrawScreen(bool redrawAll) {
  log_i("redraw PicturesDemoApp");
  int t = micros();
  if (pic==1) {
    lcd.drawImage(rle3_image, sizeof(rle3_image), 0, 0);
  } else if (pic==2) {
    lcd.drawImage(image_i256, sizeof(image_i256), 0, 0);
  } else if (pic>2) {
    lcd.drawImage(image_jpg, sizeof(image_jpg));
  } else {
    lcd.fillScreen(BLACK);
    lcd.setTextColor(RED, BLACK);
    lcd.setTextSize(2);
    lcd.drawString("Error", lcd.width()/2, lcd.height()/2, 2);
  }
  log_d("time: %lu", micros()-t);
}