/*---------------------------------------------------------------------------* * Routine: DrawMode *---------------------------------------------------------------------------* * Description: * Put the processor in the draw mode 'application' or 'demo'. * Buttons are shown to load, save, exit, and change the current color. * The user can then draw in the designated area a small picture using * the current color. * Inputs: * const T_choice *aChoice -- Choice object selected for this action. *---------------------------------------------------------------------------*/ void DrawMode(const T_choice *aChoice) { T_uezDevice lcd; T_uezDevice ts; static T_uezQueue queue = (TUInt32)NULL; INT_32 winX, winY; T_pixelColor *pixels; T_uezInputEvent inputEvent; TBool isDrawing = EFalse; INT_32 lastWinX, lastWinY; G_drExit = EFalse; #ifdef NO_DYNAMIC_MEMORY_ALLOC if (NULL == queue) { if (UEZQueueCreate(1, sizeof(T_uezInputEvent), &queue) != UEZ_ERROR_NONE) { queue = NULL; } } if (NULL != queue) { /* Register the queue so that the IAR Stateviewer Plugin knows about it. */ UEZQueueAddToRegistry( queue, "Draw TS" ); #else if (UEZQueueCreate(1, sizeof(T_uezInputEvent), &queue) == UEZ_ERROR_NONE) { #endif // Open up the touchscreen and pass in the queue to receive events if (UEZTSOpen("Touchscreen", &ts, &queue)==UEZ_ERROR_NONE) { // Open the LCD and get the pixel buffer if (UEZLCDOpen("LCD", &lcd) == UEZ_ERROR_NONE) { UEZLCDGetFrame(lcd, 0, (void **)&pixels); // Put the draw screen up DR_Screen(lcd); DR_DrawColor(); while (!G_drExit) { // Wait forever until we receive a touchscreen event // NOTE: UEZTSGetReading() can also be used, but it doesn't wait. if (UEZQueueReceive(queue, &inputEvent, UEZ_TIMEOUT_INFINITE)==UEZ_ERROR_NONE) { winX = inputEvent.iEvent.iXY.iX; winY = inputEvent.iEvent.iXY.iY; swim_get_virtual_xy(&G_drWin, &winX, &winY); // Are we in the drawing area? if ((winX > DR_IMAGE_LEFT) && (winX < DR_IMAGE_RIGHT) && (winY > DR_IMAGE_TOP) && (winY < DR_IMAGE_BOTTOM)) { // Pen down or up? if (inputEvent.iEvent.iXY.iAction == XY_ACTION_PRESS_AND_HOLD) { UEZLCDScreensaverWake(); if (G_drColor == BLACK) { // Draw a 3x3 block in the area swim_set_pen_color(&G_drWin, G_drColor); if (isDrawing) { DrawBlockLine(lastWinX, lastWinY, winX, winY); } else { DrawBlockPixel(winX, winY); } } else { // Draw a dot swim_set_pen_color(&G_drWin, G_drColor); if (isDrawing) { swim_put_line(&G_drWin, lastWinX, lastWinY, winX, winY); } else { swim_put_pixel(&G_drWin, winX, winY); } } isDrawing = ETrue; lastWinX = winX; lastWinY = winY; } else { // No longer drawing isDrawing = EFalse; } } else { ChoicesUpdateByReading(&G_drWin, G_drChoices, &inputEvent); if (inputEvent.iEvent.iXY.iAction == XY_ACTION_RELEASE) isDrawing = EFalse; } } } UEZLCDClose(lcd); } UEZTSClose(ts, queue); } #ifndef NO_DYNAMIC_MEMORY_ALLOC UEZQueueDelete(queue); #endif } }
/*---------------------------------------------------------------------------* * Routine: ChoicesUpdateContinuously *---------------------------------------------------------------------------* * Description: * Wait for a touchscreen event or timeout. Check the event and change * the state of the choices. Choices are chosen continuously as they * are pressed reporting events every call. * Inputs: * SWIM_WINDOW_T *aWin -- Window to draw within * const T_choice *aChoices -- Choices to use * T_uezQueue aTouchQueue -- Touchscreen queue * TUInt32 aTimeout -- Time to wait for touchscreen event * Outputs: * const T_choice * -- Last choice selected or 0 for none. *---------------------------------------------------------------------------*/ const T_choice *ChoicesUpdateContinuously( SWIM_WINDOW_T *aWin, const T_choice *aChoices, T_uezQueue aInputEventQueue, TUInt32 aTimeout) { T_uezInputEvent inputEvent; INT_32 winX, winY; static const T_choice *p_lastChoice = 0; const T_choice *p_choice = 0; const T_choice *p_choiceCalled = 0; if (UEZQueueReceive(aInputEventQueue, &inputEvent, aTimeout) == UEZ_ERROR_NONE) { winX = inputEvent.iEvent.iXY.iX; winY = inputEvent.iEvent.iXY.iY; swim_get_virtual_xy(aWin, &winX, &winY); // Is this a touching event? if (inputEvent.iEvent.iXY.iAction == XY_ACTION_PRESS_AND_HOLD) { // We are touching the screen. // Is this a different position than before? // Determine which choice we are in p_choice = IFindChoice(aChoices, winX, winY); if (p_choice != p_lastChoice) { if (p_lastChoice) { // Un-invert the last choice (draw black square) swim_set_fill_color(aWin, G_settings.iUnselectColor); swim_set_pen_color(aWin, G_settings.iUnselectColor); swim_set_fill_transparent(aWin, 1); swim_put_box(aWin, p_lastChoice->iLeft, p_lastChoice->iTop, p_lastChoice->iRight, p_lastChoice->iBottom); swim_set_fill_transparent(aWin, 0); } if (p_choice) { // Invert the new choice swim_set_pen_color(aWin, G_settings.iSelectColor); swim_set_fill_transparent(aWin, 1); swim_put_box(aWin, p_choice->iLeft, p_choice->iTop, p_choice->iRight, p_choice->iBottom); swim_set_fill_transparent(aWin, 0); } p_lastChoice = p_choice; p_choice = 0; } // Act like we just released the same spot // Determine which choice we are in p_choice = p_lastChoice; if (p_choice) { // Same as when we pressed // Do the action if (p_choice->iAction) { const T_choice *p_prevChoice = p_lastChoice; p_lastChoice = 0; // ButtonClick(); p_choiceCalled = p_choice; p_choice->iAction(p_choice); // Un-invert the last choice swim_set_fill_transparent(aWin, 1); swim_set_pen_color(aWin, G_settings.iUnselectColor); swim_put_box(aWin, p_prevChoice->iLeft, p_prevChoice->iTop, p_prevChoice->iRight, p_prevChoice->iBottom); swim_set_fill_transparent(aWin, 0); p_lastChoice = 0; } } } else { // The screen is no longer being touched. // Nothing being touched p_lastChoice = 0; return 0; } } else { return 0; } return p_choiceCalled; }
void BrightnessControlMode(const T_choice *aChoice) { T_uezDevice ts; static T_uezQueue queue = NULL; static T_brightnessControlWorkspace *G_ws = NULL; INT_32 winX, winY; T_uezInputEvent inputEvent; #if ENABLE_UEZ_BUTTON T_uezDevice keypadDevice; #endif #if UEZ_ENABLE_LIGHT_SENSOR TUInt32 levelCurrent = 1, levelPrevious = 0; T_uezDevice ls; DEVICE_LightSensor **p; T_uezError error; char levelText[30]; TBool lightSensorActive = EFalse; if( UEZDeviceTableFind("Light Sensor", &ls) == UEZ_ERROR_NONE) { if(UEZDeviceTableGetWorkspace(ls, (T_uezDeviceWorkspace **)&p) == UEZ_ERROR_NONE) { if((*p)->Open((void *)p, "I2C1") == UEZ_ERROR_NONE) { lightSensorActive = ETrue; } } } #endif #ifdef NO_DYNAMIC_MEMORY_ALLOC if (NULL == G_ws) { G_ws = UEZMemAlloc(sizeof(*G_ws)); } #else G_ws = UEZMemAlloc(sizeof(*G_ws)); #endif #if UEZ_ENABLE_LIGHT_SENSOR UEZTaskSuspend(G_lightSensorTask); #endif if (!G_ws) return; memset(G_ws, 0, sizeof(*G_ws)); G_ws->iExit = EFalse; G_ws->iNeedUpdate = ETrue; #ifdef NO_DYNAMIC_MEMORY_ALLOC if (NULL == queue) { if (UEZQueueCreate(1, sizeof(T_uezInputEvent), &queue) != UEZ_ERROR_NONE) { queue = NULL; } } if (NULL != queue) { /* Register the queue so that the IAR Stateviewer Plugin knows about it. */ UEZQueueAddToRegistry( queue, "Brightness TS" ); #else if (UEZQueueCreate(1, sizeof(T_uezInputEvent), &queue) == UEZ_ERROR_NONE) { #if UEZ_REGISTER UEZQueueSetName(queue, "Brightness", "\0"); #endif #endif #if ENABLE_UEZ_BUTTON UEZKeypadOpen("BBKeypad", &keypadDevice, &queue); #endif // Open up the touchscreen and pass in the queue to receive events if (UEZTSOpen("Touchscreen", &ts, &queue)==UEZ_ERROR_NONE) { // Open the LCD and get the pixel buffer if (UEZLCDOpen("LCD", &G_ws->iLCD) == UEZ_ERROR_NONE) { UEZLCDGetBacklightLevel(G_ws->iLCD, &G_ws->iLevel, &G_ws->iNumLevels); // Put the screen up BCMScreen(G_ws); // Sit here in a loop until we are done while (!G_ws->iExit) { // Do choices and updates if (UEZQueueReceive(queue, &inputEvent, 500)==UEZ_ERROR_NONE) { winX = inputEvent.iEvent.iXY.iX; winY = inputEvent.iEvent.iXY.iY; swim_get_virtual_xy(&G_win, &winX, &winY); if (inputEvent.iEvent.iXY.iAction == XY_ACTION_PRESS_AND_HOLD) { // Are we in the panel? if ((winY >= G_ws->iRSlidePanel.iTop) && (winY <= G_ws->iRSlidePanel.iBottom) && (winX >= G_ws->iRSlidePanel.iLeft) && (winX <= G_ws->iRSlidePanel.iRight)) { // Inside the panel and touching the screen, let's map this to an intensity // of 0-255 if(winY > G_ws->iRGroove.iBottom) G_ws->iLevel = 0; else { G_ws->iLevel = (G_ws->iRGroove.iBottom - winY)*(G_ws->iNumLevels)/ (1+G_ws->iRGroove.iBottom-G_ws->iRGroove.iTop); } UEZLCDSetBacklightLevel(G_ws->iLCD, G_ws->iLevel); G_ws->iNeedUpdate = ETrue; } } ChoicesUpdateByReading(&G_win, G_ws->iChoices, &inputEvent); #if UEZ_ENABLE_LIGHT_SENSOR if (lightSensorActive) { levelCurrent = (*p)->GetLevel((void *)p); if(levelCurrent == 0xFFFFFFFF) { //ligh sensor no longer resonding lightSensorActive = EFalse; break; } if( levelCurrent != levelPrevious) { swim_set_font(&G_win, &APP_DEMO_DEFAULT_FONT); swim_set_fill_color(&G_win, BLACK); swim_set_pen_color(&G_win, BLACK); sprintf(levelText, "Ambient Light Level: %04d lux\0", levelCurrent); //erase old text swim_put_box(&G_win, (UEZ_LCD_DISPLAY_WIDTH/2) - (swim_get_text_line_width(&G_win, levelText) /2),//x1 BCM_SLIDE_PANEL_OUTER_PADDING,//y1 (UEZ_LCD_DISPLAY_WIDTH/2) + (swim_get_text_line_width(&G_win, levelText) /2),//x2 BCM_SLIDE_PANEL_OUTER_PADDING + swim_get_font_height(&G_win));//y2 //put new text swim_set_pen_color(&G_win, YELLOW); swim_put_text_xy(&G_win, levelText, (UEZ_LCD_DISPLAY_WIDTH/2) - (swim_get_text_line_width(&G_win, levelText) /2),//x (BCM_SLIDE_PANEL_OUTER_PADDING));//y levelPrevious = levelCurrent; } } #endif } if (G_ws->iNeedUpdate) { BCMUpdate(G_ws); G_ws->iNeedUpdate = EFalse; } } UEZLCDClose(G_ws->iLCD); } UEZTSClose(ts, queue); } #if ENABLE_UEZ_BUTTON UEZKeypadClose(keypadDevice, &queue); #endif #ifndef NO_DYNAMIC_MEMORY_ALLOC UEZQueueDelete(queue); #endif #if UEZ_ENABLE_LIGHT_SENSOR (*p)->Close((void *)p); UEZTaskResume(G_lightSensorTask); #endif } /* <<< WHIS >>> Potential memory leak in FreeRTOS version as G_ws is not free'd. */ }
/*---------------------------------------------------------------------------* * Routine: ChoicesUpdateByReading *---------------------------------------------------------------------------* * Description: * An input event has been received. Check the event and change * the state of the choices. * Inputs: * SWIM_WINDOW_T *aWin -- Window to draw within * const T_choice *aChoices -- Choices to use * T_uezQueue aTouchQueue -- Touchscreen queue * TUInt32 aTimeout -- Time to wait for touchscreen event * Outputs: * const T_choice * -- Last choice selected or 0 for none. *---------------------------------------------------------------------------*/ const T_choice *ChoicesUpdateByReading( SWIM_WINDOW_T *aWin, const T_choice *aChoices, T_uezInputEvent *p_inputEvent) { INT_32 winX, winY; static TUInt16 lastX = 0, lastY = 0; static const T_choice *p_lastChoice = 0; static const T_choice *p_buttonChoice = 0; static const T_choice *p_nextButtonChoice = 0; const T_choice *p_choice = 0; const T_choice *p_choiceCalled = 0; winX = p_inputEvent->iEvent.iXY.iX; winY = p_inputEvent->iEvent.iXY.iY; swim_get_virtual_xy(aWin, &winX, &winY); // Is this a touching event? if(p_inputEvent->iType == INPUT_EVENT_TYPE_XY) { // Is this a press or hold event? if (p_inputEvent->iEvent.iXY.iAction == XY_ACTION_PRESS_AND_HOLD) { // We are touching the screen. // Is this a different position than before? if ((p_inputEvent->iEvent.iXY.iX != lastX) || (p_inputEvent->iEvent.iXY.iY != lastY)) { // Determine which choice we are in p_choice = IFindChoice(aChoices, winX, winY); if (p_choice != p_lastChoice) { #if HAPTIC_FEEDBACK hapticFeedback(DEFAULT_HAPTIC_TIME_MS); #endif if (p_lastChoice) { // Un-invert the last choice swim_set_fill_color(aWin, G_settings.iUnselectColor); swim_set_pen_color(aWin, G_settings.iUnselectColor); swim_set_fill_transparent(aWin, 1); swim_put_box(aWin, p_lastChoice->iLeft, p_lastChoice->iTop, p_lastChoice->iRight, p_lastChoice->iBottom); swim_set_fill_transparent(aWin, 0); } // Turn off button repeating when we leave focus G_repeatOn = EFalse; if (p_choice) { // Invert the new choice swim_set_pen_color(aWin, G_settings.iSelectColor); swim_set_fill_transparent(aWin, 1); swim_put_box(aWin, p_choice->iLeft, p_choice->iTop, p_choice->iRight, p_choice->iBottom); swim_set_fill_transparent(aWin, 0); // If the option we are over is repeating, // turn on repeating. if (p_choice->iFlags & SUI_FLAG_REPEAT) G_repeatOn = ETrue; } p_lastChoice = p_choice; p_choice = 0; } } // Are we allowed to repeat? if (G_repeatOn) { if (!G_repeating) { G_repeating = ETrue; G_repeatLastTouch = UEZTickCounterGet(); G_repeatTime = REPEAT_TIME_1; // first repeat is slow } else { // Time to repeat? if (UEZTickCounterGetDelta(G_repeatLastTouch) >= G_repeatTime) { if (G_repeatTime == REPEAT_TIME_1) G_repeatTime = REPEAT_TIME_2; else if (G_repeatTime == REPEAT_TIME_2) G_repeatTime = REPEAT_TIME_3; G_repeatLastTouch = UEZTickCounterGet(); // Cause a repeat by signalling a non-touch event below //p_reading->iFlags &= ~TSFLAG_PEN_DOWN; } } } } else { // Really not touching? // Are we repeating? if (G_repeating) { // Stop that. G_repeating = EFalse; } } // Release event (real for faked above?) if (p_inputEvent->iEvent.iXY.iAction == XY_ACTION_RELEASE) { // The screen is no longer being touched. // Determine which choice we are in p_choice = p_lastChoice; if (p_choice) { // Same as when we pressed // Do the action if (p_choice->iAction) { const T_choice *p_prevChoice = p_lastChoice; p_lastChoice = 0; p_choiceCalled = p_choice; // Un-invert the last choice swim_set_fill_transparent(aWin, 1); swim_set_pen_color(aWin, G_settings.iUnselectColor); swim_put_box(aWin, p_prevChoice->iLeft, p_prevChoice->iTop, p_prevChoice->iRight, p_prevChoice->iBottom); swim_set_fill_transparent(aWin, 0); p_choice->iAction(p_choice); p_lastChoice = 0; } } } } else { // This is a button event if(p_inputEvent->iEvent.iButton.iAction == BUTTON_ACTION_PRESS) { if(p_buttonChoice == 0){ p_buttonChoice = IFindChoiceTopLeft(aChoices); } else { // Un-invert the last choice swim_set_fill_color(aWin, G_settings.iUnselectColor); swim_set_pen_color(aWin, G_settings.iUnselectColor); swim_set_fill_transparent(aWin, 1); swim_put_box(aWin, p_buttonChoice->iLeft, p_buttonChoice->iTop, p_buttonChoice->iRight, p_buttonChoice->iBottom); swim_set_fill_transparent(aWin, 0); if(p_inputEvent->iEvent.iButton.iKey == KEY_ARROW_RIGHT) { p_nextButtonChoice = IFindChoiceRight(aChoices, p_buttonChoice, 2); if(p_nextButtonChoice == p_buttonChoice) p_buttonChoice = IFindChoiceRight(aChoices, p_buttonChoice, 1); else p_buttonChoice = p_nextButtonChoice; } else if(p_inputEvent->iEvent.iButton.iKey == KEY_ARROW_LEFT) { p_nextButtonChoice = IFindChoiceLeft(aChoices, p_buttonChoice, 2); if(p_nextButtonChoice == p_buttonChoice) p_buttonChoice = IFindChoiceLeft(aChoices, p_buttonChoice, 1); else p_buttonChoice = p_nextButtonChoice; } else if(p_inputEvent->iEvent.iButton.iKey == KEY_ARROW_UP) { p_nextButtonChoice = IFindChoiceUp(aChoices, p_buttonChoice, 2); if(p_nextButtonChoice == p_buttonChoice) p_buttonChoice = IFindChoiceUp(aChoices, p_buttonChoice, 1); else p_buttonChoice = p_nextButtonChoice; } else if(p_inputEvent->iEvent.iButton.iKey == KEY_ARROW_DOWN) { p_nextButtonChoice = IFindChoiceDown(aChoices, p_buttonChoice, 2); if(p_nextButtonChoice == p_buttonChoice) p_buttonChoice = IFindChoiceDown(aChoices, p_buttonChoice, 1); else p_buttonChoice = p_nextButtonChoice; } else if(p_inputEvent->iEvent.iButton.iKey == KEY_ENTER) { p_choice = p_buttonChoice; p_buttonChoice = 0; p_choiceCalled = p_choice; p_choice->iAction(p_choice); } } // Invert the new choice swim_set_pen_color(aWin, G_settings.iSelectColor); swim_set_fill_transparent(aWin, 1); swim_put_box(aWin, p_buttonChoice->iLeft, p_buttonChoice->iTop, p_buttonChoice->iRight, p_buttonChoice->iBottom); swim_set_fill_transparent(aWin, 0); } else /* BUTTON_ACTION_RELEASE */{ } } return p_choiceCalled; }