/** * @brief Start play * @param filename: pointer to the video file name * @retval None */ static uint8_t _StartPlay(GUI_MOVIE_HANDLE *hmovie, char * filename, FIL * file, uint16_t x0, uint16_t y0) { static char tmp[FILEMGR_FILE_NAME_SIZE]; int ms, frames; uint32_t duration; WM_HWIN hItem; if(f_open(file, filename, FA_OPEN_EXISTING | FA_READ) == FR_OK) { PrevFrameIndex = 0; LostFrames = 0; previous_total = 0; GUI_MOVIE_GetInfoEx(_GetData, file, &Video_Info); *hmovie = GUI_MOVIE_CreateEx(_GetData, file, _cbNotify) ; GUI_MOVIE_SetPeriod (*hmovie, VIDEO_FRAME_TIME); if((Video_Info.xSize == 0) || (Video_Info.ySize == 0) || (Video_Info.xSize > 1024) || (Video_Info.ySize > 768)) { GUI_MOVIE_Delete(*hmovie); return 1; } GUI_MOVIE_Show(*hmovie, ((LCD_GetXSize() - Video_Info.xSize)/2), ((LCD_GetYSize() - Video_Info.ySize)/2), 0); hTimer = WM_CreateTimer(playbackwin, 0, 1000, 0); /* Update video total time */ hItem = WM_GetDialogItem(playbackwin, ID_TIME); ms = Video_Info.msPerFrame; frames = Video_Info.NumFrames; duration = (frames * ms)/1000; sprintf((char *)tmp , "%02lu:%02lu", duration/60, duration%60 ); TEXT_SetText(hItem, tmp); WM_InvalidateWindow(playbackwin); elapsed_time = 0; hItem = WM_GetDialogItem(playbackwin, ID_VIDEO_NAME); FILEMGR_GetFileOnly (tmp, filename); TEXT_SetText(hItem, tmp); hItem = WM_GetDialogItem(playbackwin, ID_ELAPSED_TIME); TEXT_SetText(hItem, "00:00"); WM_InvalidateWindow(hItem); WM_Paint(hItem); } return 0; }
/** * @brief callback for audio process * @param pMsg: pointer to data structure of type WM_MESSAGE * @retval None */ static void _cbAudioProcess(WM_MESSAGE * pMsg) { uint32_t Id; static WM_HTIMER hProcessTimer; WM_HWIN hItem; char tmp[] = "00:00/00:00"; uint32_t duration; switch (pMsg->MsgId) { case WM_CREATE: hProcessTimer = WM_CreateTimer(pMsg->hWin, ID_PROCESS_TIMER, 1000, 0); break; case WM_TIMER: Id = WM_GetTimerId(pMsg->Data.v); if(Id == ID_PROCESS_TIMER) { if(AUDIO_RECORDER_GetState() == AUDIO_RECORDER_RECORDING) { /*Set elapsed time */ duration = AUDIO_RECORDER_GetElapsedTime(); sprintf((char *)tmp , "%02lu:%02lu", duration/60, duration%60 ); hItem = WM_GetDialogItem(hMainWin, ID_ELAPSED_TIME); TEXT_SetText(hItem, tmp); } if(AUDIO_RECORDER_GetState() == AUDIO_RECORDER_PLAYING) { /*Set elapsed time */ duration = AUDIO_RECORDER_GetTotalTime() - AUDIO_RECORDER_GetPlayedTime(); sprintf((char *)tmp , "%02lu:%02lu", duration/60, duration%60); hItem = WM_GetDialogItem(hMainWin, ID_ELAPSED_TIME); TEXT_SetText(hItem, tmp); } WM_RestartTimer(pMsg->Data.v, 1000); } break; case WM_DELETE: WM_DeleteTimer(hProcessTimer); break; default: WM_DefaultProc(pMsg); } }
// //page // const void DisPage() { char PAGE[20] = ""; TEXT_SetFont(mainwinText[4],&GUI_Font30); if (Language == 0) { sprintf(PAGE,"所处 0%d页/共 0%d页",thispage,pageNum); TEXT_SetText(mainwinText[4],PAGE); } else { sprintf(PAGE,"PAGE 0%d/0%d",thispage,pageNum); TEXT_SetText(mainwinText[4],PAGE); } }
/** * @brief Refresh browser. * @param hWin: pointer to the parent handle * @retval None */ static void _RefreshBrowser ( WM_HWIN hWin) { WM_HWIN hItem, Hint; TREEVIEW_ITEM_Handle hTreeView; uint32_t free, total; char str[FILEMGR_FULL_PATH_SIZE]; GUI_Exec(); /* Show Hint */ Hint = WM_CreateWindowAsChild(30, 120, 180, 32, hWin, WM_CF_SHOW , _cbHint, 0); GUI_Exec(); hItem = WM_GetDialogItem(hWin, ID_PROGBAR_USB); if(k_StorageGetStatus (USB_DISK_UNIT)) { free = k_StorageGetFree(USB_DISK_UNIT); total = k_StorageGetCapacity(USB_DISK_UNIT); PROGBAR_SetValue (hItem, ((total - free) * 100)/total); hItem = WM_GetDialogItem(hWin, ID_TEXT_USB); sprintf(str, "USB Disk [%lu MB]", total / (2 * 1024)); TEXT_SetText(hItem, str); } else { PROGBAR_SetValue (hItem, 0); hItem = WM_GetDialogItem(hWin, ID_TEXT_USB); TEXT_SetText(hItem, "USB Disk [N/A]" ); } hTreeView = WM_GetDialogItem(hWin, ID_TREEVIEW); hItem = TREEVIEW_GetItem(hTreeView, 0, TREEVIEW_GET_FIRST); if(hItem != 0) { TREEVIEW_ITEM_Delete (hItem); } ExploreDisks(hTreeView); WM_DeleteWindow(Hint); }
static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; switch (pMsg->MsgId) { case WM_INIT_DIALOG: hItem = pMsg->hWin; FRAMEWIN_SetText(hItem, "welcome"); FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); FRAMEWIN_SetTitleVis(hItem, 0); // // Initialization of 'Text' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0); TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); TEXT_SetFont(hItem, GUI_FONT_20B_1); TEXT_SetTextColor(hItem, 0x000000FF); TEXT_SetText(hItem, "welcome to use our system"); // // Initialization of 'Text' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_1); TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); TEXT_SetFont(hItem, GUI_FONT_16B_1); TEXT_SetTextColor(hItem, 0x008000FF); TEXT_SetText(hItem, "The elderly assistant"); // // Initialization of 'Text' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_2); TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); TEXT_SetText(hItem, "Just a moment, please. "); // // Initialization of 'Text' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_3); TEXT_SetText(hItem, "second"); TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); // USER START (Optionally insert additional code for further widget initialization) // USER END break; // USER START (Optionally insert additional message handling) // USER END default: WM_DefaultProc(pMsg); break; } }
void update_motif(void) { motif_t * m = db->motifs; for (uint32_t i = 1; i < current_motif_index; i++) m = m->next; sprintf(current_motif_title, "%i/%i -- %s", (int)current_motif_index, (int)db->nb_motifs, m->name); current_motif_desc = m->desc; MULTIEDIT_SetText(motif_desc_widget, current_motif_desc); TEXT_SetText(motif_name_widget, current_motif_title); led_clear(); point_t * p = m->points; while (p != NULL) { led_set(p->x, p->y, p->z); p = p->next; } clear_points2blink(); option_t * o = m->options; while (o != NULL) { handle_option(o); o = o->next; } }
void Login_SetText(WM_HWIN hWin,const char *Value) { WM_HWIN hItem; hItem=WM_GetDialogItem(hWin, GUI_ID_TEXT1); TEXT_SetText(hItem, Value); GUI_Exec(); }
/** * @brief Notify State Change * @param pMsg: pointer to data structure of type WM_MESSAGE * @retval None */ void _cbNotifyStateChange (void) { WM_HWIN hItem; if(AUDIO_RECORDER_GetState() == AUDIO_RECORDER_SUSPENDED) { if(RecorderMode == RECORDER_MODE_PLAYING) { RecorderMode = RECORDER_MODE_PLAY_IDLE; hItem = WM_GetDialogItem(hMainWin, ID_RECORD_REC_CANCEL_PLAY); WM_InvalidateWindow(hItem); WM_Update(hItem); } if(RecorderMode == RECORDER_MODE_RECORDING) { RecorderMode = RECORDER_MODE_REC_IDLE; } hItem = WM_GetDialogItem(hMainWin, ID_EQUAL); IMAGE_SetBitmap(hItem, &bmframe0); WM_InvalidateWindow(hItem); WM_Update(hItem); if(hMainWin != 0) { hItem = WM_GetDialogItem(hMainWin, ID_ELAPSED_TIME); TEXT_SetText(hItem, "00:00"); WM_Update(hItem); } } }
/***************************** Peremaljovuvannja paneli resursu *****************************/ void redraw_panel_resurs(void) { EDIT_SetText(hEdit, _aBitmapItem[ICONVIEW_RES_COUNTER_ID].pExplanation[sel_language]); char string_tmp[10 + 1]; unsigned int value_tmp; value_tmp = resurs_tmp; if (int_to_str (value_tmp, string_tmp))TEXT_SetText(Resurs_v[0], string_tmp); value_tmp = resurs_count_tmp; if (int_to_str (value_tmp, string_tmp))TEXT_SetText(Resurs_v[1], string_tmp); WM_HWIN FocussedWindow = (Resurs_FrameWin); WM_SetFocus(FocussedWindow); }
/** * @brief Game window Startup * @param hWin: pointer to the parent handle. * @param xpos: X position * @param ypos: Y position * @retval None */ void VNC_SERVER_LogMessage (const char *message) { WM_HWIN hItem; hItem = WM_GetDialogItem(hVncWin, ID_VNC_STATUS); TEXT_SetText(hItem, message); }
/* ********************************************************************************************************* * 函 数 名: MainTask * 功能说明: GUI主函数 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void MainTask(void) { int Value = 0; WM_HWIN hDlgFrame; /* 初始化 */ GUI_Init(); // TOUCH_Calibration(); GUI_CURSOR_Show(); WM_SetCallback(WM_HBKWIN, _cbBkWindow); WM_SetCreateFlags(WM_CF_MEMDEV); hDlgFrame = 0; while(1) { WM_HWIN hDlg, hText; char acText[3] = {0}; GUI_Delay(100); /* 如果对话框被关闭就重新的将其再打开 */ if (!WM_IsWindow(hDlgFrame)) { Value = 0; hDlgFrame = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0); } Value = (Value + 1) % 100; acText[0] = '0' + Value / 10; acText[1] = '0' + Value % 10; hDlg = WM_GetClientWindow(hDlgFrame); hText = WM_GetDialogItem(hDlg, GUI_ID_TEXT0); TEXT_SetText(hText, acText); } }
/********************************************************************* * * _cbDialog */ static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; int Id, NCode; // USER START (Optionally insert additional variables) // USER END switch (pMsg->MsgId) { case WM_INIT_DIALOG: // // Initialization of '_tAboutL1' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0); TEXT_SetText(hItem, "J&S Open Source Instruments"); TEXT_SetTextAlign(hItem, GUI_TA_RIGHT | GUI_TA_VCENTER); // // Initialization of '_tAboutL2' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_1); TEXT_SetText(hItem, "Prowered By James Kong"); TEXT_SetTextAlign(hItem, GUI_TA_RIGHT | GUI_TA_VCENTER); // // Initialization of '_tAboutL3' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_2); TEXT_SetText(hItem, "Shawn Gao"); TEXT_SetTextAlign(hItem, GUI_TA_RIGHT | GUI_TA_VCENTER); // // Initialization of '_tAboutL5' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_3); TEXT_SetText(hItem, "2013-2014 Some Right Reserved"); // // Initialization of '_tAboutL4' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_4); TEXT_SetText(hItem, "This work is licensed under CC-BY-SA 4.0"); // USER START (Optionally insert additional code for further widget initialization) // USER END break; // USER START (Optionally insert additional message handling) // USER END default: WM_DefaultProc(pMsg); break; } }
////////////////////////////////////////////////////////////////////////////// // Product: DPP example with emWin/uC/GUI, WITH Window Manager // Last updated for version 6.2.0 // Last updated on 2018-03-16 // // Q u a n t u m L e a P s // --------------------------- // innovating embedded systems // // Copyright (C) Quantum Leaps, LLC. All rights reserved. // // This program is open source software: you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Alternatively, this program may be distributed and modified under the // terms of Quantum Leaps commercial licenses, which expressly supersede // the GNU General Public License and are specifically designed for // licensees interested in retaining the proprietary status of their code. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // // Contact information: // https://www.state-machine.com // mailto:[email protected] ////////////////////////////////////////////////////////////////////////////// #include "qpcpp.h" #include "dpp.h" #include "bsp.h" extern "C" { #include "GUI.h" #include "WM.h" // emWin Windows Manager #include "DIALOG.h" #include "SIM.h" } Q_DEFINE_THIS_FILE // Active object class ------------------------------------------------------- class Table : public QActive { private: uint8_t m_fork[N_PHILO]; uint8_t m_isHungry[N_PHILO]; public: Table(); private: static QState initial(Table *me, QEvt const *e); static QState ready (Table *me, QEvt const *e); static QState serving(Table *me, QEvt const *e); static QState paused (Table *me, QEvt const *e); }; #define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1)) % N_PHILO)) #define LEFT(n_) ((uint8_t)(((n_) + 1) % N_PHILO)) enum m_forkState { FREE, USED }; // Local objects ------------------------------------------------------------- static Table l_table; // local Table object #ifdef Q_SPY enum QSUserRecords { PHILO_STAT = QS_USER, TABLE_STAT }; static uint8_t const l_onDialogGUI = 0U; #endif // Public-scope objects ------------------------------------------------------ QActive * const AO_Table = &l_table; // "opaque" AO pointer // GUI definition ============================================================ static WM_HWIN l_hDlg; static WM_CALLBACK *l_cb_WM_HBKWIN; static const GUI_WIDGET_CREATE_INFO l_dialog[] = { { &FRAMEWIN_CreateIndirect, "Dining Philosopher Problem", 0, 30, 30, 260, 180, FRAMEWIN_CF_MOVEABLE }, { &TEXT_CreateIndirect, "Philosopher 0", GUI_ID_TEXT9, 50, 10, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Philosopher 1", GUI_ID_TEXT9, 50, 30, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Philosopher 2", GUI_ID_TEXT9, 50, 50, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Philosopher 3", GUI_ID_TEXT9, 50, 70, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Philosopher 4", GUI_ID_TEXT9, 50, 90, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Table", GUI_ID_TEXT9, 50, 110, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT0, 130, 10, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT1, 130, 30, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT2, 130, 50, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT3, 130, 70, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT4, 130, 90, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "serving", GUI_ID_TEXT5, 130, 110, 0, 0, TEXT_CF_LEFT }, { &BUTTON_CreateIndirect,"PAUSE", GUI_ID_BUTTON0, 160, 130, 80, 30 } }; //..........................................................................*/ static void onMainWndGUI(WM_MESSAGE* pMsg) { switch (pMsg->MsgId) { case WM_PAINT: { GUI_SetBkColor(GUI_GRAY); GUI_Clear(); GUI_SetColor(GUI_BLACK); GUI_SetFont(&GUI_Font24_ASCII); GUI_DispStringHCenterAt("Dining Philosophers - Demo", 160, 5); break; } default: { WM_DefaultProc(pMsg); break; } } } //..........................................................................*/ static void onDialogGUI(WM_MESSAGE * pMsg) { switch (pMsg->MsgId) { case WM_INIT_DIALOG: { break; } case WM_NOTIFY_PARENT: { switch (pMsg->Data.v) { case WM_NOTIFICATION_RELEASED: { // react only if released */ switch (WM_GetId(pMsg->hWinSrc)) { case GUI_ID_BUTTON0: { // static PAUSE event for the Table AO */ static QEvent const pauseEvt = { PAUSE_SIG, 0 }; AO_Table->POST(&pauseEvt, &l_onDialogGUI); break; } } break; } } break; } default: { WM_DefaultProc(pMsg); break; } } } //..........................................................................*/ static void displyPhilStat(uint8_t n, char const *stat) { TEXT_SetText(WM_GetDialogItem(l_hDlg, GUI_ID_TEXT0 + n), stat); WM_Exec(); // update the screen and invoke WM callbacks */ QS_BEGIN(PHILO_STAT, AO_Philo[n]) // application-specific record begin */ QS_U8(1, n); // Philosopher number */ QS_STR(stat); // Philosopher status */ QS_END() } //..........................................................................*/ static void displyTableStat(char const *stat) { TEXT_SetText(WM_GetDialogItem(l_hDlg, GUI_ID_TEXT5), stat); WM_Exec(); // update the screen and invoke WM callbacks */ QS_BEGIN(TABLE_STAT, AO_Table) // application-specific record begin */ QS_STR(stat); // Philosopher status */ QS_END() }
/********************************************************************* * * GUIDEMO_ShowInfo */ void GUIDEMO_ShowInfo(const char * acInfo) { TEXT_Handle hText; if (WM_IsVisible(_hDialogInfo)) { hText = WM_GetDialogItem(_hDialogInfo, GUI_ID_TEXT0); TEXT_SetText(hText, acInfo); } }
/********************************************************************* * * _cbDialog */ static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; int Id, NCode; // USER START (Optionally insert additional variables) // USER END switch (pMsg->MsgId) { case WM_INIT_DIALOG: // // Initialization of 'Demo' // hItem = pMsg->hWin; FRAMEWIN_SetText(hItem, "GUIBuilder Demo"); FRAMEWIN_SetFont(hItem, GUI_FONT_24B_ASCII); FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); FRAMEWIN_SetTextColor(hItem, 0x00FF8000); SCROLLBAR_CreateAttached(hItem, 0); SCROLLBAR_CreateAttached(hItem, SCROLLBAR_CF_VERTICAL); // // Initialization of 'Text' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0); TEXT_SetText(hItem, "This is a text!"); TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); TEXT_SetTextColor(hItem, 0x00000000); TEXT_SetFont(hItem, GUI_FONT_16B_ASCII); // USER START (Optionally insert additional code for further widget initialization) // USER END break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); NCode = pMsg->Data.v; switch(Id) { case ID_BUTTON_0: // Notifications sent by 'Button' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_RELEASED: // USER START (Optionally insert code for reacting on notification message) // USER END break; // USER START (Optionally insert additional code for further notification handling) // USER END } break; // USER START (Optionally insert additional code for further Ids) // USER END } break; // USER START (Optionally insert additional message handling) // USER END default: WM_DefaultProc(pMsg); break; } }
/********************************************************************* * * _cbFrameWinControl */ static void _cbFrameWinControl(WM_MESSAGE * pMsg) { WM_HWIN hItem; int xSize; int ySize; int NCode; int Id; switch (pMsg->MsgId) { case WM_KEY: WM_SendMessage(WM_HBKWIN, pMsg); break; case WM_INIT_DIALOG: hItem = WM_GetDialogItem(pMsg->hWin, GUI_ID_PROGBAR0); PROGBAR_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); PROGBAR_SetFont(hItem, &GUI_FontD6x8); hItem = WM_GetDialogItem(pMsg->hWin, GUI_ID_HALT); BUTTON_SetFocussable(hItem, 0); hItem = WM_GetDialogItem(pMsg->hWin, GUI_ID_NEXT); BUTTON_SetFocussable(hItem, 0); hItem = WM_GetDialogItem(pMsg->hWin, GUI_ID_TEXT0); TEXT_SetText(hItem, "Intro"); TEXT_SetFont(hItem, &GUI_Font8_ASCII); break; case WM_PAINT: xSize = WM_GetWindowSizeX(pMsg->hWin); ySize = WM_GetWindowSizeY(pMsg->hWin); GUI_DrawGradientV(0, 0, xSize - 1, ySize - 1, 0xFFFFFF, 0xDCCEC0); break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); NCode = pMsg->Data.v; switch (NCode) { case WM_NOTIFICATION_RELEASED: switch (Id) { case GUI_ID_HALT: if (_Halt) { _Halt = 0; _HaltTime = GUI_GetTime() - _HaltTimeStart; WM_MakeModal(0); } else { _Halt = 1; _HaltTimeStart = GUI_GetTime() - _HaltTime; WM_MakeModal(pMsg->hWin); } break; case GUI_ID_NEXT: _Next = 1; // Will be set to 0 by GUIDEMO_GetNextState() _ClearHalt(); // Clear _Halt, so the next sample demonstrates immediately break; } break; } break; default: WM_DefaultProc(pMsg); } }
////////////////////////////////////////////////////////////////////////////// // Product: DPP example with emWin/uC/GUI, WITH Window Manager // Last updated for version 6.2.0 // Last updated on 2018-03-16 // // Q u a n t u m L e a P s // --------------------------- // innovating embedded systems // // Copyright (C) Quantum Leaps, LLC. All rights reserved. // // This program is open source software: you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Alternatively, this program may be distributed and modified under the // terms of Quantum Leaps commercial licenses, which expressly supersede // the GNU General Public License and are specifically designed for // licensees interested in retaining the proprietary status of their code. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // // Contact information: // https://www.state-machine.com // mailto:[email protected] ////////////////////////////////////////////////////////////////////////////// #include "qpcpp.h" #include "dpp.h" #include "bsp.h" extern "C" { #include "GUI.h" #include "WM.h" // emWin Windows Manager #include "DIALOG.h" #include "SIM.h" } Q_DEFINE_THIS_FILE // Active object class ------------------------------------------------------- class Table : public QActive { private: uint8_t m_fork[N_PHILO]; uint8_t m_isHungry[N_PHILO]; public: Table(); private: static QState initial(Table *me, QEvt const *e); static QState ready (Table *me, QEvt const *e); static QState serving(Table *me, QEvt const *e); static QState paused (Table *me, QEvt const *e); }; #define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1)) % N_PHILO)) #define LEFT(n_) ((uint8_t)(((n_) + 1) % N_PHILO)) enum m_forkState { FREE, USED }; // Local objects ------------------------------------------------------------- static Table l_table; // local Table object #ifdef Q_SPY enum QSUserRecords { PHILO_STAT = QS_USER, TABLE_STAT }; static uint8_t const l_onDialogGUI = 0U; #endif // Public-scope objects ------------------------------------------------------ QActive * const AO_Table = &l_table; // "opaque" AO pointer // GUI definition ============================================================ static WM_HWIN l_hDlg; static WM_CALLBACK *l_cb_WM_HBKWIN; static const GUI_WIDGET_CREATE_INFO l_dialog[] = { { &FRAMEWIN_CreateIndirect, "Dining Philosopher Problem", 0, 30, 30, 260, 180, FRAMEWIN_CF_MOVEABLE }, { &TEXT_CreateIndirect, "Philosopher 0", GUI_ID_TEXT9, 50, 10, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Philosopher 1", GUI_ID_TEXT9, 50, 30, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Philosopher 2", GUI_ID_TEXT9, 50, 50, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Philosopher 3", GUI_ID_TEXT9, 50, 70, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Philosopher 4", GUI_ID_TEXT9, 50, 90, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "Table", GUI_ID_TEXT9, 50, 110, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT0, 130, 10, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT1, 130, 30, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT2, 130, 50, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT3, 130, 70, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "thinking", GUI_ID_TEXT4, 130, 90, 0, 0, TEXT_CF_LEFT }, { &TEXT_CreateIndirect, "serving", GUI_ID_TEXT5, 130, 110, 0, 0, TEXT_CF_LEFT }, { &BUTTON_CreateIndirect,"PAUSE", GUI_ID_BUTTON0, 160, 130, 80, 30 } }; //..........................................................................*/ static void onMainWndGUI(WM_MESSAGE* pMsg) { switch (pMsg->MsgId) { case WM_PAINT: { GUI_SetBkColor(GUI_GRAY); GUI_Clear(); GUI_SetColor(GUI_BLACK); GUI_SetFont(&GUI_Font24_ASCII); GUI_DispStringHCenterAt("Dining Philosophers - Demo", 160, 5); break; } default: { WM_DefaultProc(pMsg); break; } } } //..........................................................................*/ static void onDialogGUI(WM_MESSAGE * pMsg) { switch (pMsg->MsgId) { case WM_INIT_DIALOG: { break; } case WM_NOTIFY_PARENT: { switch (pMsg->Data.v) { case WM_NOTIFICATION_RELEASED: { // react only if released */ switch (WM_GetId(pMsg->hWinSrc)) { case GUI_ID_BUTTON0: { // static PAUSE event for the Table AO */ static QEvent const pauseEvt = { PAUSE_SIG, 0 }; AO_Table->POST(&pauseEvt, &l_onDialogGUI); break; } } break; } } break; } default: { WM_DefaultProc(pMsg); break; } } } //..........................................................................*/ static void displyPhilStat(uint8_t n, char const *stat) { TEXT_SetText(WM_GetDialogItem(l_hDlg, GUI_ID_TEXT0 + n), stat); WM_Exec(); // update the screen and invoke WM callbacks */ QS_BEGIN(PHILO_STAT, AO_Philo[n]) // application-specific record begin */ QS_U8(1, n); // Philosopher number */ QS_STR(stat); // Philosopher status */ QS_END() }
/*---------------------------------------------------------------------------* * Routine: _cbDialog *---------------------------------------------------------------------------* * Description: * Callback function used by emWin to process events for the active window. * Inputs: * WM_MESSAGE *pMsg -- message structure for current dialog. *---------------------------------------------------------------------------*/ static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; int Id, NCode; T_keyboardMapping *p = G_keypadCurrentMapping; switch (pMsg->MsgId) { case WM_INIT_DIALOG: // // Initialization of 'Window' // hItem = pMsg->hWin; G_window = hItem; WINDOW_SetBkColor(hItem, KEYBOARD_BACKGROUND_COLOR); //BUTTON_SetDefaultBkColor(KEY_BACKGROUND_COLOR, BUTTON_CI_UNPRESSED); EDIT_SetDefaultFont(&KEYBOARD_DEFAULT_FONT); hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_BOX); EDIT_SetMaxLen(hItem, MAX_NUMBER_OF_CHARS); EDIT_SetText(hItem, G_textBox); EDIT_SetFont(hItem, &KEYBOARD_DEFAULT_FONT); G_textBoxIndex = EDIT_GetNumChars(hItem); hItem = WM_GetDialogItem(pMsg->hWin, ID_MESSAGE); TEXT_SetFont(hItem, &KEYBOARD_DEFAULT_FONT); TEXT_SetTextColor(hItem, GUI_BLACK); TEXT_SetBkColor(hItem, KEYBOARD_BACKGROUND_COLOR); TEXT_SetText(hItem, G_message); TEXT_SetTextAlign(hItem, GUI_TA_TOP); while (p->iID) { hItem = WM_GetDialogItem(pMsg->hWin, p->iID); BUTTON_SetFont(hItem, &KEYBOARD_DEFAULT_FONT); BUTTON_SetTextColor(hItem, BUTTON_CI_UNPRESSED, GUI_BLACK); BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_BLACK); BUTTON_SetBkColor(hItem, BUTTON_CI_UNPRESSED, KEY_BACKGROUND_COLOR); BUTTON_SetBkColor(hItem, BUTTON_CI_PRESSED, GUI_LIGHTGRAY); //BUTTON_SetSkin(hItem, BUTTON_SKIN_FLEX); p++; } WM_MakeModal(pMsg->hWin); setNewButtonText(pMsg, 0, 0); break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); NCode = pMsg->Data.v; if (!IKeyboardHandleEvent(pMsg, NCode, Id)) { // Special cases go here // Nothing happens otherwise } case WM_POST_PAINT: // Make sure the all presses up til now are gone TouchscreenClearPresses(); break; default: WM_DefaultProc(pMsg); break; } }
/** * @brief wt_SetText_Menu * @param * @retval None */ void wt_SetText_Menu(const char * pMenu) { TEXT_Handle hText; if (WM_IsVisible(hWin_Title)) { hText = WM_GetDialogItem(hWin_Title, ID_TITLE_TEXT_1); TEXT_SetText(hText, pMenu); } }
/********************************************************************* * * Обновление меток диалогового окна */ void update_do_labels() { TEXT_SetText(WM_GetDialogItem(rankDlgDOPg, ID_RANK_DO_TEXT_LABEL), typeDOTextLabels[sel_language]); DROPDOWN_Handle typeDOListBox = WM_GetDialogItem(rankDlgDOPg, ID_RANK_DO_TYPE); DROPDOWN_DeleteItem(typeDOListBox, 0); DROPDOWN_InsertString(typeDOListBox, typesDO0[sel_language], 0); DROPDOWN_DeleteItem(typeDOListBox, 1); DROPDOWN_InsertString(typeDOListBox, typesDO1[sel_language], 1); }
/** * @brief Callback routine of the alarm dialog * @param pMsg: pointer to a data structure of type WM_MESSAGE * @retval None */ static void _cbAlarmDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; int Id, NCode; char temp[50]; uint8_t asec, amin, ahour; switch (pMsg->MsgId) { case WM_INIT_DIALOG: /* Initialization of 'Alarm' */ hItem = pMsg->hWin; FRAMEWIN_SetFont(hItem, GUI_FONT_13HB_ASCII); hItem = WM_GetDialogItem(pMsg->hWin, ID_ALARM); TEXT_SetFont(hItem, GUI_FONT_13HB_ASCII); /* Initialization of 'Image' */ hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_INFO); IMAGE_SetBitmap(hItem, &bmalarmclock); /* Initialization of 'Time' */ hItem = WM_GetDialogItem(pMsg->hWin, ID_TIME); ahour = RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours; amin = RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes; asec = RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds; sprintf (temp, "%02d:%02d:%02d", ahour, amin, asec); TEXT_SetText(hItem, temp); TEXT_SetFont(hItem, GUI_FONT_24B_ASCII); TEXT_SetTextColor(hItem, GUI_BROWN); /* Initialization of 'Close' */ hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_INFO_CLOSE); BUTTON_SetFont(hItem, GUI_FONT_13HB_ASCII); break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); /* Id of widget */ NCode = pMsg->Data.v; /* Notification code */ switch (NCode) { case WM_NOTIFICATION_RELEASED: /* React only if released */ switch (Id) { case ID_BUTTON_INFO_CLOSE: GUI_EndDialog(pMsg->hWin, 0); STM_EVAL_LEDOff(LED4); alarm_set=0; break; } break; } break; default: WM_DefaultProc(pMsg); break; } }
/*---------------------------------------------------------------------------*/ static void IUpdateFields(WM_MESSAGE *pMsg) { WM_HWIN hItem; T_uezTimeDate currentTimeDate; char message[50]; hItem = WM_GetDialogItem(pMsg->hWin, ID_TITLE_TEXT); TEXT_SetText(hItem, G_AlbumName); UEZTimeDateGet(¤tTimeDate); hItem = WM_GetDialogItem(pMsg->hWin, ID_TIMEDATE_TEXT); sprintf(message, "%02d:%02d %02d/%02d/%04d", currentTimeDate.iTime.iHour, currentTimeDate.iTime.iMinute, currentTimeDate.iDate.iMonth, currentTimeDate.iDate.iDay, currentTimeDate.iDate.iYear); TEXT_SetText(hItem, message); }
/********************************************************************* * * _cbFrameWinVideo */ static void _cbFrameWinVideo(WM_MESSAGE* pMsg) { WM_HWIN hWin; WM_HWIN hText; int IsCompletelyVis; int IsCompletelyCovered; switch (pMsg->MsgId) { case WM_PAINT: if (_IsCompletelyVis) { GUI_SetBkColor(GUI_DARKGREEN); GUI_Clear(); GUI_SetColor(GUI_WHITE); GUI_DispStringAt("Completely visible", 5, 5); } else { GUI_SetBkColor(GUI_GRAY); GUI_Clear(); GUI_SetColor(GUI_WHITE); GUI_DispStringAt("Not completely visible", 5, 5); } break; case WM_NOTIFY_VIS_CHANGED: hText = WM_GetDialogItem(WM_HBKWIN, GUI_ID_TEXT1); hWin = WM_GetClientWindow(pMsg->hWin); IsCompletelyVis = WM_IsCompletelyVisible(hWin); IsCompletelyCovered = WM_IsCompletelyCovered(hWin); if (IsCompletelyCovered) { TEXT_SetText(hText, "completely\ncovered"); } else { TEXT_SetText(hText, "not completely\ncovered"); } if (_IsCompletelyVis != IsCompletelyVis) { _IsCompletelyVis = IsCompletelyVis; WM_InvalidateWindow(hWin); /* Only required if content changes if partially hidden */ } break; default: WM_DefaultProc(pMsg); } }
/********************************************************************* * * GUIDEMO_UpdateControlText */ void GUIDEMO_UpdateControlText(void) { TEXT_Handle hText; char acText[20] = { 0 }; hText = WM_GetDialogItem(_hDialogControl, GUI_ID_TEXT0); GUIDEMO_AddStringToString(acText, "Demo "); GUIDEMO_AddIntToString (acText, _iDemo + 1); GUIDEMO_AddStringToString(acText, "."); GUIDEMO_AddIntToString (acText, _iDemoMinor); GUIDEMO_AddStringToString(acText, "/"); GUIDEMO_AddIntToString (acText, _GUIDemoConfig.NumDemos - 1); TEXT_SetText (hText, acText); }
/********************************************************************* * * _cbDialog */ static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; // USER START (Optionally insert additional variables) // USER END switch (pMsg->MsgId) { case WM_INIT_DIALOG: // // Initialization of 'Window' // hItem = pMsg->hWin; WINDOW_SetBkColor(hItem, 0x00000000); // // Initialization of 'Text' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0); TEXT_SetTextColor(hItem, 0x0010DA80); TEXT_SetText(hItem, "22.1"); TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); TEXT_SetFont(hItem, GUI_FONT_20B_ASCII); // // Initialization of 'Text' // hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_1); TEXT_SetTextColor(hItem, 0x0011B511); TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); TEXT_SetFont(hItem, GUI_FONT_20B_ASCII); TEXT_SetText(hItem, "22.4"); // USER START (Optionally insert additional code for further widget initialization) // USER END break; // USER START (Optionally insert additional message handling) // USER END default: WM_DefaultProc(pMsg); break; } }
/** * @brief Display assigned IP, Mask and GW addresses on the VNC dialog * @param None * @retval None */ static void _VNCServer_DisplayIPAddress(void) { WM_HWIN hItem; uint8_t iptxt[30]; hItem = WM_GetDialogItem(hWinVNC, ID_TEXT_DHCP_STATE); if (VNCSettings.dhcp_use.b.dhcp) TEXT_SetText(hItem, (char const *)"Enabled"); else TEXT_SetText(hItem, (char const *)"Disabled"); sprintf((char*)iptxt, " %d.%d.%d.%d\n", VNCSettings.ipaddr.b.addr3, VNCSettings.ipaddr.b.addr2, VNCSettings.ipaddr.b.addr1, VNCSettings.ipaddr.b.addr0); hItem = WM_GetDialogItem(hWinVNC, ID_TEXT_IPADDR_VALUE); TEXT_SetText(hItem, (char const *)iptxt); sprintf((char*)iptxt, " %d.%d.%d.%d\n", VNCSettings.maskaddr.b.addr3, VNCSettings.maskaddr.b.addr2, VNCSettings.maskaddr.b.addr1, VNCSettings.maskaddr.b.addr0); hItem = WM_GetDialogItem(hWinVNC, ID_TEXT_SUBNETMASK_VALUE); TEXT_SetText(hItem, (char const *)iptxt); sprintf((char*)iptxt, " %d.%d.%d.%d\n", VNCSettings.gwaddr.b.addr3, VNCSettings.gwaddr.b.addr2, VNCSettings.gwaddr.b.addr1, VNCSettings.gwaddr.b.addr0); hItem = WM_GetDialogItem(hWinVNC, ID_TEXT_GWADDR_VALUE); TEXT_SetText(hItem, (char const *)iptxt); }
/** * @brief Play wav file. * @param filename: pointer to file name. * @retval None */ static void _PlayFile(char *filename) { int duration; static char tmp[FILEMGR_FILE_NAME_SIZE]; WM_HWIN hItem; if(AUDIOPLAYER_GetFileInfo(filename, &WavInfo) == 0) { /* Title */ FILEMGR_GetFileOnly (tmp, filename); TEXT_SetText(WM_GetDialogItem(AUDIOPLAYER_hWin, ID_TITLE), tmp); /* Total Time */ duration = WavInfo.FileSize / WavInfo.ByteRate; sprintf((char *)tmp , "%02d:%02d", duration/60, duration%60 ); hItem = WM_GetDialogItem(AUDIOPLAYER_hWin, ID_TOTAL_TIME); TEXT_SetText(hItem, tmp); /* Author */ hItem = WM_GetDialogItem(AUDIOPLAYER_hWin, ID_AUTHOR); TEXT_SetText(hItem, "Unknown"); /* Sampling Rate */ hItem = WM_GetDialogItem(AUDIOPLAYER_hWin, ID_SAMPLING_VALUE); sprintf((char *)tmp , "%lu Hz", WavInfo.SampleRate); TEXT_SetText(hItem, tmp); /* Open audio file */ if(AUDIOPLAYER_SelectFile(filename) == 0) { /* start playing */ AUDIOPLAYER_Play(WavInfo.SampleRate); if(PlayerSettings.b.mute == MUTE_ON) { AUDIOPLAYER_Mute(MUTE_ON); } } } else { TEXT_SetText(WM_GetDialogItem(AUDIOPLAYER_hWin, ID_TITLE), "Unknown"); hItem = WM_GetDialogItem(AUDIOPLAYER_hWin, ID_TOTAL_TIME); TEXT_SetText(hItem, "--:--"); hItem = WM_GetDialogItem(AUDIOPLAYER_hWin, ID_SAMPLING_VALUE); TEXT_SetText(hItem, "Unsupported Format"); } }
/********************************************************************* * * MainTask */ void MainTask(void) { int Value = 0; WM_HWIN hDlgFrame; GUI_Init(); WM_SetCallback(WM_HBKWIN, _cbBkWindow); WM_SetCreateFlags(WM_CF_MEMDEV); /* Use memory devices on all windows to avoid flicker */ while(1) { WM_HWIN hDlg, hText; char acText[3] = {0}; GUI_Delay(150); if (!WM_IsWindow(hDlgFrame)) { hDlgFrame = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0); } Value = (Value + 1) % 100; acText[0] = '0' + Value / 10; acText[1] = '0' + Value % 10; hDlg = WM_GetClientWindow(hDlgFrame); hText = WM_GetDialogItem(hDlg, GUI_ID_TEXT0); TEXT_SetText(hText, acText); } }
// USER START (Optionally insert additional static code) // USER END static void _cbDialog2(WM_MESSAGE * pMsg) { WM_HWIN hItem; switch (pMsg->MsgId) { case WM_INIT_DIALOG: { hItem=WM_GetDialogItem(pMsg->hWin,ID_TEXT_1); TEXT_SetFont(hItem,GUI_FONT_32_ASCII); TEXT_SetText(hItem,itoa(il,t,10)); break; } default: { WM_DefaultProc(pMsg); break; } } }
/** * @brief Callback routine of the Benchmark dialog * @param pMsg: pointer to data structure of type WM_MESSAGE * @retval None */ static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; int Id, NCode; WM_HWIN hGraph; int cpu_speed = 0; char temp[50]; WM_CALLBACK *_cb; switch (pMsg->MsgId) { case WM_INIT_DIALOG: /* Initialization of 'CPU' */ hItem = pMsg->hWin; FRAMEWIN_SetFont(hItem, GUI_FONT_13HB_ASCII); FRAMEWIN_AddCloseButton(hItem, FRAMEWIN_BUTTON_RIGHT, 0); hItem = TEXT_CreateEx(10, 20, 100, 25, pMsg->hWin, WM_CF_SHOW,0, 0x123,""); TEXT_SetFont(hItem, GUI_FONT_13B_1); TEXT_SetTextColor(hItem, 0x00804000); TEXT_SetText(hItem, "CPU Usage %:"); hItem = WM_GetDialogItem(pMsg->hWin, ID_BENCH_CPU); TEXT_SetFont(hItem, GUI_FONT_16B_ASCII); TEXT_SetTextColor(hItem, GUI_DARKRED); hItem = WM_GetDialogItem(pMsg->hWin, ID_CPU_GRAPH); FRAMEWIN_SetBarColor(hItem, 0, GUI_DARKGRAY); FRAMEWIN_SetBarColor(hItem, 1, GUI_DARKGRAY); hGraph = GRAPH_CreateEx(10, 35, 300, 95, pMsg->hWin, WM_CF_SHOW, 0, GUI_ID_GRAPH0); hData = GRAPH_DATA_YT_Create(GUI_LIGHTGREEN, 500, 0, 20); GRAPH_SetGridVis(hGraph, 1); GRAPH_SetBorder(hGraph, 20, 4, 5, 4); GRAPH_AttachData(hGraph, hData); hScale = GRAPH_SCALE_Create(20, GUI_TA_RIGHT, GRAPH_SCALE_CF_VERTICAL, 25); GRAPH_AttachScale(hGraph, hScale); GRAPH_SCALE_SetTextColor(hScale, GUI_YELLOW); GRAPH_SetGridDistX(hGraph, 25); GRAPH_SetGridDistY(hGraph, 25); WM_CreateWindowAsChild(80, 45, 354, 23, pMsg->hWin, WM_CF_SHOW | WM_CF_HASTRANS, _cbCpuWindow , 0); break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); /* Id of widget */ NCode = pMsg->Data.v; /* Notification code */ switch (NCode) { case WM_NOTIFICATION_RELEASED: /* React only if released */ switch (Id) { case ID_BENCH_CPU: Stop_Test = 0; WM_HideWindow(pMsg->hWin); _cb = WM_GetCallback(WM_HBKWIN); WM_SetCallback(WM_HBKWIN, _ClearDesktop); cpu_speed = Run_SpeedTest(); WM_ShowWindow(pMsg->hWin); hItem = WM_GetDialogItem(pMsg->hWin, ID_BENCH_CPU); sprintf (temp, "%d Pixels/s ", cpu_speed); TEXT_SetText(hItem, temp); WM_SetCallback(WM_HBKWIN, _cb); hItem = WM_GetDialogItem(WM_HBKWIN, ID_BUTTON_BKGND); WM_InvalidateWindow(hItem); WM_InvalidateWindow(WM_HBKWIN); WM_Paint(WM_HBKWIN); break; } break; case WM_NOTIFICATION_CHILD_DELETED: Stop_Test = 1; break; } break; default: WM_DefaultProc(pMsg); break; } }