From 5bbbc41898b7bc5f603ae5eb882afed4df31afb7 Mon Sep 17 00:00:00 2001 From: idea4good Date: Fri, 8 Nov 2019 23:11:45 +0800 Subject: [PATCH] refactor folder --- GuiLite-linux.cpp | 3727 ++++++++++++++++ GuiLite-unknow.cpp | 3460 +++++++++++++++ GuiLite-win.cpp | 3887 +++++++++++++++++ GuiLite.h | 900 ++++ README.md | 40 +- README_zh.md | 40 +- {doc => documents}/Android.gif | Bin {doc => documents}/BuildInfo.png | Bin {doc => documents}/GraphicLayer.png | Bin {doc => documents}/GuiLite3D.gif | Bin {doc => documents}/GuiLiteCube.gif | Bin {doc => documents}/GuiLiteGraphic.gif | Bin {doc => documents}/Hello3D.gif | Bin {doc => documents}/HelloNets-pc.gif | Bin {doc => documents}/HelloParticle.gif | Bin {doc => documents}/HelloStar.gif | Bin {doc => documents}/HelloWave.gif | Bin {doc => documents}/HelloWidgets.gif | Bin {doc => documents}/HostMonitor.gif | Bin {doc => documents}/HowLayoutWork.md | 0 {doc => documents}/HowMessageWork.md | 0 {doc => documents}/HowToBuild.md | 0 {doc => documents}/HowToWork-cn.md | 0 {doc => documents}/HowToWork.md | 0 {doc => documents}/Linux.gif | Bin {doc => documents}/Mac.gif | Bin {doc => documents}/Previewer.gif | Bin {doc => documents}/UML.md | 0 {doc => documents}/WinMR.gif | Bin {doc => documents}/click_button.png | Bin {doc => documents}/data_on_cloud.png | Bin {doc => documents}/draw_wav.png | Bin {doc => documents}/flip.png | Bin {doc => documents}/iOS.gif | Bin {doc => documents}/iOS.particle.gif | Bin {doc => documents}/iWatch.hello3D.gif | Bin {doc => documents}/iWatch.helloWave.gif | Bin {doc => documents}/layout_dialog.png | Bin {doc => documents}/layout_single_slide.png | Bin {doc => documents}/layout_slide_group.png | Bin {doc => documents}/qq.group.jpg | Bin {doc => documents}/uml-class.png | Bin {doc => documents}/uml-ui-process.png | Bin {doc => documents}/unicode.jpg | Bin {doc => documents}/vs-configure.jpg | Bin workspace/.DS_Store | Bin 0 -> 6148 bytes 1h-1cpp.sh => workspace/1h-1cpp.sh | 0 CMakeLists.txt => workspace/CMakeLists.txt | 0 GuiLite.sln => workspace/GuiLite.sln | 0 GuiLite.uvprojx => workspace/GuiLite.uvprojx | 0 GuiLite.vcxproj => workspace/GuiLite.vcxproj | 0 .../GuiLite.vcxproj.filters | 0 LICENSE => workspace/LICENSE | 0 .../core}/adapter/api_linux.cpp | 0 .../core}/adapter/api_unknow.cpp | 0 {core => workspace/core}/adapter/api_win.cpp | 0 .../core}/adapter/audio_linux.cpp | 0 .../core}/adapter/audio_win.cpp | 0 {core => workspace/core}/bitmap.cpp | 0 {core => workspace/core}/cmd_target.cpp | 0 {core => workspace/core}/display.cpp | 0 {core => workspace/core}/rect.cpp | 0 {core => workspace/core}/surface.cpp | 0 {core => workspace/core}/theme.cpp | 0 {core => workspace/core}/wnd.cpp | 0 {core => workspace/core}/word.cpp | 0 .../core_include}/api.h | 0 .../core_include}/audio.h | 0 .../core_include}/bitmap.h | 0 .../core_include}/cmd_target.h | 0 .../core_include}/display.h | 0 .../core_include}/rect.h | 0 .../core_include}/resource.h | 0 .../core_include}/surface.h | 0 .../core_include}/theme.h | 0 .../core_include}/wnd.h | 0 .../core_include}/word.h | 0 sync_build.bat => workspace/sync_build.bat | 0 {widgets => workspace/widgets}/button.cpp | 0 {widgets => workspace/widgets}/dialog.cpp | 0 {widgets => workspace/widgets}/edit.cpp | 0 {widgets => workspace/widgets}/gesture.cpp | 0 {widgets => workspace/widgets}/keyboard.cpp | 0 {widgets => workspace/widgets}/label.cpp | 0 {widgets => workspace/widgets}/list_box.cpp | 0 .../widgets}/slide_group.cpp | 0 {widgets => workspace/widgets}/spinbox.cpp | 0 {widgets => workspace/widgets}/table.cpp | 0 .../widgets}/wave_buffer.cpp | 0 {widgets => workspace/widgets}/wave_ctrl.cpp | 0 .../widgets_include}/button.h | 0 .../widgets_include}/dialog.h | 0 .../widgets_include}/edit.h | 0 .../widgets_include}/gesture.h | 0 .../widgets_include}/keyboard.h | 0 .../widgets_include}/label.h | 0 .../widgets_include}/list_box.h | 0 .../widgets_include}/slide_group.h | 0 .../widgets_include}/spinbox.h | 0 .../widgets_include}/table.h | 0 .../widgets_include}/wave_buffer.h | 0 .../widgets_include}/wave_ctrl.h | 0 102 files changed, 12014 insertions(+), 40 deletions(-) create mode 100644 GuiLite-linux.cpp create mode 100644 GuiLite-unknow.cpp create mode 100644 GuiLite-win.cpp create mode 100644 GuiLite.h rename {doc => documents}/Android.gif (100%) rename {doc => documents}/BuildInfo.png (100%) rename {doc => documents}/GraphicLayer.png (100%) rename {doc => documents}/GuiLite3D.gif (100%) rename {doc => documents}/GuiLiteCube.gif (100%) rename {doc => documents}/GuiLiteGraphic.gif (100%) rename {doc => documents}/Hello3D.gif (100%) rename {doc => documents}/HelloNets-pc.gif (100%) rename {doc => documents}/HelloParticle.gif (100%) rename {doc => documents}/HelloStar.gif (100%) rename {doc => documents}/HelloWave.gif (100%) rename {doc => documents}/HelloWidgets.gif (100%) rename {doc => documents}/HostMonitor.gif (100%) rename {doc => documents}/HowLayoutWork.md (100%) rename {doc => documents}/HowMessageWork.md (100%) rename {doc => documents}/HowToBuild.md (100%) rename {doc => documents}/HowToWork-cn.md (100%) rename {doc => documents}/HowToWork.md (100%) rename {doc => documents}/Linux.gif (100%) rename {doc => documents}/Mac.gif (100%) rename {doc => documents}/Previewer.gif (100%) rename {doc => documents}/UML.md (100%) rename {doc => documents}/WinMR.gif (100%) rename {doc => documents}/click_button.png (100%) rename {doc => documents}/data_on_cloud.png (100%) rename {doc => documents}/draw_wav.png (100%) rename {doc => documents}/flip.png (100%) rename {doc => documents}/iOS.gif (100%) rename {doc => documents}/iOS.particle.gif (100%) rename {doc => documents}/iWatch.hello3D.gif (100%) rename {doc => documents}/iWatch.helloWave.gif (100%) rename {doc => documents}/layout_dialog.png (100%) rename {doc => documents}/layout_single_slide.png (100%) rename {doc => documents}/layout_slide_group.png (100%) rename {doc => documents}/qq.group.jpg (100%) rename {doc => documents}/uml-class.png (100%) rename {doc => documents}/uml-ui-process.png (100%) rename {doc => documents}/unicode.jpg (100%) rename {doc => documents}/vs-configure.jpg (100%) create mode 100644 workspace/.DS_Store rename 1h-1cpp.sh => workspace/1h-1cpp.sh (100%) rename CMakeLists.txt => workspace/CMakeLists.txt (100%) rename GuiLite.sln => workspace/GuiLite.sln (100%) rename GuiLite.uvprojx => workspace/GuiLite.uvprojx (100%) rename GuiLite.vcxproj => workspace/GuiLite.vcxproj (100%) rename GuiLite.vcxproj.filters => workspace/GuiLite.vcxproj.filters (100%) rename LICENSE => workspace/LICENSE (100%) rename {core => workspace/core}/adapter/api_linux.cpp (100%) rename {core => workspace/core}/adapter/api_unknow.cpp (100%) rename {core => workspace/core}/adapter/api_win.cpp (100%) rename {core => workspace/core}/adapter/audio_linux.cpp (100%) rename {core => workspace/core}/adapter/audio_win.cpp (100%) rename {core => workspace/core}/bitmap.cpp (100%) rename {core => workspace/core}/cmd_target.cpp (100%) rename {core => workspace/core}/display.cpp (100%) rename {core => workspace/core}/rect.cpp (100%) rename {core => workspace/core}/surface.cpp (100%) rename {core => workspace/core}/theme.cpp (100%) rename {core => workspace/core}/wnd.cpp (100%) rename {core => workspace/core}/word.cpp (100%) rename {core_include => workspace/core_include}/api.h (100%) rename {core_include => workspace/core_include}/audio.h (100%) rename {core_include => workspace/core_include}/bitmap.h (100%) rename {core_include => workspace/core_include}/cmd_target.h (100%) rename {core_include => workspace/core_include}/display.h (100%) rename {core_include => workspace/core_include}/rect.h (100%) rename {core_include => workspace/core_include}/resource.h (100%) rename {core_include => workspace/core_include}/surface.h (100%) rename {core_include => workspace/core_include}/theme.h (100%) rename {core_include => workspace/core_include}/wnd.h (100%) rename {core_include => workspace/core_include}/word.h (100%) rename sync_build.bat => workspace/sync_build.bat (100%) rename {widgets => workspace/widgets}/button.cpp (100%) rename {widgets => workspace/widgets}/dialog.cpp (100%) rename {widgets => workspace/widgets}/edit.cpp (100%) rename {widgets => workspace/widgets}/gesture.cpp (100%) rename {widgets => workspace/widgets}/keyboard.cpp (100%) rename {widgets => workspace/widgets}/label.cpp (100%) rename {widgets => workspace/widgets}/list_box.cpp (100%) rename {widgets => workspace/widgets}/slide_group.cpp (100%) rename {widgets => workspace/widgets}/spinbox.cpp (100%) rename {widgets => workspace/widgets}/table.cpp (100%) rename {widgets => workspace/widgets}/wave_buffer.cpp (100%) rename {widgets => workspace/widgets}/wave_ctrl.cpp (100%) rename {widgets_include => workspace/widgets_include}/button.h (100%) rename {widgets_include => workspace/widgets_include}/dialog.h (100%) rename {widgets_include => workspace/widgets_include}/edit.h (100%) rename {widgets_include => workspace/widgets_include}/gesture.h (100%) rename {widgets_include => workspace/widgets_include}/keyboard.h (100%) rename {widgets_include => workspace/widgets_include}/label.h (100%) rename {widgets_include => workspace/widgets_include}/list_box.h (100%) rename {widgets_include => workspace/widgets_include}/slide_group.h (100%) rename {widgets_include => workspace/widgets_include}/spinbox.h (100%) rename {widgets_include => workspace/widgets_include}/table.h (100%) rename {widgets_include => workspace/widgets_include}/wave_buffer.h (100%) rename {widgets_include => workspace/widgets_include}/wave_ctrl.h (100%) diff --git a/GuiLite-linux.cpp b/GuiLite-linux.cpp new file mode 100644 index 0000000..7b85c1d --- /dev/null +++ b/GuiLite-linux.cpp @@ -0,0 +1,3727 @@ +#include "GuiLite.h" +void c_bitmap::draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO *pBitmap, int x, int y, unsigned int mask_rgb) +{ + if (0 == pBitmap) + { + return; + } + unsigned short* lower_fb = 0; + int lower_fb_width = surface->m_width; + if (z_order >= Z_ORDER_LEVEL_1) + { + lower_fb = surface->m_frame_layers[z_order - 1].fb; + } + unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); + int xsize = pBitmap->width; + int ysize = pBitmap->height; + const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; + for (int j = 0; j < ysize; j++) + { + for (int i = 0; i < xsize; i++) + { + unsigned int rgb = *pData++; + if (mask_rgb_16 == rgb) + { + if (lower_fb) + {//restore lower layer + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(lower_fb[(y + j) * lower_fb_width + x + i]), z_order); + } + } + else + { + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + } + } + } +} +void c_bitmap::draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO* pBitmap, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb) +{ + if (0 == pBitmap || (src_x + width > pBitmap->width) || (src_y + height > pBitmap->height)) + { + return; + } + unsigned short* lower_fb = 0; + int lower_fb_width = surface->m_width; + if (z_order >= Z_ORDER_LEVEL_1) + { + lower_fb = surface->m_frame_layers[z_order - 1].fb; + } + unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); + const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; + for (int j = 0; j < height; j++) + { + const unsigned short* p = &pData[src_x + (src_y + j) * pBitmap->width]; + for (int i = 0; i < width; i++) + { + unsigned int rgb = *p++; + if (mask_rgb_16 == rgb) + { + if (lower_fb) + {//restore lower layer + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(lower_fb[(y + j) * lower_fb_width + x + i]), z_order); + } + } + else + { + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + } + } + } +} +GL_MSG_ENTRY c_cmd_target::ms_usr_map_entries[USR_MSG_MAX]; +unsigned short c_cmd_target::ms_user_map_size; +GL_BEGIN_MESSAGE_MAP(c_cmd_target) +GL_END_MESSAGE_MAP() +c_cmd_target::c_cmd_target() +{ +} +c_cmd_target::~c_cmd_target() +{ +} +int c_cmd_target::handle_usr_msg(unsigned int msgId, unsigned int wParam, unsigned int lParam) +{ + int i; + c_cmd_target* p_wnd = 0; + MSGFUNCS msg_funcs; + for (i = 0; i < ms_user_map_size; i++) + { + if (msgId == ms_usr_map_entries[i].msgId) + { + p_wnd = (c_cmd_target*)ms_usr_map_entries[i].pObject; + msg_funcs.func = ms_usr_map_entries[i].func; + (p_wnd->*msg_funcs.func_vwl)(wParam , lParam); + } + } + return 1; +} +void c_cmd_target::load_cmd_msg() +{ + const GL_MSG_ENTRY* p_entry = GetMSgEntries(); + if (0 == p_entry) + { + return; + } + bool bExist = false; + while(MSG_TYPE_INVALID != p_entry->msgType) + { + if (MSG_TYPE_WND == p_entry->msgType) + { + p_entry++; + continue; + } + bExist = false; + for (int i = 0; i < ms_user_map_size; i++) + { + //repeat register, return. + if (p_entry->msgId == ms_usr_map_entries[i].msgId + && ms_usr_map_entries[i].pObject == this) + { + bExist = true; + break; + } + } + if (true == bExist) + { + p_entry++; + continue; + } + if (MSG_TYPE_USR == p_entry->msgType) + { + ms_usr_map_entries[ms_user_map_size] = *p_entry; + ms_usr_map_entries[ms_user_map_size].pObject = this; + ms_user_map_size++; + if (USR_MSG_MAX == ms_user_map_size) + { + ASSERT(false); + } + } + else + { + ASSERT(false); + break; + } + p_entry++; + } +} +const GL_MSG_ENTRY* c_cmd_target::FindMsgEntry(const GL_MSG_ENTRY *pEntry, + unsigned int msgType, unsigned short msgId, unsigned short ctrlId) +{ + if ( MSG_TYPE_INVALID == msgType) + { + return 0; + } + while (MSG_CALLBACK_NULL != pEntry->callbackType) + { + if ( (msgType == pEntry->msgType) && (msgId == pEntry->msgId) && (void*)(unsigned long)ctrlId == pEntry->pObject) + { + return pEntry; + } + pEntry++; + } + return 0; +} +#include +#include +c_display::c_display(void* phy_fb, unsigned int display_width, unsigned int display_height, + unsigned int surface_width, unsigned int surface_height, + unsigned int color_bytes, unsigned int surface_cnt, EXTERNAL_GFX_OP* gfx_op) +{ + if (color_bytes != 2 && color_bytes != 4) + { + log_out("Support 16 bits, 32 bits color only!"); + ASSERT(false); + } + m_width = display_width; + m_height = display_height; + m_color_bytes = color_bytes; + m_phy_fb = phy_fb; + m_phy_read_index = m_phy_write_index = 0; + memset(m_surface_group, 0, sizeof(m_surface_group)); + m_surface_index = 0; + m_surface_cnt = surface_cnt; + ASSERT(m_surface_cnt <= SURFACE_CNT_MAX); + + for (int i = 0; i < m_surface_cnt; i++) + { + m_surface_group[i] = phy_fb ? new c_surface(this, surface_width, surface_height, color_bytes) : new c_surface_no_fb(this, surface_width, surface_height, color_bytes, gfx_op); + } +} +c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder) +{ + if(max_zorder >= Z_ORDER_LEVEL_MAX || m_surface_index >= m_surface_cnt) + { + ASSERT(false); + return 0; + } + int i = m_surface_index++; + m_surface_group[i]->set_surface(max_zorder); + return m_surface_group[i]; +} +int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset) +{ + int surface_width = s0->get_width(); + int surface_height = s0->get_height(); + if (offset < 0 || offset > surface_width || y0 < 0 || y0 >= surface_height || + y1 < 0 || y1 >= surface_height || x0 < 0 || x0 >= surface_width || x1 < 0 || x1 >= surface_width) + { + ASSERT(false); + return -1; + } + int width = (x1 - x0 + 1); + if (width < 0 || width > surface_width || width < offset) + { + ASSERT(false); + return -1; + } + x0 = (x0 >= m_width) ? (m_width - 1) : x0; + x1 = (x1 >= m_width) ? (m_width - 1) : x1; + y0 = (y0 >= m_height) ? (m_height - 1) : y0; + y1 = (y1 >= m_height) ? (m_height - 1) : y1; + + if (m_phy_fb) + { + for (int y = y0; y <= y1; y++) + { + //Left surface + char* addr_s = ((char*)(s0->m_fb) + (y * (s0->get_width()) + x0 + offset) * m_color_bytes); + char* addr_d = ((char*)(m_phy_fb)+(y * m_width + x0) * m_color_bytes); + memcpy(addr_d, addr_s, (width - offset) * m_color_bytes); + //Right surface + addr_s = ((char*)(s1->m_fb) + (y * (s1->get_width()) + x0) * m_color_bytes); + addr_d = ((char*)(m_phy_fb)+(y * m_width + x0 + (width - offset)) * m_color_bytes); + memcpy(addr_d, addr_s, offset * m_color_bytes); + } + } + else if(m_color_bytes == 4) + { + void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel; + for (int y = y0; y <= y1; y++) + { + //Left surface + for (int x = x0; x <= (x1 - offset); x++) + { + draw_pixel(x, y, ((unsigned int*)s0->m_fb)[y * m_width + x + offset]); + } + //Right surface + for (int x = x1 - offset; x <= x1; x++) + { + draw_pixel(x, y, ((unsigned int*)s1->m_fb)[y * m_width + x + offset - x1 + x0]); + } + } + } + else if (m_color_bytes == 2) + { + void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel; + for (int y = y0; y <= y1; y++) + { + //Left surface + for (int x = x0; x <= (x1 - offset); x++) + { + draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s0->m_fb)[y * m_width + x + offset])); + } + //Right surface + for (int x = x1 - offset; x <= x1; x++) + { + draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s1->m_fb)[y * m_width + x + offset - x1 + x0])); + } + } + } + m_phy_write_index++; + return 0; +} +void* c_display::get_updated_fb(int* width, int* height, bool force_update) +{ + if (width && height) + { + *width = get_width(); + *height = get_height(); + } + if (force_update) + { + return m_phy_fb; + } + if (m_phy_read_index == m_phy_write_index) + {//No update + return 0; + } + m_phy_read_index = m_phy_write_index; + return m_phy_fb; +} +int c_display::snap_shot(const char* file_name) +{ + if (!m_phy_fb) + { + return -1; + } + unsigned int width = get_width(); + unsigned int height = get_height(); + //16 bits framebuffer + if (m_color_bytes == 2) + { + return build_bmp(file_name, width, height, (unsigned char*)m_phy_fb); + } + //32 bits framebuffer + unsigned short* p_bmp565_data = new unsigned short[width * height]; + unsigned int* p_raw_data = (unsigned int*)m_phy_fb; + for (int i = 0; i < width * height; i++) + { + unsigned int rgb = *p_raw_data++; + p_bmp565_data[i] = GL_RGB_32_to_16(rgb); + } + int ret = build_bmp(file_name, width, height, (unsigned char*)p_bmp565_data); + delete []p_bmp565_data; + return ret; +} +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) +c_rect::c_rect(const c_rect& rect) +{ + SetRect(rect.m_left,rect.m_top,rect.m_right,rect.m_bottom); +} +c_rect& c_rect::operator=(const c_rect& rect) +{ + SetRect(rect.m_left,rect.m_top,rect.m_right,rect.m_bottom); + return *this; +} +void c_rect::SetRect( int Left, int Top, int Right, int Bottom) +{ + m_left = MIN(Left, Right); + m_top = MIN(Top, Bottom); + m_right = MAX(Left, Right); + m_bottom = MAX(Top, Bottom); +} +c_rect c_rect::operator&(const c_rect& rect) const +{ + c_rect dst; + dst.m_left = MAX(m_left, rect.m_left); + dst.m_top = MAX(m_top, rect.m_top); + dst.m_right = MIN(m_right, rect.m_right); + dst.m_bottom = MIN(m_bottom, rect.m_bottom); + if(dst.m_left >= dst.m_right || dst.m_top >= dst.m_bottom) + dst.Empty(); + return dst; +} +void c_rect::Empty() +{ + m_left = m_top = m_right = m_bottom = 0; +} +void c_rect::Offset(int x, int y) +{ + m_left +=x; + m_right +=x; + m_top += y; + m_bottom += y; +} +int c_rect::IsEmpty() const +{ + return m_top == m_bottom || m_left == m_right; +} +int c_rect::PtInRect(int x, int y) const +{ + return x >= m_left && x <= m_right && y >= m_top && y <= m_bottom; +} +int c_rect::operator==(const c_rect& rect) const +{ + return (m_left == rect.m_left) && (m_top==rect.m_top) && + (m_right == rect.m_right) && (m_bottom==rect.m_bottom); +} +#include +#include +#define GL_ROUND_RGB_32(rgb) (rgb & 0xFFF8FCF8) //make RGB32 = RGB16 +c_surface::c_surface(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes) +{ + m_width = width; + m_height = height; + m_color_bytes = color_bytes; + m_display = display; + m_phy_fb = display->m_phy_fb; + m_phy_write_index = &display->m_phy_write_index; + m_fb = 0; + m_top_zorder = m_max_zorder = Z_ORDER_LEVEL_0; + m_is_active = false; + m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height); +} +void c_surface::set_surface(Z_ORDER_LEVEL max_z_order) +{ + m_max_zorder = max_z_order; + if (m_display->m_surface_cnt > 1) + { + m_fb = calloc(m_width * m_height, m_color_bytes); + } + + for(int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++) + {//Top layber fb always be 0 + m_frame_layers[i].fb = (unsigned short*)calloc(m_width * m_height, sizeof(unsigned short)); + ASSERT(0 != m_frame_layers[i].fb); + } +} +void c_surface::draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order) +{ + if (x >= m_width || y >= m_height || x < 0 || y < 0) + { + return; + } + if (z_order > m_max_zorder) + { + ASSERT(false); + return; + } + rgb = GL_ROUND_RGB_32(rgb); + if (z_order == m_max_zorder) + { + return draw_pixel_on_fb(x, y, rgb); + } + if (z_order > m_top_zorder) + { + m_top_zorder = (Z_ORDER_LEVEL)z_order; + } + if (0 == m_frame_layers[z_order].visible_rect.PtInRect(x, y)) + { + ASSERT(false); + return; + } + ((unsigned short*)(m_frame_layers[z_order].fb))[x + y * m_width] = GL_RGB_32_to_16(rgb); + if (z_order == m_top_zorder) + { + return draw_pixel_on_fb(x, y, rgb); + } + bool is_covered = false; + for (int tmp_z_order = Z_ORDER_LEVEL_MAX - 1; tmp_z_order > z_order; tmp_z_order--) + { + if (true == m_frame_layers[tmp_z_order].visible_rect.PtInRect(x, y)) + { + is_covered = true; + break; + } + } + if (!is_covered) + { + draw_pixel_on_fb(x, y, rgb); + } +} +void c_surface::draw_pixel_on_fb(int x, int y, unsigned int rgb) +{ + if (m_fb) + { + (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb); + } + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + if (m_is_active && (x < display_width) && (y < display_height)) + { + if (m_color_bytes == 4) + { + ((unsigned int*)m_phy_fb)[y * (m_display->get_width()) + x] = rgb; + } + else + { + ((unsigned short*)m_phy_fb)[y * (m_display->get_width()) + x] = GL_RGB_32_to_16(rgb); + } + *m_phy_write_index = *m_phy_write_index + 1; + } +} +void c_surface::fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order) +{ + x0 = (x0 < 0) ? 0 : x0; + y0 = (y0 < 0) ? 0 : y0; + x1 = (x1 > (m_width - 1)) ? (m_width - 1) : x1; + y1 = (y1 > (m_height - 1)) ? (m_height - 1) : y1; + rgb = GL_ROUND_RGB_32(rgb); + if (z_order == m_max_zorder) + { + return fill_rect_on_fb(x0, y0, x1, y1, rgb); + } + if (z_order == m_top_zorder) + { + int x, y; + unsigned short *mem_fb; + unsigned int rgb_16 = GL_RGB_32_to_16(rgb); + for (y = y0; y <= y1; y++) + { + x = x0; + mem_fb = &((unsigned short*)m_frame_layers[z_order].fb)[y * m_width + x]; + for (; x <= x1; x++) + { + *mem_fb++ = rgb_16; + } + } + return fill_rect_on_fb(x0, y0, x1, y1, rgb); + } + for (; y0 <= y1; y0++) + { + draw_hline(x0, x1, y0, rgb, z_order); + } +} +void c_surface::fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) +{ + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + if (m_color_bytes == 4) + { + int x; + unsigned int *fb, *phy_fb; + for (; y0 <= y1; y0++) + { + x = x0; + fb = m_fb ? &((unsigned int*)m_fb)[y0 * m_width + x] : 0; + phy_fb = &((unsigned int*)m_phy_fb)[y0 * display_width + x]; + *m_phy_write_index = *m_phy_write_index + 1; + for (; x <= x1; x++) + { + if (fb) + { + *fb++ = rgb; + } + if (m_is_active && (x < display_width) && (y0 < display_height)) + { + *phy_fb++ = rgb; + } + } + } + } + else if(m_color_bytes == 2) + { + int x; + unsigned short *fb, *phy_fb; + rgb = GL_RGB_32_to_16(rgb); + for (; y0 <= y1; y0++) + { + x = x0; + fb = m_fb ? &((unsigned short*)m_fb)[y0 * m_width + x] : 0; + phy_fb = &((unsigned short*)m_phy_fb)[y0 * display_width + x]; + *m_phy_write_index = *m_phy_write_index + 1; + for (; x <= x1; x++) + { + if (fb) + { + *fb++ = rgb; + } + if (m_is_active && (x < display_width) && (y0 < display_height)) + { + *phy_fb++ = rgb; + } + } + } + } +} +unsigned int c_surface::get_pixel(int x, int y, unsigned int z_order) +{ + if (x >= m_width || y >= m_height || x < 0 || y < 0 || + z_order >= Z_ORDER_LEVEL_MAX) + { + ASSERT(false); + return 0; + } + if (z_order == m_max_zorder) + { + if (m_fb) + { + return (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_fb)[y * m_width + x]); + } + else if(m_phy_fb) + { + return (m_color_bytes == 4) ? ((unsigned int*)m_phy_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_phy_fb)[y * m_width + x]); + } + return 0; + } + + unsigned short rgb_16 = ((unsigned short*)(m_frame_layers[z_order].fb))[y * m_width + x]; + return GL_RGB_16_to_32(rgb_16); +} +void c_surface::draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order) +{ + for (;x0 <= x1; x0++) + { draw_pixel(x0, y, rgb, z_order); } +} +void c_surface::draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order) +{ + for (;y0 <= y1; y0++) + { draw_pixel(x, y0, rgb, z_order); } +} +void c_surface::draw_line(int x1, int y1, int x2, int y2, unsigned int rgb, unsigned int z_order) +{ + int dx, dy, e; + dx = x2 - x1; + dy = y2 - y1; + if ((dx >= 0) && (dy >= 0)) + { + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 <= x2; x1++, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1++; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 <= y2; y1++, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1++; e -= dy; } + } + } + } + else if ((dx >= 0) && (dy < 0)) + { + dy = -dy; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 <= x2; x1++, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1--; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 >= y2; y1--, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1++; e -= dy; } + } + } + } + else if ((dx < 0) && (dy >= 0)) + { + dx = -dx; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 >= x2; x1--, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1++; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 <= y2; y1++, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1--; e -= dy; } + } + } + } + else if ((dx < 0) && (dy < 0)) + { + dx = -dx; + dy = -dy; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 >= x2; x1--, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1--; e -= dx; } + } + } + else + { + e = dx - dy / 2; + while (y1-- >= y2) + for(; y1 >= y2; y1--, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1--; e -= dy; } + } + } + } +} +void c_surface::draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size) +{ + for (unsigned int offset = 0; offset < size; offset++) + { + draw_hline(x0 + offset, x1 - offset, y0 + offset, rgb, z_order); + draw_hline(x0 + offset, x1 - offset, y1 - offset, rgb, z_order); + draw_vline(x0 + offset, y0 + offset, y1 - offset, rgb, z_order); + draw_vline(x1 - offset, y0 + offset, y1 - offset, rgb, z_order); + } +} +int c_surface::set_frame_layer_visible_rect(c_rect& rect, unsigned int z_order) +{ + if (rect == m_frame_layers[z_order].visible_rect) + { + return 0; + } + if (rect.m_left < 0 || rect.m_left >= m_width || + rect.m_right < 0 || rect.m_right >= m_width || + rect.m_top < 0 || rect.m_top >= m_height || + rect.m_bottom < 0 || rect.m_bottom >=m_height) + { + ASSERT(false); + return -1; + } + if (!(z_order > Z_ORDER_LEVEL_0 && z_order < Z_ORDER_LEVEL_MAX)) + { + ASSERT(false); + return -2; + } + if (z_order < m_top_zorder) + { + ASSERT(false); + return -3; + } + m_top_zorder = (Z_ORDER_LEVEL)z_order; + + c_rect old_rect = m_frame_layers[z_order].visible_rect; + //Recover the lower layer + int src_zorder = (Z_ORDER_LEVEL)(z_order - 1); + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + for (int y = old_rect.m_top; y <= old_rect.m_bottom; y++) + { + for (int x = old_rect.m_left; x <= old_rect.m_right; x++) + { + if (!rect.PtInRect(x, y)) + { + unsigned int rgb = ((unsigned short*)(m_frame_layers[src_zorder].fb))[x + y * m_width]; + draw_pixel_on_fb(x, y, GL_RGB_16_to_32(rgb)); + } + } + } + m_frame_layers[z_order].visible_rect = rect; + if (rect.IsEmpty()) + { + m_top_zorder = (Z_ORDER_LEVEL)(z_order - 1); + } + return 0; +} +int c_surface::flush_screen(int left, int top, int right, int bottom) +{ + if(left < 0 || left >= m_width || right < 0 || right >= m_width || + top < 0 || top >= m_height || bottom < 0 || bottom >= m_height) + { + ASSERT(false); + } + if(!m_is_active || (0 == m_phy_fb) || (0 == m_fb)) + { + return -1; + } + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + left = (left >= display_width) ? (display_width - 1) : left; + right = (right >= display_width) ? (display_width - 1) : right; + top = (top >= display_height) ? (display_height - 1) : top; + bottom = (bottom >= display_height) ? (display_height - 1) : bottom; + for (int y = top; y < bottom; y++) + { + void* s_addr = (char*)m_fb + ((y * m_width + left) * m_color_bytes); + void* d_addr = (char*)m_phy_fb + ((y * display_width + left) * m_color_bytes); + memcpy(d_addr, s_addr, (right - left) * m_color_bytes); + } + *m_phy_write_index = *m_phy_write_index + 1; + return 0; +} +bool c_surface::is_valid(c_rect rect) +{ + if (rect.m_left < 0 || rect.m_top < 0) + { + return false; + } + if (rect.m_right >= m_width || rect.m_bottom >= m_height) + { + return false; + } + return true; +} +////////////////////////////////////////////////////////////////////////////////////// +void c_surface_no_fb::fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) +{ + if (!m_gfx_op) + { + return; + } + if (m_gfx_op->fill_rect) + { + return m_gfx_op->fill_rect(x0, y0, x1, y1, rgb); + } + if (m_gfx_op->draw_pixel && m_is_active) + { + for (int y = y0; y <= y1; y++) + { + for (int x = x0; x <= x1; x++) + { + m_gfx_op->draw_pixel(x, y, rgb); + } + } + } + if (!m_fb) { return; } + if(m_color_bytes == 4) + { + unsigned int *fb; + for (int y = y0; y <= y1; y++) + { + fb = &((unsigned int*)m_fb)[y0 * m_width + x0]; + for (int x = x0; x <= x1; x++) + { + *fb++ = rgb; + } + } + } + else if (m_color_bytes == 2) + { + unsigned short *fb; + rgb = GL_RGB_32_to_16(rgb); + for (int y = y0; y <= y1; y++) + { + fb = &((unsigned short*)m_fb)[y0 * m_width + x0]; + for (int x = x0; x <= x1; x++) + { + *fb++ = rgb; + } + } + } +} +void c_surface_no_fb::draw_pixel_on_fb(int x, int y, unsigned int rgb) +{ + if (m_gfx_op && m_gfx_op->draw_pixel && m_is_active) + { + m_gfx_op->draw_pixel(x, y, rgb); + } + if (!m_fb) { return; } + if (m_color_bytes == 4) + { + ((unsigned int*)m_fb)[y * m_width + x] = rgb; + } + else if (m_color_bytes == 2) + { + ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb); + } +} + +static const FONT_INFO* s_font_map[FONT_MAX]; +static const BITMAP_INFO* s_bmp_map[BITMAP_MAX]; +static unsigned int s_color_map[COLOR_MAX]; + +int c_theme::add_font(FONT_TYPE index, const FONT_INFO* font) +{ + if (index >= FONT_MAX) + { + ASSERT(false); + return -1; + } + s_font_map[index] = font; + return 0; +} + +const FONT_INFO* c_theme::get_font(FONT_TYPE index) +{ + if (index >= FONT_MAX) + { + ASSERT(false); + return 0; + } + return s_font_map[index]; +} + +int c_theme::add_bitmap(BITMAP_TYPE index, const BITMAP_INFO* bmp) +{ + if (index >= BITMAP_MAX) + { + ASSERT(false); + return -1; + } + s_bmp_map[index] = bmp; + return 0; +} + +const BITMAP_INFO* c_theme::get_bmp(BITMAP_TYPE index) +{ + if (index >= BITMAP_MAX) + { + ASSERT(false); + return 0; + } + return s_bmp_map[index]; +} + +int c_theme::add_color(COLOR_TYPE index, const unsigned int color) +{ + if (index >= COLOR_MAX) + { + ASSERT(false); + return -1; + } + s_color_map[index] = color; + return 0; +} + +const unsigned int c_theme::get_color(COLOR_TYPE index) +{ + if (index >= COLOR_MAX) + { + ASSERT(false); + return 0; + } + return s_color_map[index]; +} +c_wnd::c_wnd(): m_status(STATUS_NORMAL), m_attr(ATTR_VISIBLE), m_parent(0), m_top_child(0), m_prev_sibling(0), m_next_sibling(0), +m_str(0), m_font_color(0), m_bg_color(0), m_resource_id(0), m_z_order(Z_ORDER_LEVEL_0), m_focus_child(0), m_surface(0) +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); +} +int c_wnd::connect(c_wnd *parent, unsigned short resource_id, const char* str, + short x, short y, short width, short height, WND_TREE* p_child_tree ) +{ + if(0 == resource_id) + { + ASSERT(false); + return -1; + } + m_resource_id = resource_id; + set_str(str); + m_parent = parent; + m_status = STATUS_NORMAL; + if (parent) + { + m_z_order = parent->m_z_order; + m_surface = parent->m_surface; + } + if(0 == m_surface) + { + ASSERT(false); + return -2; + } + /* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/ + m_wnd_rect.m_left = x; + m_wnd_rect.m_top = y; + m_wnd_rect.m_right = (x + width - 1); + m_wnd_rect.m_bottom = (y + height - 1); + c_rect rect; + get_screen_rect(rect); + ASSERT(m_surface->is_valid(rect)); + pre_create_wnd(); + if ( 0 != parent ) + { + parent->add_child_2_tail(this); + } + if (load_child_wnd(p_child_tree) >= 0) + { + load_cmd_msg(); + on_init_children(); + } + return 0; +} +int c_wnd::load_child_wnd(WND_TREE *p_child_tree) +{ + if (0 == p_child_tree) + { + return 0; + } + int sum = 0; + WND_TREE* p_cur = p_child_tree; + while(p_cur->p_wnd) + { + if (0 != p_cur->p_wnd->m_resource_id) + {//This wnd has been used! Do not share! + ASSERT(false); + return -1; + } + else + { + p_cur->p_wnd->connect(this, p_cur->resource_id, p_cur->str, + p_cur->x, p_cur->y, p_cur->width, p_cur->height,p_cur->p_child_tree); + } + p_cur++; + sum++; + } + return sum; +} +c_wnd* c_wnd::connect_clone(c_wnd *parent, unsigned short resource_id, const char* str, + short x, short y, short width, short height, WND_TREE* p_child_tree ) +{ + if(0 == resource_id) + { + ASSERT(false); + return 0; + } + c_wnd* wnd = clone(); + wnd->m_resource_id = resource_id; + wnd->set_str(str); + wnd->m_parent = parent; + wnd->m_status = STATUS_NORMAL; + if (parent) + { + wnd->m_z_order = parent->m_z_order; + wnd->m_surface = parent->m_surface; + } + else + { + wnd->m_surface = m_surface; + } + if(0 == wnd->m_surface) + { + ASSERT(false); + return 0; + } + /* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/ + wnd->m_wnd_rect.m_left = x; + wnd->m_wnd_rect.m_top = y; + wnd->m_wnd_rect.m_right = (x + width - 1); + wnd->m_wnd_rect.m_bottom = (y + height - 1); + c_rect rect; + wnd->get_screen_rect(rect); + ASSERT(wnd->m_surface->is_valid(rect)); + wnd->pre_create_wnd(); + + if ( 0 != parent ) + { + parent->add_child_2_tail(wnd); + } + if (wnd->load_clone_child_wnd(p_child_tree) >= 0) + { + wnd->load_cmd_msg(); + wnd->on_init_children(); + } + return wnd; +} +int c_wnd::load_clone_child_wnd(WND_TREE *p_child_tree) +{ + if (0 == p_child_tree) + { + return 0; + } + int sum = 0; + WND_TREE* p_cur = p_child_tree; + while(p_cur->p_wnd) + { + p_cur->p_wnd->connect_clone(this, p_cur->resource_id, p_cur->str, + p_cur->x, p_cur->y, p_cur->width, p_cur->height,p_cur->p_child_tree); + p_cur++; + sum++; + } + return sum; +} +void c_wnd::disconnect() +{ + if (0 == m_resource_id) + { + return; + } + if (0 != m_top_child) + { + c_wnd *child = m_top_child; + c_wnd *next_child = 0; + while (child) + { + next_child = child->m_next_sibling; + child->disconnect(); + child = next_child; + } + } + if (0 != m_parent) + { + m_parent->unlink_child(this); + } + m_focus_child = 0; + m_resource_id = 0; +} +c_wnd* c_wnd::get_wnd_ptr(unsigned short id) const +{ + c_wnd *child = m_top_child; + while ( child ) + { + if ( child->get_id() == id ) + { + break; + } + child = child->m_next_sibling; + } + return child; +} +void c_wnd::set_attr(WND_ATTRIBUTION attr) +{ + m_attr = attr; + if ( ATTR_DISABLED == (attr & ATTR_DISABLED) ) + { + m_status = STATUS_DISABLED; + } + else + { + if (m_status == STATUS_DISABLED) + { + m_status = STATUS_NORMAL; + } + } +} +int c_wnd::is_focus_wnd() const +{ + if ( (m_attr & ATTR_VISIBLE) + && !(m_attr & ATTR_DISABLED) + && (m_attr & ATTR_FOCUS)) + { + return true; + } + else + { + return false; + } +} +void c_wnd::set_wnd_pos(short x, short y, short width, short height) +{ + m_wnd_rect.m_left = x; + m_wnd_rect.m_top = y; + m_wnd_rect.m_right = x + width - 1; + m_wnd_rect.m_bottom = y + height - 1; +} +void c_wnd::get_wnd_rect(c_rect &rect) const +{ + rect = m_wnd_rect; +} +void c_wnd::get_screen_rect(c_rect &rect) const +{ + rect.SetRect(0, 0, (m_wnd_rect.Width() - 1), (m_wnd_rect.Height() - 1)); + wnd2screen(rect); +} +void c_wnd::wnd2screen(int &x, int &y) const +{ + c_wnd *parent = m_parent; + c_rect rect; + x += m_wnd_rect.m_left; + y += m_wnd_rect.m_top; + while ( 0 != parent ) + { + parent->get_wnd_rect(rect); + x += rect.m_left; + y += rect.m_top; + parent = parent->m_parent; + } +} +void c_wnd::wnd2screen(c_rect &rect) const +{ + int l = rect.m_left; + int t = rect.m_top; + wnd2screen(l, t); + int r = (l + rect.Width() - 1); + int b = (t + rect.Height() - 1); + rect.SetRect(l, t, r, b); +} +c_wnd* c_wnd::set_child_focus(c_wnd * focus_child) +{ + ASSERT(0 != focus_child); + ASSERT(focus_child->m_parent == this); + c_wnd *old_focus_child = m_focus_child; + if (focus_child->is_focus_wnd()) + { + if (focus_child != old_focus_child ) + { + if (old_focus_child) + { + old_focus_child->on_kill_focus(); + } + m_focus_child = focus_child; + if (m_parent) + { + m_parent->set_child_focus(this); + } + m_focus_child->on_focus(); + } + } + return m_focus_child; +} +void c_wnd::add_child_2_tail(c_wnd *child) +{ + if( 0 == child )return; + if(child == get_wnd_ptr(child->m_resource_id))return; + if ( 0 == m_top_child ) + { + m_top_child = child; + child->m_prev_sibling = 0; + child->m_next_sibling = 0; + } + else + { + c_wnd *last_child = get_last_child(); + if (0 == last_child) + { + ASSERT(false); + } + last_child->m_next_sibling = child; + child->m_prev_sibling = last_child; + child->m_next_sibling = 0; + } +} +c_wnd* c_wnd::get_last_child() const +{ + if ( 0 == m_top_child ) + { + return 0; + } + c_wnd *child = m_top_child; + while ( child->m_next_sibling) + { + child = child->m_next_sibling; + } + return child; +} +int c_wnd::unlink_child(c_wnd *child) +{ + if ((0 == child) + || (this != child->m_parent)) + { + return -1; + } + if (0 == m_top_child) + { + return -2; + } + int find = false; + c_wnd *tmp_child = m_top_child; + if (tmp_child == child) + { + m_top_child = child->m_next_sibling; + if (0 != child->m_next_sibling) + { + child->m_next_sibling->m_prev_sibling = 0; + } + find = true; + } + else + { + while (tmp_child->m_next_sibling) + { + if (child == tmp_child->m_next_sibling) + { + tmp_child->m_next_sibling = child->m_next_sibling; + if (0 != child->m_next_sibling) + { + child->m_next_sibling->m_prev_sibling = tmp_child; + } + find = true; + break; + } + tmp_child = tmp_child->m_next_sibling; + } + } + if (true == find) + { + if (m_focus_child == child) + { + m_focus_child = 0; + } + child->m_next_sibling = 0; + child->m_prev_sibling = 0; + return 1; + } + else + { + return 0; + } +} +void c_wnd::show_window() +{ + if (ATTR_VISIBLE == (m_attr & ATTR_VISIBLE)) + { + on_paint(); + c_wnd *child = m_top_child; + if ( 0 != child ) + { + while ( child ) + { + child->show_window(); + child = child->m_next_sibling; + } + } + } +} +bool c_wnd::on_touch(int x, int y, TOUCH_ACTION action) +{ + c_rect rect; + x -= m_wnd_rect.m_left; + y -= m_wnd_rect.m_top; + c_wnd* child = m_top_child; + c_wnd* target_wnd = 0; + int target_z_order = Z_ORDER_LEVEL_0; + while (child) + { + if (ATTR_VISIBLE == (child->m_attr & ATTR_VISIBLE)) + { + child->get_wnd_rect(rect); + if (true == rect.PtInRect(x, y) || child->m_attr & ATTR_MODAL) + { + if (true == child->is_focus_wnd()) + { + if (child->m_z_order >= target_z_order) + { + target_wnd = child; + target_z_order = child->m_z_order; + } + } + } + } + child = child->m_next_sibling; + } + if (target_wnd == 0) + { + return false; + } + return target_wnd->on_touch(x, y, action); +} +bool c_wnd::on_key(KEY_TYPE key) +{ + ASSERT(key == KEY_FORWARD || key == KEY_BACKWARD || key == KEY_ENTER); + // Find current focus wnd. + c_wnd* old_focus_wnd = m_focus_child; + while (m_focus_child && m_focus_child->m_focus_child) + { + old_focus_wnd = m_focus_child->m_focus_child; + } + if (old_focus_wnd && !old_focus_wnd->on_key(key)) + { + return true; + } + // Default moving focus(Default handle KEY_FOWARD/KEY_BACKWARD) + if (key == KEY_ENTER) + { + return true; + } + if (!old_focus_wnd) + {// No current focus wnd, new one. + c_wnd *child = m_top_child; + c_wnd *new_focus_wnd = 0; + while (child) + { + if (ATTR_VISIBLE == (child->m_attr & ATTR_VISIBLE)) + { + if (true == child->is_focus_wnd()) + { + new_focus_wnd = child; + new_focus_wnd->m_parent->set_child_focus(new_focus_wnd); + child = child->m_top_child; + continue; + } + } + child = child->m_next_sibling; + } + return true; + } + // Move focus from old wnd to next wnd + c_wnd* next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_next_sibling : old_focus_wnd->m_prev_sibling; + while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd())) + {// Search neighbor of old focus wnd + next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling; + } + if (!next_focus_wnd) + {// Search whole brother wnd + next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_parent->m_top_child : old_focus_wnd->m_parent->get_last_child(); + while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd())) + { + next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling; + } + } + if (next_focus_wnd) + { + next_focus_wnd->m_parent->set_child_focus(next_focus_wnd); + } + return true; +} +void c_wnd::notify_parent(unsigned int msg_id, int param) +{ + if (!m_parent) + { + return; + } + const GL_MSG_ENTRY* entry = m_parent->FindMsgEntry(m_parent->GetMSgEntries(), MSG_TYPE_WND, msg_id, m_resource_id); + if (0 == entry) + { + return; + } + MSGFUNCS msg_funcs; + msg_funcs.func = entry->func; + switch (entry->callbackType) + { + case MSG_CALLBACK_VV: + (m_parent->*msg_funcs.func)(); + break; + case MSG_CALLBACK_VVL: + (m_parent->*msg_funcs.func_vvl)(param); + break; + case MSG_CALLBACK_VWV: + (m_parent->*msg_funcs.func_vwv)(m_resource_id); + break; + case MSG_CALLBACK_VWL: + (m_parent->*msg_funcs.func_vwl)(m_resource_id, param); + break; + default: + ASSERT(false); + break; + } +} +#include +#include +#define BUFFER_LEN 16 +unsigned char s_utf8_length_table[256] = +{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 +}; +inline static int get_utf8_code(const char* s, unsigned int& output_utf8_code) +{ + unsigned char* us = (unsigned char*)s; + int utf8_bytes = s_utf8_length_table[*us]; + switch (utf8_bytes) + { + case 1: + output_utf8_code = *us; + break; + case 2: + output_utf8_code = (*us << 8) | (*(us + 1)); + break; + case 3: + output_utf8_code = (*us << 16) | ((*(us + 1)) << 8) | *(us + 2); + break; + case 4: + output_utf8_code = (*us << 24) | ((*(us + 1)) << 16) | (*(us + 2) << 8) | *(us + 3); + break; + default: + ASSERT(false); + break; + } + return utf8_bytes; +} +void c_word::draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + char buf[BUFFER_LEN]; + value_2_string(value, dot_position, buf, BUFFER_LEN); + draw_string_in_rect(surface, z_order, buf, rect, font, font_color, bg_color, align_type); +} +void c_word::draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + char buf[BUFFER_LEN]; + value_2_string(value, dot_position, buf, BUFFER_LEN); + draw_string(surface, z_order, buf, x, y, font, font_color, bg_color, align_type); +} +void c_word::draw_string_in_rect(c_surface* surface, int z_order, const char *s, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + if(0 == s) + { + return; + } + int x, y; + get_string_pos(s, font, rect, align_type, x, y); + draw_string(surface, z_order, s, rect.m_left + x, rect.m_top + y, font, font_color, bg_color, ALIGN_LEFT); +} +void c_word::draw_string(c_surface* surface, int z_order, const char *s, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + if (0 == s) + { + return; + } + int offset = 0; + unsigned int utf8_code; + while (*s) + { + s += get_utf8_code(s, utf8_code); + offset += draw_single_char(surface, z_order, utf8_code, (x + offset), y, font, font_color, bg_color); + } +} +void c_word::value_2_string(int value, int dot_position, char* buf, int len) +{ + memset(buf, 0, len); + switch (dot_position) + { + case 0: + sprintf(buf, "%d", value); + break; + case 1: + sprintf(buf, "%.1f", value*1.0 / 10); + break; + case 2: + sprintf(buf, "%.2f", value*1.0 / 100); + break; + case 3: + sprintf(buf, "%.3f", value*1.0 / 1000); + break; + default: + ASSERT(false); + break; + } +} +const LATTICE* c_word::get_lattice(const FONT_INFO* font, unsigned int utf8_code) +{ + int first = 0; + int last = font->count - 1; + int middle = (first + last) / 2; + while (first <= last) + { + if (font->lattice_array[middle].utf8_code < utf8_code) + first = middle + 1; + else if (font->lattice_array[middle].utf8_code == utf8_code) + { + return &font->lattice_array[middle]; + } + else + { + last = middle - 1; + } + middle = (first + last) / 2; + } + return 0; +} +int c_word::draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color) +{ + unsigned int error_color = 0xFFFFFFFF; + if (font) + { + const LATTICE* p_lattice = get_lattice(font, utf8_code); + if (p_lattice) + { + draw_lattice(surface, z_order, x, y, p_lattice->width, font->height, p_lattice->pixel_gray_array, font_color, bg_color); + return p_lattice->width; + } + } + else + { + error_color = GL_RGB(255, 0, 0); + } + + //lattice/font not found, draw "X" + int len = 16; + for (int y_ = 0; y_ < len; y_++) + { + for (int x_ = 0; x_ < len; x_++) + { + int diff = (x_ - y_); + int sum = (x_ + y_); + (diff == 0 || diff == -1 || diff == 1 || sum == len || sum == (len - 1) || sum == (len + 1)) ? + surface->draw_pixel((x + x_), (y + y_), error_color, z_order) : surface->draw_pixel((x + x_), (y + y_), 0, z_order); + } + } + return len; +} +void c_word::draw_lattice(c_surface* surface, int z_order, int x, int y, int width, int height, + const unsigned char* p_data, unsigned int font_color, unsigned int bg_color) +{ + unsigned int r, g, b, rgb; + unsigned char blk_value = *p_data++; + unsigned char blk_cnt = *p_data++; + b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8; + g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8; + r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8; + rgb = GL_RGB(r, g, b); + for (int y_ = 0; y_ < height; y_++) + { + for (int x_ = 0; x_ < width; x_++) + { + ASSERT(blk_cnt); + if (0x00 == blk_value) + { + if (GL_ARGB_A(bg_color)) + { + surface->draw_pixel(x + x_, y + y_, bg_color, z_order); + } + } + else + { + surface->draw_pixel((x + x_), (y + y_), rgb, z_order); + } + if (--blk_cnt == 0) + {//reload new block + blk_value = *p_data++; + blk_cnt = *p_data++; + b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8; + g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8; + r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8; + rgb = GL_RGB(r, g, b); + } + } + } +} +int c_word::get_str_size(const char *s, const FONT_INFO* font, int& width, int& height) +{ + if(0 == s || 0 == font) + { + width = height = 0; + return -1; + } + int lattice_width = 0; + unsigned int utf8_code; + int utf8_bytes; + while (*s) + { + utf8_bytes = get_utf8_code(s, utf8_code); + const LATTICE* p_lattice = get_lattice(font, utf8_code); + lattice_width += p_lattice?p_lattice->width:font->height; + s += utf8_bytes; + } + width = lattice_width; + height = font->height; + return 0; +} +void c_word::get_string_pos(const char *s, const FONT_INFO* font, c_rect rect, unsigned int align_type, int &x, int &y) +{ + int x_size, y_size; + get_str_size(s, font, x_size, y_size); + int height = rect.m_bottom - rect.m_top + 1; + int width = rect.m_right - rect.m_left + 1; + x = y = 0; + switch (align_type & ALIGN_HMASK) + { + case ALIGN_HCENTER: + //m_text_org_x=0 + if (width > x_size) + { + x = (width - x_size)/2; + } + break; + case ALIGN_LEFT: + x = 0; + break; + case ALIGN_RIGHT: + //m_text_org_x=0 + if (width > x_size) + { + x = width - x_size; + } + break; + default: + ASSERT(0); + break; + } + switch (align_type & ALIGN_VMASK) + { + case ALIGN_VCENTER: + //m_text_org_y=0 + if (height > y_size) + { + y = (height - y_size)/2; + } + break; + case ALIGN_TOP: + y = 0; + break; + case ALIGN_BOTTOM: + //m_text_org_y=0 + if (height > y_size) + { + y = height - y_size; + } + break; + default: + ASSERT(0); + break; + } +} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define MAX_TIMER_CNT 10 +#define TIMER_UNIT 50//ms +static void(*do_assert)(const char* file, int line); +static void(*do_log_out)(const char* log); +void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log)) +{ + do_assert = my_assert; + do_log_out = my_log_out; +} +void _assert(const char* file, int line) +{ + if(do_assert) + { + do_assert(file, line); + } + else + { + printf("assert@ file:%s, line:%d, error no: %d\n", file, line, errno); + } +} +void log_out(const char* log) +{ + if (do_log_out) + { + do_log_out(log); + } + else + { + printf("%s", log); + fflush(stdout); + } +} +typedef struct _timer_manage +{ + struct _timer_info + { + int state; /* on or off */ + int interval; + int elapse; /* 0~interval */ + void (* timer_proc) (void* ptmr, void* parg); + }timer_info[MAX_TIMER_CNT]; + void (* old_sigfunc)(int); + void (* new_sigfunc)(int); +}_timer_manage_t; +static struct _timer_manage timer_manage; +static void* timer_routine(void*) +{ + int i; + while(true) + { + for(i = 0; i < MAX_TIMER_CNT; i++) + { + if(timer_manage.timer_info[i].state == 0) + { + continue; + } + timer_manage.timer_info[i].elapse++; + if(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval) + { + timer_manage.timer_info[i].elapse = 0; + timer_manage.timer_info[i].timer_proc(0, 0); + } + } + usleep(1000 * TIMER_UNIT); + } + return NULL; +} +static int init_mul_timer() +{ + static bool s_is_init = false; + if(s_is_init == true) + { + return 0; + } + memset(&timer_manage, 0, sizeof(struct _timer_manage)); + pthread_t pid; + pthread_create(&pid, NULL, timer_routine, NULL); + s_is_init = true; + return 1; +} +static int set_a_timer(int interval, void (* timer_proc) (void* ptmr, void* parg)) +{ + init_mul_timer(); + int i; + if(timer_proc == NULL || interval <= 0) + { + return (-1); + } + for(i = 0; i < MAX_TIMER_CNT; i++) + { + if(timer_manage.timer_info[i].state == 1) + { + continue; + } + memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i])); + timer_manage.timer_info[i].timer_proc = timer_proc; + timer_manage.timer_info[i].interval = interval; + timer_manage.timer_info[i].elapse = 0; + timer_manage.timer_info[i].state = 1; + break; + } + if(i >= MAX_TIMER_CNT) + { + ASSERT(false); + return (-1); + } + return (i); +} +typedef void (*EXPIRE_ROUTINE)(void* arg); +EXPIRE_ROUTINE s_expire_function; +static c_fifo s_real_timer_fifo; +static void* real_timer_routine(void*) +{ + char dummy; + while(1) + { + if(s_real_timer_fifo.read(&dummy, 1) > 0) + { + if(s_expire_function)s_expire_function(0); + } + else + { + ASSERT(false); + } + } + return 0; +} +static void expire_real_timer(int sigo) +{ + char dummy = 0x33; + if(s_real_timer_fifo.write(&dummy, 1) <= 0) + { + ASSERT(false); + } +} +void start_real_timer(void (*func)(void* arg)) +{ + if(NULL == func) + { + return; + } + s_expire_function = func; + signal(SIGALRM, expire_real_timer); + struct itimerval value, ovalue; + value.it_value.tv_sec = 0; + value.it_value.tv_usec = REAL_TIME_TASK_CYCLE_MS * 1000; + value.it_interval.tv_sec = 0; + value.it_interval.tv_usec = REAL_TIME_TASK_CYCLE_MS * 1000; + setitimer(ITIMER_REAL, &value, &ovalue); + static pthread_t s_pid; + if(s_pid == 0) + { + pthread_create(&s_pid, NULL, real_timer_routine, NULL); + } +} +unsigned int get_cur_thread_id() +{ + return (unsigned long)pthread_self(); +} +void register_timer(int milli_second,void func(void* ptmr, void* parg)) +{ + set_a_timer(milli_second/TIMER_UNIT,func); +} +long get_time_in_second() +{ + return time(NULL); /* + 8*60*60*/ +} +T_TIME get_time() +{ + T_TIME ret = {0}; + struct tm *fmt; + time_t timer; + timer = get_time_in_second(); + fmt = localtime(&timer); + ret.year = fmt->tm_year + 1900; + ret.month = fmt->tm_mon + 1; + ret.day = fmt->tm_mday; + ret.hour = fmt->tm_hour; + ret.minute = fmt->tm_min; + ret.second = fmt->tm_sec; + return ret; +} +T_TIME second_to_day(long second) +{ + T_TIME ret = {0}; + struct tm *fmt; + fmt = localtime(&second); + ret.year = fmt->tm_year + 1900; + ret.month = fmt->tm_mon + 1; + ret.day = fmt->tm_mday; + ret.hour = fmt->tm_hour; + ret.minute = fmt->tm_min; + ret.second = fmt->tm_sec; + return ret; +} +void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg) +{ + pthread_create((pthread_t*)thread_id, (pthread_attr_t const*)attr, start_routine, arg); +} +void thread_sleep(unsigned int milli_seconds) +{ + usleep(milli_seconds * 1000); +} +typedef struct { + unsigned short bfType; + unsigned int bfSize; + unsigned short bfReserved1; + unsigned short bfReserved2; + unsigned int bfOffBits; +}__attribute__((packed))FileHead; +typedef struct{ + unsigned int biSize; + int biWidth; + int biHeight; + unsigned short biPlanes; + unsigned short biBitCount; + unsigned int biCompress; + unsigned int biSizeImage; + int biXPelsPerMeter; + int biYPelsPerMeter; + unsigned int biClrUsed; + unsigned int biClrImportant; + unsigned int biRedMask; + unsigned int biGreenMask; + unsigned int biBlueMask; +}__attribute__((packed))Infohead; +int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data) +{ + FileHead bmp_head; + Infohead bmp_info; + int size = width * height * 2; + //initialize bmp head. + bmp_head.bfType = 0x4d42; + bmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead); + bmp_head.bfReserved1 = bmp_head.bfReserved2 = 0; + bmp_head.bfOffBits = bmp_head.bfSize - size; + //initialize bmp info. + bmp_info.biSize = 40; + bmp_info.biWidth = width; + bmp_info.biHeight = height; + bmp_info.biPlanes = 1; + bmp_info.biBitCount = 16; + bmp_info.biCompress = 3; + bmp_info.biSizeImage = size; + bmp_info.biXPelsPerMeter = 0; + bmp_info.biYPelsPerMeter = 0; + bmp_info.biClrUsed = 0; + bmp_info.biClrImportant = 0; + //RGB565 + bmp_info.biRedMask = 0xF800; + bmp_info.biGreenMask = 0x07E0; + bmp_info.biBlueMask = 0x001F; + //copy the data + FILE *fp; + if(!(fp=fopen(filename,"wb"))) + { + return -1; + } + fwrite(&bmp_head, 1, sizeof(FileHead),fp); + fwrite(&bmp_info, 1, sizeof(Infohead),fp); + //fwrite(data, 1, size, fp);//top <-> bottom + for (int i = (height - 1); i >= 0; --i) + { + fwrite(&data[i * width * 2], 1, width * 2, fp); + } + + fclose(fp); + return 0; +} +c_fifo::c_fifo() +{ + m_head = m_tail = 0; + m_read_sem = malloc(sizeof(sem_t)); + m_write_mutex = malloc(sizeof(pthread_mutex_t)); + + sem_init((sem_t*)m_read_sem, 0, 0); + pthread_mutex_init((pthread_mutex_t*)m_write_mutex, 0); +} +int c_fifo::read(void* buf, int len) +{ + unsigned char* pbuf = (unsigned char*)buf; + int i = 0; + while(i < len) + { + if (m_tail == m_head) + {//empty + sem_wait((sem_t*)m_read_sem); + continue; + } + *pbuf++ = m_buf[m_head]; + m_head = (m_head + 1) % FIFO_BUFFER_LEN; + i++; + } + if(i != len) + { + ASSERT(false); + } + return i; +} +int c_fifo::write(void* buf, int len) +{ + unsigned char* pbuf = (unsigned char*)buf; + int i = 0; + int tail = m_tail; + pthread_mutex_lock((pthread_mutex_t*)m_write_mutex); + while(i < len) + { + if ((m_tail + 1) % FIFO_BUFFER_LEN == m_head) + {//full, clear data has been written; + m_tail = tail; + log_out("Warning: fifo full\n"); + pthread_mutex_unlock((pthread_mutex_t*)m_write_mutex); + return 0; + } + m_buf[m_tail] = *pbuf++; + m_tail = (m_tail + 1) % FIFO_BUFFER_LEN; + i++; + } + pthread_mutex_unlock((pthread_mutex_t*)m_write_mutex); + if(i != len) + { + ASSERT(false); + } + else + { + sem_post((sem_t*)m_read_sem); + } + return i; +} +#include +#include +#include +#include +#include +typedef void(*ANDROID_PLAY_WAV)(const char* fileName); +ANDROID_PLAY_WAV gAndroidPlayWav; +typedef struct +{ + AUDIO_TYPE type; +}AUDIO_REQUEST; +static c_fifo s_request_fifo; +static void* render_thread(void* param) +{ + while (true) + { + AUDIO_REQUEST request; + s_request_fifo.read(&request, sizeof(request)); + + if (AUDIO_MAX <= request.type) + { + continue; + } + if(gAndroidPlayWav) + { + gAndroidPlayWav("heart_beat.wav"); + } + } +} +void c_audio::init() +{ + static bool s_flag = false; + if (s_flag) + { + return; + } + unsigned long pid; + create_thread(&pid, 0, render_thread, 0); + s_flag = true; +} +int c_audio::play(AUDIO_TYPE type) +{ + if (AUDIO_MAX <= type) + { + return -1; + } + init(); + AUDIO_REQUEST request; + request.type = type; + s_request_fifo.write(&request, sizeof(request)); + return 0; +} +void c_button::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); +} +void c_button::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_button::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +bool c_button::on_touch(int x, int y, TOUCH_ACTION action) +{ + if (action == TOUCH_DOWN) + { + m_parent->set_child_focus(this); + m_status = STATUS_PUSHED; + on_paint(); + } + else + { + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_BN_CLICKED, 0); + } + return true; +} +bool c_button::on_key(KEY_TYPE key) +{ + if (key == KEY_ENTER) + { + notify_parent(GL_BN_CLICKED, 0); + return false;// Do not handle KEY_ENTER by other wnd. + } + return true;// Handle KEY_FOWARD/KEY_BACKWARD by parent wnd. +} +void c_button::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + case STATUS_FOCUSED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + default: + ASSERT(false); + break; + } +} +DIALOG_ARRAY c_dialog::ms_the_dialogs[SURFACE_CNT_MAX]; +void c_dialog::pre_create_wnd() +{ + m_attr = WND_ATTRIBUTION(0);// no focus/visible + m_z_order = Z_ORDER_LEVEL_1; + m_bg_color = GL_RGB(33, 42, 53); +} +void c_dialog::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + m_surface->fill_rect(rect, m_bg_color, m_z_order); + if (m_str) + { + c_word::draw_string(m_surface, m_z_order, m_str, rect.m_left+35, rect.m_top, c_theme::get_font(FONT_DEFAULT), GL_RGB(255, 255, 255), GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + } +} +c_dialog* c_dialog::get_the_dialog(c_surface* surface) +{ + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + return ms_the_dialogs[i].dialog; + } + } + return 0; +} +int c_dialog::open_dialog(c_dialog* p_dlg, bool modal_mode) +{ + if (0 == p_dlg) + { + ASSERT(false); + return 0; + } + c_dialog* cur_dlg = get_the_dialog(p_dlg->get_surface()); + if (cur_dlg == p_dlg) + { + return 1; + } + if(cur_dlg) + { + cur_dlg->set_attr(WND_ATTRIBUTION(0)); + } + c_rect rc; + p_dlg->get_screen_rect(rc); + p_dlg->get_surface()->set_frame_layer_visible_rect(rc, Z_ORDER_LEVEL_1); + p_dlg->set_attr(modal_mode ? (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL) : (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)); + p_dlg->show_window(); + p_dlg->set_me_the_dialog(); + return 1; +} +int c_dialog::close_dialog(c_surface* surface) +{ + c_dialog* dlg = get_the_dialog(surface); + if (0 == dlg) + { + return 0; + } + c_rect rc; + + dlg->set_attr(WND_ATTRIBUTION(0)); + surface->set_frame_layer_visible_rect(rc, dlg->m_z_order); + //clear the dialog + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + ms_the_dialogs[i].dialog = 0; + return 1; + } + } + ASSERT(false); + return -1; +} +int c_dialog::set_me_the_dialog() +{ + c_surface* surface = get_surface(); + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + ms_the_dialogs[i].dialog = this; + return 0; + } + } + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == 0) + { + ms_the_dialogs[i].dialog = this; + if(this) + { + ms_the_dialogs[i].surface = surface; + } + return 1; + } + } + ASSERT(false); + return -2; +} +#include +#define IDD_KEY_BOARD 0x1 +GL_BEGIN_MESSAGE_MAP(c_edit) +ON_KEYBORAD_UPDATE(IDD_KEY_BOARD, c_edit::on_key_board_click) +GL_END_MESSAGE_MAP() +static c_keyboard s_keyboard; +void c_edit::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_kb_style = STYLE_ALL_BOARD; + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); + memset(m_str_input, 0, sizeof(m_str_input)); + memset(m_str, 0, sizeof(m_str)); + set_text(c_wnd::m_str); +} +void c_edit::set_text(const char* str) +{ + if (str != 0 && strlen(str) < sizeof(m_str)) + { + strcpy(m_str, str); + } +} +bool c_edit::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return true; +} +void c_edit::on_touch_down(int x, int y) +{ + c_rect kb_rect_relate_2_edit_parent; + s_keyboard.get_wnd_rect(kb_rect_relate_2_edit_parent); + kb_rect_relate_2_edit_parent.m_left += m_wnd_rect.m_left; + kb_rect_relate_2_edit_parent.m_right += m_wnd_rect.m_left; + kb_rect_relate_2_edit_parent.m_top += m_wnd_rect.m_top; + kb_rect_relate_2_edit_parent.m_bottom += m_wnd_rect.m_top; + if (m_wnd_rect.PtInRect(x, y)) + {//click edit box + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } + } + else if (kb_rect_relate_2_edit_parent.PtInRect(x,y)) + {//click key board + c_wnd::on_touch(x, y, TOUCH_DOWN); + } + else + { + if (STATUS_PUSHED == m_status) + { + m_status = STATUS_FOCUSED; + on_paint(); + } + } +} +void c_edit::on_touch_up(int x, int y) +{ + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + if (m_wnd_rect.PtInRect(x,y)) + {//click edit box + m_status = STATUS_FOCUSED; + on_paint(); + } + else + { + c_wnd::on_touch(x, y, TOUCH_UP); + } + } +} +void c_edit::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_edit::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +void c_edit::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + c_rect empty_rect; + empty_rect.Empty(); + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + s_keyboard.disconnect(); + m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + s_keyboard.disconnect(); + m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); + show_keyboard(); + } + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_PUSHED), m_parent->get_z_order()); + m_surface->draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_BORDER), m_parent->get_z_order(), 2); + strlen(m_str_input) ? c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str_input, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER) : + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + break; + default: + ASSERT(false); + } +} +void c_edit::show_keyboard() +{ + s_keyboard.connect(this, IDD_KEY_BOARD, m_kb_style); + c_rect kb_rect; + s_keyboard.get_screen_rect(kb_rect); + m_surface->set_frame_layer_visible_rect(kb_rect, s_keyboard.get_z_order()); + s_keyboard.show_window(); +} +void c_edit::on_key_board_click(unsigned int ctrl_id, long param) +{ + switch (param) + { + case CLICK_CHAR: + strcpy(m_str_input, s_keyboard.get_str()); + on_paint(); + break; + case CLICK_ENTER: + if (strlen(m_str_input)) + { + memcpy(m_str, m_str_input, sizeof(m_str_input)); + } + m_status = STATUS_FOCUSED; + on_paint(); + break; + case CLICK_ESC: + memset(m_str_input, 0, sizeof(m_str_input)); + m_status = STATUS_FOCUSED; + on_paint(); + break; + default: + ASSERT(false); + break; + } +} +#include +//#define SWIPE_STEP 300//for arm +#define SWIPE_STEP 10//for PC & ANDROID +#define MOVE_THRESHOLD 10 +c_gesture::c_gesture(c_slide_group* group) +{ + m_slide_group = group; + m_state = TOUCH_IDLE; + m_down_x = m_down_y = m_move_x = m_move_y = 0; +} +bool c_gesture::handle_swipe(int x, int y, TOUCH_ACTION action) +{ + if(action == TOUCH_DOWN)//MOUSE_LBUTTONDOWN + { + if(m_state == TOUCH_IDLE) + { + m_state = TOUCH_MOVE; + m_move_x = m_down_x = x; + return true; + } + else//TOUCH_MOVE + { + return on_move(x); + } + } + else if(action == TOUCH_UP)//MOUSE_LBUTTONUP + { + if(m_state == TOUCH_MOVE) + { + m_state = TOUCH_IDLE; + return on_swipe(x); + } + else + { + return false; + //ASSERT(false); + } + } + return true; +} +bool c_gesture::on_move(int x) +{ + if (m_slide_group == 0) + { + return true; + } + if (abs(x - m_move_x) < MOVE_THRESHOLD) + { + return false; + } + m_slide_group->disabel_all_slide(); + m_move_x = x; + if ((m_move_x - m_down_x) > 0) + { + move_right(); + } + else + { + move_left(); + } + return false; +} +bool c_gesture::on_swipe(int x) +{ + if (m_slide_group == 0) + { + return true; + } + if ((m_down_x == m_move_x) && (abs(x - m_down_x) < MOVE_THRESHOLD)) + { + return true; + } + m_slide_group->disabel_all_slide(); + int page = -1; + m_move_x = x; + if ((m_move_x - m_down_x) > 0) + { + page = swipe_right(); + } + else + { + page = swipe_left(); + } + if (page >= 0) + { + m_slide_group->set_active_slide(page); + } + else + { + m_slide_group->set_active_slide(m_slide_group->get_active_slide_index(), false); + } + return false; +} +int c_gesture::swipe_left() +{ + if (m_slide_group == 0) + { + return -1; + } + int index = m_slide_group->get_active_slide_index(); + if((index + 1) >= MAX_PAGES || + m_slide_group->get_slide(index + 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return -2; + } + c_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + if (s1->get_display() != s2->get_display()) + { + return -3; + } + int step = m_down_x - m_move_x; + c_rect rc; + m_slide_group->get_screen_rect(rc); + while(step < rc.Width()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step); + step += SWIPE_STEP; + } + if (step != rc.Width()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, rc.Width()); + } + return (index + 1); +} +int c_gesture::swipe_right() +{ + if (m_slide_group == 0) + { + return -1; + } + int index = m_slide_group->get_active_slide_index(); + if(index <= 0 || + m_slide_group->get_slide(index - 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return -2; + } + c_surface* s1 = m_slide_group->get_slide(index -1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + if (s1->get_display() != s2->get_display()) + { + return -3; + } + c_rect rc; + m_slide_group->get_screen_rect(rc); + int step = rc.Width() - (m_move_x - m_down_x); + while(step > 0) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step); + step -= SWIPE_STEP; + } + if (step != 0) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, 0); + } + return (index - 1); +} +void c_gesture::move_left() +{ + int index = m_slide_group->get_active_slide_index(); + if((index + 1) >= MAX_PAGES || + m_slide_group->get_slide(index + 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return; + } + c_surface* s1 = m_slide_group->get_slide(index +1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + c_rect rc; + m_slide_group->get_screen_rect(rc); + if(s1->get_display() == s2->get_display()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (m_down_x - m_move_x)); + } +} +void c_gesture::move_right() +{ + int index = m_slide_group->get_active_slide_index(); + if(index <= 0 || + m_slide_group->get_slide(index - 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return; + } + c_surface* s1 = m_slide_group->get_slide(index -1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + c_rect rc; + m_slide_group->get_screen_rect(rc); + if(s1->get_display() == s2->get_display()) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (rc.Width() - (m_move_x - m_down_x))); + } +} +#include +//Changing key width/height will change the width/height of keyboard +#define KEY_WIDTH 65 +#define KEY_HEIGHT 38 +#define KEYBOARD_WIDTH ((KEY_WIDTH + 2) * 10) +#define KEYBOARD_HEIGHT ((KEY_HEIGHT + 2) * 4) +#define NUM_BOARD_WIDTH ((KEY_WIDTH + 2) * 4) +#define NUM_BOARD_HEIGHT ((KEY_HEIGHT + 2) * 4) +#define CAPS_WIDTH (KEY_WIDTH * 3 / 2) +#define DEL_WIDTH (KEY_WIDTH * 3 / 2 + 1) +#define ESC_WIDTH (KEY_WIDTH * 2 + 2) +#define SWITCH_WIDTH (KEY_WIDTH * 3 / 2 ) +#define SPACE_WIDTH (KEY_WIDTH * 3 + 2 * 2) +#define DOT_WIDTH (KEY_WIDTH * 3 / 2 + 3) +#define ENTER_WIDTH (KEY_WIDTH * 2 + 2) +#define POS_X(c) ((KEY_WIDTH * c) + (c + 1) * 2) +#define POS_Y(r) ((KEY_HEIGHT * r) + (r + 1) * 2) +static c_keyboard_button s_button_0,s_button_1, s_button_2, s_button_3, s_button_4, s_button_5, s_button_6, s_button_7, s_button_8, s_button_9; +static c_keyboard_button s_button_A, s_button_B, s_button_C, s_button_D, s_button_E, s_button_F, s_button_G, s_button_H, s_button_I, s_button_J; +static c_keyboard_button s_button_K, s_button_L, s_button_M, s_button_N, s_button_O, s_button_P, s_button_Q, s_button_R, s_button_S, s_button_T; +static c_keyboard_button s_button_U, s_button_V, s_button_W, s_button_X, s_button_Y, s_button_Z; +static c_keyboard_button s_button_dot, s_button_caps, s_button_space, s_button_enter, s_button_del, s_button_esc, s_button_num_switch; +WND_TREE g_key_board_children[] = +{ + //Row 1 + {&s_button_Q, 'Q', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_W, 'W', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_E, 'E', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_R, 'R', 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_T, 'T', 0, POS_X(4), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_Y, 'Y', 0, POS_X(5), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_U, 'U', 0, POS_X(6), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_I, 'I', 0, POS_X(7), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_O, 'O', 0, POS_X(8), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_P, 'P', 0, POS_X(9), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + //Row 2 + {&s_button_A, 'A', 0, ((KEY_WIDTH / 2) + POS_X(0)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_S, 'S', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_D, 'D', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_F, 'F', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_G, 'G', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_H, 'H', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_J, 'J', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_K, 'K', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_L, 'L', 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + //Row 3 + {&s_button_caps, 0x14, 0, POS_X(0), POS_Y(2), CAPS_WIDTH, KEY_HEIGHT}, + {&s_button_Z, 'Z', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_X, 'X', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_C, 'C', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_V, 'V', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_B, 'B', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_N, 'N', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_M, 'M', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_del, 0x7F, 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(2), DEL_WIDTH, KEY_HEIGHT}, + //Row 4 + {&s_button_esc, 0x1B, 0, POS_X(0), POS_Y(3), ESC_WIDTH, KEY_HEIGHT}, + {&s_button_num_switch, 0x90, 0, POS_X(2), POS_Y(3), SWITCH_WIDTH, KEY_HEIGHT}, + {&s_button_space, ' ', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(3), SPACE_WIDTH, KEY_HEIGHT}, + {&s_button_dot, '.', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(3), DOT_WIDTH, KEY_HEIGHT}, + {&s_button_enter, '\n', 0, POS_X(8), POS_Y(3), ENTER_WIDTH, KEY_HEIGHT}, + {0,0,0,0,0,0,0} +}; +WND_TREE g_number_board_children[] = +{ + {&s_button_1, '1', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_2, '2', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_3, '3', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_del, 0x7F, 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT * 2 + 2}, + {&s_button_4, '4', 0, POS_X(0), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_5, '5', 0, POS_X(1), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_6, '6', 0, POS_X(2), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_7, '7', 0, POS_X(0), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_8, '8', 0, POS_X(1), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_9, '9', 0, POS_X(2), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_enter,'\n', 0, POS_X(3), POS_Y(2), KEY_WIDTH, KEY_HEIGHT * 2 + 2}, + {&s_button_esc, 0x1B, 0, POS_X(0), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_0, '0', 0, POS_X(1), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_dot, '.', 0, POS_X(2), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {0,0,0,0,0,0,0} +}; +GL_BEGIN_MESSAGE_MAP(c_keyboard) +ON_GL_BN_CLICKED('A', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('B', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('C', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('D', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('E', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('F', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('G', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('H', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('I', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('J', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('K', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('L', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('M', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('N', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('O', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('P', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Q', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('R', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('S', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('T', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('U', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('V', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('W', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('X', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Y', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Z', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('0', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('1', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('2', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('3', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('4', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('5', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('6', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('7', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('8', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('9', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED(' ', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('.', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED(0x7F, c_keyboard::on_del_clicked) +ON_GL_BN_CLICKED(0x14, c_keyboard::on_caps_clicked) +ON_GL_BN_CLICKED('\n', c_keyboard::on_enter_clicked) +ON_GL_BN_CLICKED(0x1B, c_keyboard::on_esc_clicked) +GL_END_MESSAGE_MAP() +int c_keyboard::connect(c_wnd *user, unsigned short resource_id, KEYBOARD_STYLE style) +{ + c_rect user_rect; + user->get_wnd_rect(user_rect); + if (style == STYLE_ALL_BOARD) + {//Place keyboard at the bottom of user's parent window. + c_rect user_parent_rect; + user->get_parent()->get_wnd_rect(user_parent_rect); + return c_wnd::connect(user, resource_id, 0, (0 - user_rect.m_left), (user_parent_rect.Height() - user_rect.m_top - KEYBOARD_HEIGHT), KEYBOARD_WIDTH, KEYBOARD_HEIGHT, g_key_board_children); + } + else if(style == STYLE_NUM_BOARD) + {//Place keyboard below the user window. + return c_wnd::connect(user, resource_id, 0, 0, user_rect.Height(), NUM_BOARD_WIDTH, NUM_BOARD_HEIGHT, g_number_board_children); + } + else + { + ASSERT(false); + } + return -1; +} +void c_keyboard::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_cap_status = STATUS_UPPERCASE; + memset(m_str, 0, sizeof(m_str)); + m_str_len = 0; +} +void c_keyboard::on_caps_clicked(unsigned int ctrl_id) +{ + m_cap_status = (m_cap_status == STATUS_LOWERCASE) ? STATUS_UPPERCASE : STATUS_LOWERCASE; + show_window(); +} +void c_keyboard::on_enter_clicked(unsigned int ctrl_id) +{ + memset(m_str, 0, sizeof(m_str)); + notify_parent(KEYBORAD_CLICK, CLICK_ENTER); +} +void c_keyboard::on_esc_clicked(unsigned int ctrl_id) +{ + memset(m_str, 0, sizeof(m_str)); + notify_parent(KEYBORAD_CLICK, CLICK_ESC); +} +void c_keyboard::on_del_clicked(unsigned int ctrl_id) +{ + if (m_str_len <= 0) + { + return; + } + m_str[--m_str_len] = 0; + notify_parent(KEYBORAD_CLICK, CLICK_CHAR); +} +void c_keyboard::on_char_clicked(unsigned int ctrl_id) +{//ctrl_id = char ascii code. + if (m_str_len >= sizeof(m_str)) + { + return; + } + if ((ctrl_id >= '0' && ctrl_id <= '9') || ctrl_id == ' ' || ctrl_id == '.') + { + goto InputChar; + } + if (ctrl_id >= 'A' && ctrl_id <= 'Z') + { + if (STATUS_LOWERCASE == m_cap_status) + { + ctrl_id += 0x20; + } + goto InputChar; + } + ASSERT(false); +InputChar: + m_str[m_str_len++] = ctrl_id; + notify_parent(KEYBORAD_CLICK, CLICK_CHAR); +} +void c_keyboard::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + m_surface->fill_rect(rect, GL_RGB(0, 0, 0), m_z_order); +} +void c_keyboard_button::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + break; + case STATUS_FOCUSED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + break; + default: + ASSERT(false); + break; + } + + if (m_resource_id == 0x14) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Caps", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x1B) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Esc", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == ' ') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Space", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == '\n') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Enter", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == '.') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, ".", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x7F) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Back", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x90) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "?123", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + + char letter[] = { 0, 0 }; + if (m_resource_id >= 'A' && m_resource_id <= 'Z') + { + letter[0] = (((c_keyboard*)m_parent)->get_cap_status() == STATUS_UPPERCASE) ? m_resource_id : (m_resource_id + 0x20); + } + else if (m_resource_id >= '0' && m_resource_id <= '9') + { + letter[0] = m_resource_id; + } + c_word::draw_string_in_rect(m_surface, m_z_order, letter, rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); +} +void c_label::pre_create_wnd() +{ + m_attr = ATTR_VISIBLE; + m_font_color = c_theme::get_color(COLOR_WND_FONT); + m_font_type = c_theme::get_font(FONT_DEFAULT); +} +void c_label::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + if (m_str) + { + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, m_parent->get_bg_color(), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, m_parent->get_bg_color(), ALIGN_LEFT | ALIGN_VCENTER); + } +} +#include +#define ITEM_HEIGHT 45 +void c_list_box::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + memset(m_item_array, 0, sizeof(m_item_array)); + m_item_total = 0; + m_selected_item = 0; + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); +} +void c_list_box::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_list_box::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +void c_list_box::on_paint() +{ + c_rect rect, empty_rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, GL_RGB(2, 124, 165), GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER | ALIGN_VCENTER); + //draw list + if (m_item_total > 0) + { + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + } + m_surface->set_frame_layer_visible_rect(m_list_screen_rect, m_z_order); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); + show_list(); + } + break; + default: + ASSERT(false); + } +} +bool c_list_box::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return true; +} +void c_list_box::on_touch_down(int x, int y) +{ + if (m_wnd_rect.PtInRect(x, y) ) + {//click base + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } + } + else if (m_list_wnd_rect.PtInRect(x, y)) + {//click extend list + c_wnd::on_touch(x, y, TOUCH_DOWN); + } + else + { + if (STATUS_PUSHED == m_status) + { + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_LIST_CONFIRM, m_selected_item); + } + } +} +void c_list_box::on_touch_up(int x, int y) +{ + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + if (m_wnd_rect.PtInRect(x, y)) + {//click base + m_status = STATUS_FOCUSED; + on_paint(); + } + else if (m_list_wnd_rect.PtInRect(x, y)) + {//click extend list + m_status = STATUS_FOCUSED; + select_item((y - m_list_wnd_rect.m_top) / ITEM_HEIGHT); + on_paint(); + notify_parent(GL_LIST_CONFIRM, m_selected_item); + } + else + { + c_wnd::on_touch(x, y, TOUCH_UP); + } + } +} +void c_list_box::update_list_size() +{ + m_list_wnd_rect = m_wnd_rect; + m_list_wnd_rect.m_top = m_wnd_rect.m_bottom + 1; + m_list_wnd_rect.m_bottom = m_list_wnd_rect.m_top + m_item_total * ITEM_HEIGHT; + get_screen_rect(m_list_screen_rect); + m_list_screen_rect.m_top = m_list_screen_rect.m_bottom + 1; + m_list_screen_rect.m_bottom = m_list_screen_rect.m_top + m_item_total * ITEM_HEIGHT; +} +void c_list_box::show_list() +{ + //draw all items + c_rect tmp_rect; + for (int i = 0; i < m_item_total; i++) + { + tmp_rect.m_left = m_list_screen_rect.m_left; + tmp_rect.m_right = m_list_screen_rect.m_right; + tmp_rect.m_top = m_list_screen_rect.m_top + i * ITEM_HEIGHT; + tmp_rect.m_bottom = tmp_rect.m_top + ITEM_HEIGHT; + if (m_selected_item == i) + { + m_surface->fill_rect(tmp_rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + } + else + { + m_surface->fill_rect(tmp_rect, GL_RGB(17, 17, 17), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font_type, m_font_color, GL_RGB(17, 17, 17), ALIGN_HCENTER | ALIGN_VCENTER); + } + } +} +int c_list_box::add_item(char* str) +{ + if (m_item_total >= MAX_ITEM_NUM) + { + ASSERT(false); + return -1; + } + m_item_array[m_item_total++] = str; + update_list_size(); + return 0; +} +void c_list_box::clear_item() +{ + m_selected_item = m_item_total = 0; + memset(m_item_array, 0, sizeof(m_item_array)); + update_list_size(); +} +void c_list_box::select_item(short index) +{ + if (index < 0 || index >= m_item_total) + { + ASSERT(false); + } + m_selected_item = index; +} +c_slide_group::c_slide_group() +{ + m_gesture = new c_gesture(this); + for(int i = 0; i < MAX_PAGES; i++) + { + m_slides[i] = 0; + } + m_active_slide_index = 0; +} +int c_slide_group::set_active_slide(int index, bool is_redraw) +{ + if(index >= MAX_PAGES || index < 0) + { + return -1; + } + if(0 == m_slides[index]) + { + return -2; + } + m_active_slide_index = index; + for(int i = 0; i < MAX_PAGES; i++) + { + if(m_slides[i] == 0) + { + continue; + } + if(i == index) + { + m_slides[i]->get_surface()->set_active(true); + add_child_2_tail(m_slides[i]); + if(is_redraw) + { + c_rect rc; + get_screen_rect(rc); + m_slides[i]->get_surface()->flush_screen(rc.m_left, rc.m_top, rc.m_right, rc.m_bottom); + } + } + else + { + m_slides[i]->get_surface()->set_active(false); + } + } + return 0; +} +int c_slide_group::add_slide(c_wnd* slide, unsigned short resource_id, short x, short y, + short width, short height, WND_TREE* p_child_tree, Z_ORDER_LEVEL max_zorder) +{ + if(0 == slide) + { + return -1; + } + c_surface* old_surface = get_surface(); + c_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder); + new_surface->set_active(false); + set_surface(new_surface); + slide->connect(this, resource_id ,0 , x, y, width, height, p_child_tree); + set_surface(old_surface); + int i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == slide) + {//slide has lived + ASSERT(false); + return -2; + } + i++; + } + //new slide + i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == 0) + { + m_slides[i] = slide; + slide->show_window(); + return 0; + } + i++; + } + //no more slide can be add + ASSERT(false); + return -3; +} +int c_slide_group::add_clone_silde(c_wnd* slide, unsigned short resource_id, short x, short y, + short width, short height, WND_TREE* p_child_tree, Z_ORDER_LEVEL max_zorder) +{ + if(0 == slide) + { + return -1; + } + c_surface* old_surface = get_surface(); + c_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder); + new_surface->set_active(false); + set_surface(new_surface); + c_wnd* page_tmp = slide->connect_clone(this,resource_id,0,x,y,width,height,p_child_tree); + set_surface(old_surface); + int i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == page_tmp) + {//slide has lived + ASSERT(false); + return -2; + } + i++; + } + //new slide + i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == 0) + { + m_slides[i] = page_tmp; + page_tmp->show_window(); + return 0; + } + i++; + } + //no more slide can be add + ASSERT(false); + return -3; +} +void c_slide_group::disabel_all_slide() +{ + for(int i = 0; i < MAX_PAGES; i++) + { + if(m_slides[i]) + { + m_slides[i]->get_surface()->set_active(false); + } + } +} +bool c_slide_group::on_touch(int x, int y, TOUCH_ACTION action) +{ + x -= m_wnd_rect.m_left; + y -= m_wnd_rect.m_top; + if (m_gesture->handle_swipe(x, y, action)) + { + if (m_slides[m_active_slide_index]) + { + m_slides[m_active_slide_index]->on_touch(x, y, action); + } + } + return true; +} +bool c_slide_group::on_key(KEY_TYPE key) +{ + if (m_slides[m_active_slide_index]) + { + m_slides[m_active_slide_index]->on_key(key); + } + return true; +} +#define ARROW_BT_HEIGHT 55 +#define ID_BT_ARROW_UP 1 +#define ID_BT_ARROW_DOWN 2 +GL_BEGIN_MESSAGE_MAP(c_spin_box) +ON_GL_BN_CLICKED(ID_BT_ARROW_UP, c_spin_box::on_arrow_up_bt_click) +ON_GL_BN_CLICKED(ID_BT_ARROW_DOWN, c_spin_box::on_arrow_down_bt_click) +GL_END_MESSAGE_MAP() +void c_spin_box::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); + m_max = 6; + m_min = 1; + m_digit = 0; + m_step = 1; + //set arrow button position. + c_rect rect; + get_screen_rect(rect); + m_bt_up_rect.m_left = rect.m_left; + m_bt_up_rect.m_right = rect.m_left + rect.Width() / 2 - 1; + m_bt_up_rect.m_top = rect.m_bottom + 1; + m_bt_up_rect.m_bottom = m_bt_up_rect.m_top + ARROW_BT_HEIGHT; + m_bt_down_rect.m_left = rect.m_left + rect.Width() / 2; + m_bt_down_rect.m_right = rect.m_right; + m_bt_down_rect.m_top = rect.m_bottom + 1; + m_bt_down_rect.m_bottom = m_bt_down_rect.m_top + ARROW_BT_HEIGHT; +} +bool c_spin_box::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return c_wnd::on_touch(x, y, action); +} +void c_spin_box::on_touch_down(int x, int y) +{ + if (false == m_wnd_rect.PtInRect(x, y)) + {//maybe click on up/down arrow button + return; + } + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } +} +void c_spin_box::on_touch_up(int x, int y) +{ + if (false == m_wnd_rect.PtInRect(x, y)) + {//maybe click on up/down arrow button + return; + } + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + m_value = m_cur_value; + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_SPIN_CONFIRM, m_value); + } +} +void c_spin_box::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_spin_box::on_kill_focus() +{ + m_cur_value = m_value; + m_status = STATUS_NORMAL; + on_paint(); +} +void c_spin_box::show_arrow_button() +{ + m_bt_up.connect(this, ID_BT_ARROW_UP, "\xe2\x96\xb2"/*unicode of up arrow*/, 0, m_wnd_rect.Height(), m_bt_up_rect.Width(),m_bt_up_rect.Height()); + m_bt_up.show_window(); + m_bt_down.connect(this, ID_BT_ARROW_DOWN, "\xe2\x96\xbc"/*unicode of down arrow*/, m_bt_up_rect.Width(), m_wnd_rect.Height(), m_bt_down_rect.Width(),m_bt_down_rect.Height()); + m_bt_down.show_window(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); +} +void c_spin_box::hide_arrow_button() +{ + m_bt_up.disconnect(); + m_bt_down.disconnect(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); +} +void c_spin_box::on_paint() +{ + c_rect rect, tmp_rect, empty_rect; + get_screen_rect(rect); + tmp_rect.m_left = rect.m_left; + tmp_rect.m_right = rect.m_right; + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + hide_arrow_button(); + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + hide_arrow_button(); + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + } + tmp_rect.m_top = m_bt_down_rect.m_top; + tmp_rect.m_bottom = m_bt_down_rect.m_bottom; + m_surface->set_frame_layer_visible_rect(tmp_rect, m_z_order); + show_arrow_button(); + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_PUSHED), m_parent->get_z_order()); + m_surface->draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_BORDER), m_parent->get_z_order(), 2); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + break; + default: + ASSERT(false); + } +} +void c_spin_box::on_arrow_up_bt_click(unsigned int ctr_id) +{ + if (m_cur_value + m_step > m_max) + { + return; + } + m_cur_value += m_step; + notify_parent(GL_SPIN_CHANGE, m_cur_value); + on_paint(); +} +void c_spin_box::on_arrow_down_bt_click(unsigned int ctr_id) +{ + if (m_cur_value - m_step < m_min) + { + return; + } + m_cur_value -= m_step; + notify_parent(GL_SPIN_CHANGE, m_cur_value); + on_paint(); +} +void c_table::set_item(int row, int col, char* str, unsigned int color) +{ + draw_item( row, col, str, color); +} +void c_table::draw_item(int row, int col, const char* str, unsigned int color) +{ + c_rect rect = get_item_rect(row, col); + m_surface->fill_rect(rect.m_left+1, rect.m_top+1, rect.m_right-1, rect.m_bottom-1, color, m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, str, rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_align_type); +} +void c_table::set_row_height(unsigned int height) +{ + for (unsigned int i = 0; i < m_row_num; i ++) + { + m_row_height[i] = height; + } +} +void c_table::set_col_width(unsigned int width) +{ + for (unsigned int i = 0; i < m_col_num; i ++) + { + m_col_width[i] = width; + } +} +int c_table::set_row_height(unsigned int index, unsigned int height) +{ + if (m_row_num > index) + { + m_row_height[index] = height; + return index; + } + return -1; +} +int c_table::set_col_width(unsigned int index, unsigned int width) +{ + if (m_col_num > index) + { + m_col_width[index] = width; + return index; + } + return -1; +} +c_rect c_table::get_item_rect(int row, int col) +{ + static c_rect rect; + if (row >= MAX_ROW_NUM || col >= MAX_COL_NUM) + { + return rect; + } + unsigned int width = 0; + unsigned int height = 0; + for (int i = 0; i < col; i++) + { + width += m_col_width[i]; + } + for (int j = 0; j < row; j++) + { + height += m_row_height[j]; + } + c_rect wRect; + get_screen_rect(wRect); + rect.m_left = wRect.m_left + width; + rect.m_right = rect.m_left + m_col_width[col]; + if (rect.m_right > wRect.m_right) + { + rect.m_right = wRect.m_right; + } + rect.m_top = wRect.m_top + height; + rect.m_bottom = rect.m_top + m_row_height[row]; + if (rect.m_bottom > wRect.m_bottom) + { + rect.m_bottom = wRect.m_bottom; + } + return rect; +} +#include +#include +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) +c_wave_buffer::c_wave_buffer() +{ + m_head = m_tail = m_min_old = m_max_old = + m_min_older = m_max_older = m_last_data = m_read_cache_sum = m_refresh_sequence = 0; + memset(m_wave_buf, 0, sizeof(m_wave_buf)); + memset(m_read_cache_min, 0, sizeof(m_read_cache_min)); + memset(m_read_cache_mid, 0, sizeof(m_read_cache_mid)); + memset(m_read_cache_max, 0, sizeof(m_read_cache_max)); +} +short c_wave_buffer::get_cnt() +{ + return (m_tail >= m_head)?(m_tail - m_head):(m_tail - m_head + WAVE_BUFFER_LEN); +} +int c_wave_buffer::write_wave_data(short data) +{ + if ((m_tail + 1) % WAVE_BUFFER_LEN == m_head) + {//full + //log_out("wave buf full\n"); + return BUFFER_FULL; + } + m_wave_buf[m_tail] = data; + m_tail = (m_tail + 1) % WAVE_BUFFER_LEN; + return 1; +} +int c_wave_buffer::read_data() +{ + if (m_head == m_tail) + {//empty + //log_out("wave buf empty\n"); + return BUFFER_EMPTY; + } + int ret = m_wave_buf[m_head]; + m_head = (m_head + 1) % WAVE_BUFFER_LEN; + return ret; +} +int c_wave_buffer::read_wave_data_by_frame(short &max, short &min, short frame_len, unsigned int sequence, short offset) +{ + if (m_refresh_sequence != sequence) + { + m_refresh_sequence = sequence; + m_read_cache_sum = 0; + } + else if(offset < m_read_cache_sum)//(m_refresh_sequence == sequence && offset < m_fb_sum) + { + max = m_read_cache_max[offset]; + min = m_read_cache_min[offset]; + return m_read_cache_mid[offset]; + } + + m_read_cache_sum++; + ASSERT(m_read_cache_sum <= WAVE_READ_CACHE_LEN); + int i, data; + int tmp_min = m_last_data; + int tmp_max = m_last_data; + int mid = (m_min_old + m_max_old)>>1; + i = 0; + while(i++ < frame_len) + { + data = read_data(); + if(BUFFER_EMPTY == data) + { + break; + } + m_last_data = data; + if(data < tmp_min){tmp_min = data;} + if(data > tmp_max){tmp_max = data;} + } + min = m_read_cache_min[offset] = MIN(m_min_old, MIN(tmp_min, m_min_older)); + max = m_read_cache_max[offset] = MAX(m_max_old, MAX(tmp_max, m_max_older)); + m_min_older = m_min_old; + m_max_older = m_max_old; + m_min_old = tmp_min; + m_max_old = tmp_max; + return (m_read_cache_mid[offset] = mid); +} +void c_wave_buffer::clear_data() +{ + m_head = m_tail = 0; + memset(m_wave_buf, 0, sizeof(m_wave_buf)); +} +void c_wave_buffer::reset() +{ + m_head = m_tail; +} +#include +#include +#define CORRECT(x, high_limit, low_limit) {\ + x = (x > high_limit) ? high_limit : x;\ + x = (x < low_limit) ? low_limit : x;\ +}while(0) +#define WAVE_CURSOR_WIDTH 8 +#define WAVE_LINE_WIDTH 1 +#define WAVE_MARGIN 5 +c_wave_ctrl::c_wave_ctrl() +{ + m_wave = 0; + m_bg_fb = 0; + m_wave_name_font = m_wave_unit_font = 0; + m_wave_name = m_wave_unit = 0; + m_max_data = 500; + m_min_data = 0; + m_wave_speed = 1; + m_wave_data_rate = 0; + m_wave_refresh_rate = 1000; + m_frame_len_map_index = 0; + m_wave_name_color = m_wave_unit_color = m_wave_color = GL_RGB(255,0,0); + m_back_color = GL_RGB(0,0,0); +} +void c_wave_ctrl::on_init_children() +{ + c_rect rect; + get_screen_rect(rect); + m_wave_left = rect.m_left + WAVE_MARGIN; + m_wave_right = rect.m_right - WAVE_MARGIN; + m_wave_top = rect.m_top + WAVE_MARGIN; + m_wave_bottom = rect.m_bottom - WAVE_MARGIN; + m_wave_cursor = m_wave_left; + m_bg_fb = (unsigned int*)calloc(rect.Width() * rect.Height(), 4); +} +void c_wave_ctrl::set_max_min(short max_data, short min_data) +{ + m_max_data = max_data; + m_min_data = min_data; +} +void c_wave_ctrl::set_wave_in_out_rate(unsigned int data_rate, unsigned int refresh_rate) +{ + m_wave_data_rate = data_rate; + m_wave_refresh_rate = refresh_rate; + int read_times_per_second = m_wave_speed * 1000 / m_wave_refresh_rate; + memset(m_frame_len_map, 0, sizeof(m_frame_len_map)); + for (unsigned int i = 1; i < sizeof(m_frame_len_map) + 1; i++) + { + m_frame_len_map[i-1] = data_rate * i / read_times_per_second - data_rate * (i-1) / read_times_per_second; + } + m_frame_len_map_index = 0; +} +void c_wave_ctrl::set_wave_speed(unsigned int speed) +{ + m_wave_speed = speed; + set_wave_in_out_rate(m_wave_data_rate, m_wave_refresh_rate); +} +void c_wave_ctrl::clear_data() +{ + if(m_wave == 0) + { + ASSERT(false); + return; + } + m_wave->clear_data(); +} +bool c_wave_ctrl::is_data_enough() +{ + if(m_wave == 0) + { + ASSERT(false); + return false; + } + return (m_wave->get_cnt() - m_frame_len_map[m_frame_len_map_index] * m_wave_speed); +} +void c_wave_ctrl::refresh_wave(unsigned char frame) +{ + if(m_wave == 0) + { + ASSERT(false); + return; + } + short max, min, mid; + for(short offset = 0; offset < m_wave_speed; offset++) + { + //get wave value + mid = m_wave->read_wave_data_by_frame(max, min, + m_frame_len_map[m_frame_len_map_index++], + frame, offset); + m_frame_len_map_index %= sizeof(m_frame_len_map); + + //map to wave ctrl + int y_min,y_max; + if(m_max_data == m_min_data) + { + ASSERT(false); + } + y_max = m_wave_bottom + WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top)*(min - m_min_data)/(m_max_data - m_min_data); + y_min = m_wave_bottom - WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top)*(max - m_min_data)/(m_max_data - m_min_data); + mid = m_wave_bottom - (m_wave_bottom - m_wave_top)*(mid - m_min_data)/(m_max_data - m_min_data); + CORRECT(y_min, m_wave_bottom, m_wave_top); + CORRECT(y_max, m_wave_bottom, m_wave_top); + CORRECT(mid, m_wave_bottom, m_wave_top); + if (m_wave_cursor > m_wave_right) + { + m_wave_cursor = m_wave_left; + } + draw_smooth_vline(y_min, y_max, mid, m_wave_color); + restore_background(); + m_wave_cursor++; + } +} +void c_wave_ctrl::draw_smooth_vline(int y_min, int y_max, int mid, unsigned int rgb) +{ + int dy = y_max - y_min; + short r = GL_RGB_R(rgb); + short g = GL_RGB_G(rgb); + short b = GL_RGB_B(rgb); + int index = (dy >> 1) + 2; + int y; + m_surface->draw_pixel(m_wave_cursor, mid, rgb, m_z_order); + if (dy < 1) + { + return; + } + unsigned char cur_r,cur_g,cur_b; + unsigned int cur_rgb; + for (int i = 1; i <= (dy >> 1) + 1; ++i ) + { + if ( (mid + i) <= y_max ) + { + y = mid + i; + cur_r = r * (index - i) / index; + cur_g = g * (index - i) / index; + cur_b = b * (index - i) / index; + cur_rgb = GL_RGB(cur_r, cur_g, cur_b); + m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order); + } + if ( (mid - i) >= y_min ) + { + y = mid - i; + cur_r = r * (index - i) / index; + cur_g = g * (index - i) / index; + cur_b = b * (index - i) / index; + cur_rgb = GL_RGB(cur_r, cur_g, cur_b); + m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order); + } + } +} +void c_wave_ctrl::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, m_back_color, m_z_order); + + //show name + c_word::draw_string(m_surface, m_z_order, m_wave_name, m_wave_left + 10, rect.m_top, m_wave_name_font, m_wave_name_color, GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + //show unit + c_word::draw_string(m_surface, m_z_order, m_wave_unit, m_wave_left + 60, rect.m_top, m_wave_unit_font, m_wave_unit_color, GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + save_background(); +} +void c_wave_ctrl::clear_wave(void) +{ + m_surface->fill_rect(m_wave_left, m_wave_top, m_wave_right, m_wave_bottom, m_back_color, m_z_order); + m_wave_cursor = m_wave_left; +} +void c_wave_ctrl::restore_background() +{ + int x = m_wave_cursor + WAVE_CURSOR_WIDTH; + if (x > m_wave_right) + { + x -= (m_wave_right - m_wave_left + 1); + } + c_rect rect; + get_screen_rect(rect); + register int width = rect.Width(); + register int top = rect.m_top; + register int left = rect.m_left; + for (int y_pos = (m_wave_top - 1); y_pos <= (m_wave_bottom + 1); y_pos++) + { + (m_bg_fb) ? m_surface->draw_pixel(x, y_pos, m_bg_fb[(y_pos - top) * width + (x - left)], m_z_order) : m_surface->draw_pixel(x, y_pos, 0, m_z_order); + } +} +void c_wave_ctrl::save_background() +{ + if (!m_bg_fb) + { + return; + } + c_rect rect; + get_screen_rect(rect); + + register unsigned int* p_des = m_bg_fb; + for (int y = rect.m_top; y <= rect.m_bottom; y++) + { + for (int x = rect.m_left; x <= rect.m_right; x++) + { + *p_des++ = m_surface->get_pixel(x, y, m_z_order); + } + } +} diff --git a/GuiLite-unknow.cpp b/GuiLite-unknow.cpp new file mode 100644 index 0000000..0f9d2f8 --- /dev/null +++ b/GuiLite-unknow.cpp @@ -0,0 +1,3460 @@ +#include "GuiLite.h" +void c_bitmap::draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO *pBitmap, int x, int y, unsigned int mask_rgb) +{ + if (0 == pBitmap) + { + return; + } + unsigned short* lower_fb = 0; + int lower_fb_width = surface->m_width; + if (z_order >= Z_ORDER_LEVEL_1) + { + lower_fb = surface->m_frame_layers[z_order - 1].fb; + } + unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); + int xsize = pBitmap->width; + int ysize = pBitmap->height; + const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; + for (int j = 0; j < ysize; j++) + { + for (int i = 0; i < xsize; i++) + { + unsigned int rgb = *pData++; + if (mask_rgb_16 == rgb) + { + if (lower_fb) + {//restore lower layer + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(lower_fb[(y + j) * lower_fb_width + x + i]), z_order); + } + } + else + { + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + } + } + } +} +void c_bitmap::draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO* pBitmap, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb) +{ + if (0 == pBitmap || (src_x + width > pBitmap->width) || (src_y + height > pBitmap->height)) + { + return; + } + unsigned short* lower_fb = 0; + int lower_fb_width = surface->m_width; + if (z_order >= Z_ORDER_LEVEL_1) + { + lower_fb = surface->m_frame_layers[z_order - 1].fb; + } + unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); + const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; + for (int j = 0; j < height; j++) + { + const unsigned short* p = &pData[src_x + (src_y + j) * pBitmap->width]; + for (int i = 0; i < width; i++) + { + unsigned int rgb = *p++; + if (mask_rgb_16 == rgb) + { + if (lower_fb) + {//restore lower layer + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(lower_fb[(y + j) * lower_fb_width + x + i]), z_order); + } + } + else + { + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + } + } + } +} +GL_MSG_ENTRY c_cmd_target::ms_usr_map_entries[USR_MSG_MAX]; +unsigned short c_cmd_target::ms_user_map_size; +GL_BEGIN_MESSAGE_MAP(c_cmd_target) +GL_END_MESSAGE_MAP() +c_cmd_target::c_cmd_target() +{ +} +c_cmd_target::~c_cmd_target() +{ +} +int c_cmd_target::handle_usr_msg(unsigned int msgId, unsigned int wParam, unsigned int lParam) +{ + int i; + c_cmd_target* p_wnd = 0; + MSGFUNCS msg_funcs; + for (i = 0; i < ms_user_map_size; i++) + { + if (msgId == ms_usr_map_entries[i].msgId) + { + p_wnd = (c_cmd_target*)ms_usr_map_entries[i].pObject; + msg_funcs.func = ms_usr_map_entries[i].func; + (p_wnd->*msg_funcs.func_vwl)(wParam , lParam); + } + } + return 1; +} +void c_cmd_target::load_cmd_msg() +{ + const GL_MSG_ENTRY* p_entry = GetMSgEntries(); + if (0 == p_entry) + { + return; + } + bool bExist = false; + while(MSG_TYPE_INVALID != p_entry->msgType) + { + if (MSG_TYPE_WND == p_entry->msgType) + { + p_entry++; + continue; + } + bExist = false; + for (int i = 0; i < ms_user_map_size; i++) + { + //repeat register, return. + if (p_entry->msgId == ms_usr_map_entries[i].msgId + && ms_usr_map_entries[i].pObject == this) + { + bExist = true; + break; + } + } + if (true == bExist) + { + p_entry++; + continue; + } + if (MSG_TYPE_USR == p_entry->msgType) + { + ms_usr_map_entries[ms_user_map_size] = *p_entry; + ms_usr_map_entries[ms_user_map_size].pObject = this; + ms_user_map_size++; + if (USR_MSG_MAX == ms_user_map_size) + { + ASSERT(false); + } + } + else + { + ASSERT(false); + break; + } + p_entry++; + } +} +const GL_MSG_ENTRY* c_cmd_target::FindMsgEntry(const GL_MSG_ENTRY *pEntry, + unsigned int msgType, unsigned short msgId, unsigned short ctrlId) +{ + if ( MSG_TYPE_INVALID == msgType) + { + return 0; + } + while (MSG_CALLBACK_NULL != pEntry->callbackType) + { + if ( (msgType == pEntry->msgType) && (msgId == pEntry->msgId) && (void*)(unsigned long)ctrlId == pEntry->pObject) + { + return pEntry; + } + pEntry++; + } + return 0; +} +#include +#include +c_display::c_display(void* phy_fb, unsigned int display_width, unsigned int display_height, + unsigned int surface_width, unsigned int surface_height, + unsigned int color_bytes, unsigned int surface_cnt, EXTERNAL_GFX_OP* gfx_op) +{ + if (color_bytes != 2 && color_bytes != 4) + { + log_out("Support 16 bits, 32 bits color only!"); + ASSERT(false); + } + m_width = display_width; + m_height = display_height; + m_color_bytes = color_bytes; + m_phy_fb = phy_fb; + m_phy_read_index = m_phy_write_index = 0; + memset(m_surface_group, 0, sizeof(m_surface_group)); + m_surface_index = 0; + m_surface_cnt = surface_cnt; + ASSERT(m_surface_cnt <= SURFACE_CNT_MAX); + + for (int i = 0; i < m_surface_cnt; i++) + { + m_surface_group[i] = phy_fb ? new c_surface(this, surface_width, surface_height, color_bytes) : new c_surface_no_fb(this, surface_width, surface_height, color_bytes, gfx_op); + } +} +c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder) +{ + if(max_zorder >= Z_ORDER_LEVEL_MAX || m_surface_index >= m_surface_cnt) + { + ASSERT(false); + return 0; + } + int i = m_surface_index++; + m_surface_group[i]->set_surface(max_zorder); + return m_surface_group[i]; +} +int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset) +{ + int surface_width = s0->get_width(); + int surface_height = s0->get_height(); + if (offset < 0 || offset > surface_width || y0 < 0 || y0 >= surface_height || + y1 < 0 || y1 >= surface_height || x0 < 0 || x0 >= surface_width || x1 < 0 || x1 >= surface_width) + { + ASSERT(false); + return -1; + } + int width = (x1 - x0 + 1); + if (width < 0 || width > surface_width || width < offset) + { + ASSERT(false); + return -1; + } + x0 = (x0 >= m_width) ? (m_width - 1) : x0; + x1 = (x1 >= m_width) ? (m_width - 1) : x1; + y0 = (y0 >= m_height) ? (m_height - 1) : y0; + y1 = (y1 >= m_height) ? (m_height - 1) : y1; + + if (m_phy_fb) + { + for (int y = y0; y <= y1; y++) + { + //Left surface + char* addr_s = ((char*)(s0->m_fb) + (y * (s0->get_width()) + x0 + offset) * m_color_bytes); + char* addr_d = ((char*)(m_phy_fb)+(y * m_width + x0) * m_color_bytes); + memcpy(addr_d, addr_s, (width - offset) * m_color_bytes); + //Right surface + addr_s = ((char*)(s1->m_fb) + (y * (s1->get_width()) + x0) * m_color_bytes); + addr_d = ((char*)(m_phy_fb)+(y * m_width + x0 + (width - offset)) * m_color_bytes); + memcpy(addr_d, addr_s, offset * m_color_bytes); + } + } + else if(m_color_bytes == 4) + { + void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel; + for (int y = y0; y <= y1; y++) + { + //Left surface + for (int x = x0; x <= (x1 - offset); x++) + { + draw_pixel(x, y, ((unsigned int*)s0->m_fb)[y * m_width + x + offset]); + } + //Right surface + for (int x = x1 - offset; x <= x1; x++) + { + draw_pixel(x, y, ((unsigned int*)s1->m_fb)[y * m_width + x + offset - x1 + x0]); + } + } + } + else if (m_color_bytes == 2) + { + void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel; + for (int y = y0; y <= y1; y++) + { + //Left surface + for (int x = x0; x <= (x1 - offset); x++) + { + draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s0->m_fb)[y * m_width + x + offset])); + } + //Right surface + for (int x = x1 - offset; x <= x1; x++) + { + draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s1->m_fb)[y * m_width + x + offset - x1 + x0])); + } + } + } + m_phy_write_index++; + return 0; +} +void* c_display::get_updated_fb(int* width, int* height, bool force_update) +{ + if (width && height) + { + *width = get_width(); + *height = get_height(); + } + if (force_update) + { + return m_phy_fb; + } + if (m_phy_read_index == m_phy_write_index) + {//No update + return 0; + } + m_phy_read_index = m_phy_write_index; + return m_phy_fb; +} +int c_display::snap_shot(const char* file_name) +{ + if (!m_phy_fb) + { + return -1; + } + unsigned int width = get_width(); + unsigned int height = get_height(); + //16 bits framebuffer + if (m_color_bytes == 2) + { + return build_bmp(file_name, width, height, (unsigned char*)m_phy_fb); + } + //32 bits framebuffer + unsigned short* p_bmp565_data = new unsigned short[width * height]; + unsigned int* p_raw_data = (unsigned int*)m_phy_fb; + for (int i = 0; i < width * height; i++) + { + unsigned int rgb = *p_raw_data++; + p_bmp565_data[i] = GL_RGB_32_to_16(rgb); + } + int ret = build_bmp(file_name, width, height, (unsigned char*)p_bmp565_data); + delete []p_bmp565_data; + return ret; +} +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) +c_rect::c_rect(const c_rect& rect) +{ + SetRect(rect.m_left,rect.m_top,rect.m_right,rect.m_bottom); +} +c_rect& c_rect::operator=(const c_rect& rect) +{ + SetRect(rect.m_left,rect.m_top,rect.m_right,rect.m_bottom); + return *this; +} +void c_rect::SetRect( int Left, int Top, int Right, int Bottom) +{ + m_left = MIN(Left, Right); + m_top = MIN(Top, Bottom); + m_right = MAX(Left, Right); + m_bottom = MAX(Top, Bottom); +} +c_rect c_rect::operator&(const c_rect& rect) const +{ + c_rect dst; + dst.m_left = MAX(m_left, rect.m_left); + dst.m_top = MAX(m_top, rect.m_top); + dst.m_right = MIN(m_right, rect.m_right); + dst.m_bottom = MIN(m_bottom, rect.m_bottom); + if(dst.m_left >= dst.m_right || dst.m_top >= dst.m_bottom) + dst.Empty(); + return dst; +} +void c_rect::Empty() +{ + m_left = m_top = m_right = m_bottom = 0; +} +void c_rect::Offset(int x, int y) +{ + m_left +=x; + m_right +=x; + m_top += y; + m_bottom += y; +} +int c_rect::IsEmpty() const +{ + return m_top == m_bottom || m_left == m_right; +} +int c_rect::PtInRect(int x, int y) const +{ + return x >= m_left && x <= m_right && y >= m_top && y <= m_bottom; +} +int c_rect::operator==(const c_rect& rect) const +{ + return (m_left == rect.m_left) && (m_top==rect.m_top) && + (m_right == rect.m_right) && (m_bottom==rect.m_bottom); +} +#include +#include +#define GL_ROUND_RGB_32(rgb) (rgb & 0xFFF8FCF8) //make RGB32 = RGB16 +c_surface::c_surface(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes) +{ + m_width = width; + m_height = height; + m_color_bytes = color_bytes; + m_display = display; + m_phy_fb = display->m_phy_fb; + m_phy_write_index = &display->m_phy_write_index; + m_fb = 0; + m_top_zorder = m_max_zorder = Z_ORDER_LEVEL_0; + m_is_active = false; + m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height); +} +void c_surface::set_surface(Z_ORDER_LEVEL max_z_order) +{ + m_max_zorder = max_z_order; + if (m_display->m_surface_cnt > 1) + { + m_fb = calloc(m_width * m_height, m_color_bytes); + } + + for(int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++) + {//Top layber fb always be 0 + m_frame_layers[i].fb = (unsigned short*)calloc(m_width * m_height, sizeof(unsigned short)); + ASSERT(0 != m_frame_layers[i].fb); + } +} +void c_surface::draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order) +{ + if (x >= m_width || y >= m_height || x < 0 || y < 0) + { + return; + } + if (z_order > m_max_zorder) + { + ASSERT(false); + return; + } + rgb = GL_ROUND_RGB_32(rgb); + if (z_order == m_max_zorder) + { + return draw_pixel_on_fb(x, y, rgb); + } + if (z_order > m_top_zorder) + { + m_top_zorder = (Z_ORDER_LEVEL)z_order; + } + if (0 == m_frame_layers[z_order].visible_rect.PtInRect(x, y)) + { + ASSERT(false); + return; + } + ((unsigned short*)(m_frame_layers[z_order].fb))[x + y * m_width] = GL_RGB_32_to_16(rgb); + if (z_order == m_top_zorder) + { + return draw_pixel_on_fb(x, y, rgb); + } + bool is_covered = false; + for (int tmp_z_order = Z_ORDER_LEVEL_MAX - 1; tmp_z_order > z_order; tmp_z_order--) + { + if (true == m_frame_layers[tmp_z_order].visible_rect.PtInRect(x, y)) + { + is_covered = true; + break; + } + } + if (!is_covered) + { + draw_pixel_on_fb(x, y, rgb); + } +} +void c_surface::draw_pixel_on_fb(int x, int y, unsigned int rgb) +{ + if (m_fb) + { + (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb); + } + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + if (m_is_active && (x < display_width) && (y < display_height)) + { + if (m_color_bytes == 4) + { + ((unsigned int*)m_phy_fb)[y * (m_display->get_width()) + x] = rgb; + } + else + { + ((unsigned short*)m_phy_fb)[y * (m_display->get_width()) + x] = GL_RGB_32_to_16(rgb); + } + *m_phy_write_index = *m_phy_write_index + 1; + } +} +void c_surface::fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order) +{ + x0 = (x0 < 0) ? 0 : x0; + y0 = (y0 < 0) ? 0 : y0; + x1 = (x1 > (m_width - 1)) ? (m_width - 1) : x1; + y1 = (y1 > (m_height - 1)) ? (m_height - 1) : y1; + rgb = GL_ROUND_RGB_32(rgb); + if (z_order == m_max_zorder) + { + return fill_rect_on_fb(x0, y0, x1, y1, rgb); + } + if (z_order == m_top_zorder) + { + int x, y; + unsigned short *mem_fb; + unsigned int rgb_16 = GL_RGB_32_to_16(rgb); + for (y = y0; y <= y1; y++) + { + x = x0; + mem_fb = &((unsigned short*)m_frame_layers[z_order].fb)[y * m_width + x]; + for (; x <= x1; x++) + { + *mem_fb++ = rgb_16; + } + } + return fill_rect_on_fb(x0, y0, x1, y1, rgb); + } + for (; y0 <= y1; y0++) + { + draw_hline(x0, x1, y0, rgb, z_order); + } +} +void c_surface::fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) +{ + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + if (m_color_bytes == 4) + { + int x; + unsigned int *fb, *phy_fb; + for (; y0 <= y1; y0++) + { + x = x0; + fb = m_fb ? &((unsigned int*)m_fb)[y0 * m_width + x] : 0; + phy_fb = &((unsigned int*)m_phy_fb)[y0 * display_width + x]; + *m_phy_write_index = *m_phy_write_index + 1; + for (; x <= x1; x++) + { + if (fb) + { + *fb++ = rgb; + } + if (m_is_active && (x < display_width) && (y0 < display_height)) + { + *phy_fb++ = rgb; + } + } + } + } + else if(m_color_bytes == 2) + { + int x; + unsigned short *fb, *phy_fb; + rgb = GL_RGB_32_to_16(rgb); + for (; y0 <= y1; y0++) + { + x = x0; + fb = m_fb ? &((unsigned short*)m_fb)[y0 * m_width + x] : 0; + phy_fb = &((unsigned short*)m_phy_fb)[y0 * display_width + x]; + *m_phy_write_index = *m_phy_write_index + 1; + for (; x <= x1; x++) + { + if (fb) + { + *fb++ = rgb; + } + if (m_is_active && (x < display_width) && (y0 < display_height)) + { + *phy_fb++ = rgb; + } + } + } + } +} +unsigned int c_surface::get_pixel(int x, int y, unsigned int z_order) +{ + if (x >= m_width || y >= m_height || x < 0 || y < 0 || + z_order >= Z_ORDER_LEVEL_MAX) + { + ASSERT(false); + return 0; + } + if (z_order == m_max_zorder) + { + if (m_fb) + { + return (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_fb)[y * m_width + x]); + } + else if(m_phy_fb) + { + return (m_color_bytes == 4) ? ((unsigned int*)m_phy_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_phy_fb)[y * m_width + x]); + } + return 0; + } + + unsigned short rgb_16 = ((unsigned short*)(m_frame_layers[z_order].fb))[y * m_width + x]; + return GL_RGB_16_to_32(rgb_16); +} +void c_surface::draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order) +{ + for (;x0 <= x1; x0++) + { draw_pixel(x0, y, rgb, z_order); } +} +void c_surface::draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order) +{ + for (;y0 <= y1; y0++) + { draw_pixel(x, y0, rgb, z_order); } +} +void c_surface::draw_line(int x1, int y1, int x2, int y2, unsigned int rgb, unsigned int z_order) +{ + int dx, dy, e; + dx = x2 - x1; + dy = y2 - y1; + if ((dx >= 0) && (dy >= 0)) + { + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 <= x2; x1++, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1++; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 <= y2; y1++, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1++; e -= dy; } + } + } + } + else if ((dx >= 0) && (dy < 0)) + { + dy = -dy; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 <= x2; x1++, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1--; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 >= y2; y1--, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1++; e -= dy; } + } + } + } + else if ((dx < 0) && (dy >= 0)) + { + dx = -dx; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 >= x2; x1--, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1++; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 <= y2; y1++, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1--; e -= dy; } + } + } + } + else if ((dx < 0) && (dy < 0)) + { + dx = -dx; + dy = -dy; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 >= x2; x1--, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1--; e -= dx; } + } + } + else + { + e = dx - dy / 2; + while (y1-- >= y2) + for(; y1 >= y2; y1--, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1--; e -= dy; } + } + } + } +} +void c_surface::draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size) +{ + for (unsigned int offset = 0; offset < size; offset++) + { + draw_hline(x0 + offset, x1 - offset, y0 + offset, rgb, z_order); + draw_hline(x0 + offset, x1 - offset, y1 - offset, rgb, z_order); + draw_vline(x0 + offset, y0 + offset, y1 - offset, rgb, z_order); + draw_vline(x1 - offset, y0 + offset, y1 - offset, rgb, z_order); + } +} +int c_surface::set_frame_layer_visible_rect(c_rect& rect, unsigned int z_order) +{ + if (rect == m_frame_layers[z_order].visible_rect) + { + return 0; + } + if (rect.m_left < 0 || rect.m_left >= m_width || + rect.m_right < 0 || rect.m_right >= m_width || + rect.m_top < 0 || rect.m_top >= m_height || + rect.m_bottom < 0 || rect.m_bottom >=m_height) + { + ASSERT(false); + return -1; + } + if (!(z_order > Z_ORDER_LEVEL_0 && z_order < Z_ORDER_LEVEL_MAX)) + { + ASSERT(false); + return -2; + } + if (z_order < m_top_zorder) + { + ASSERT(false); + return -3; + } + m_top_zorder = (Z_ORDER_LEVEL)z_order; + + c_rect old_rect = m_frame_layers[z_order].visible_rect; + //Recover the lower layer + int src_zorder = (Z_ORDER_LEVEL)(z_order - 1); + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + for (int y = old_rect.m_top; y <= old_rect.m_bottom; y++) + { + for (int x = old_rect.m_left; x <= old_rect.m_right; x++) + { + if (!rect.PtInRect(x, y)) + { + unsigned int rgb = ((unsigned short*)(m_frame_layers[src_zorder].fb))[x + y * m_width]; + draw_pixel_on_fb(x, y, GL_RGB_16_to_32(rgb)); + } + } + } + m_frame_layers[z_order].visible_rect = rect; + if (rect.IsEmpty()) + { + m_top_zorder = (Z_ORDER_LEVEL)(z_order - 1); + } + return 0; +} +int c_surface::flush_screen(int left, int top, int right, int bottom) +{ + if(left < 0 || left >= m_width || right < 0 || right >= m_width || + top < 0 || top >= m_height || bottom < 0 || bottom >= m_height) + { + ASSERT(false); + } + if(!m_is_active || (0 == m_phy_fb) || (0 == m_fb)) + { + return -1; + } + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + left = (left >= display_width) ? (display_width - 1) : left; + right = (right >= display_width) ? (display_width - 1) : right; + top = (top >= display_height) ? (display_height - 1) : top; + bottom = (bottom >= display_height) ? (display_height - 1) : bottom; + for (int y = top; y < bottom; y++) + { + void* s_addr = (char*)m_fb + ((y * m_width + left) * m_color_bytes); + void* d_addr = (char*)m_phy_fb + ((y * display_width + left) * m_color_bytes); + memcpy(d_addr, s_addr, (right - left) * m_color_bytes); + } + *m_phy_write_index = *m_phy_write_index + 1; + return 0; +} +bool c_surface::is_valid(c_rect rect) +{ + if (rect.m_left < 0 || rect.m_top < 0) + { + return false; + } + if (rect.m_right >= m_width || rect.m_bottom >= m_height) + { + return false; + } + return true; +} +////////////////////////////////////////////////////////////////////////////////////// +void c_surface_no_fb::fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) +{ + if (!m_gfx_op) + { + return; + } + if (m_gfx_op->fill_rect) + { + return m_gfx_op->fill_rect(x0, y0, x1, y1, rgb); + } + if (m_gfx_op->draw_pixel && m_is_active) + { + for (int y = y0; y <= y1; y++) + { + for (int x = x0; x <= x1; x++) + { + m_gfx_op->draw_pixel(x, y, rgb); + } + } + } + if (!m_fb) { return; } + if(m_color_bytes == 4) + { + unsigned int *fb; + for (int y = y0; y <= y1; y++) + { + fb = &((unsigned int*)m_fb)[y0 * m_width + x0]; + for (int x = x0; x <= x1; x++) + { + *fb++ = rgb; + } + } + } + else if (m_color_bytes == 2) + { + unsigned short *fb; + rgb = GL_RGB_32_to_16(rgb); + for (int y = y0; y <= y1; y++) + { + fb = &((unsigned short*)m_fb)[y0 * m_width + x0]; + for (int x = x0; x <= x1; x++) + { + *fb++ = rgb; + } + } + } +} +void c_surface_no_fb::draw_pixel_on_fb(int x, int y, unsigned int rgb) +{ + if (m_gfx_op && m_gfx_op->draw_pixel && m_is_active) + { + m_gfx_op->draw_pixel(x, y, rgb); + } + if (!m_fb) { return; } + if (m_color_bytes == 4) + { + ((unsigned int*)m_fb)[y * m_width + x] = rgb; + } + else if (m_color_bytes == 2) + { + ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb); + } +} + +static const FONT_INFO* s_font_map[FONT_MAX]; +static const BITMAP_INFO* s_bmp_map[BITMAP_MAX]; +static unsigned int s_color_map[COLOR_MAX]; + +int c_theme::add_font(FONT_TYPE index, const FONT_INFO* font) +{ + if (index >= FONT_MAX) + { + ASSERT(false); + return -1; + } + s_font_map[index] = font; + return 0; +} + +const FONT_INFO* c_theme::get_font(FONT_TYPE index) +{ + if (index >= FONT_MAX) + { + ASSERT(false); + return 0; + } + return s_font_map[index]; +} + +int c_theme::add_bitmap(BITMAP_TYPE index, const BITMAP_INFO* bmp) +{ + if (index >= BITMAP_MAX) + { + ASSERT(false); + return -1; + } + s_bmp_map[index] = bmp; + return 0; +} + +const BITMAP_INFO* c_theme::get_bmp(BITMAP_TYPE index) +{ + if (index >= BITMAP_MAX) + { + ASSERT(false); + return 0; + } + return s_bmp_map[index]; +} + +int c_theme::add_color(COLOR_TYPE index, const unsigned int color) +{ + if (index >= COLOR_MAX) + { + ASSERT(false); + return -1; + } + s_color_map[index] = color; + return 0; +} + +const unsigned int c_theme::get_color(COLOR_TYPE index) +{ + if (index >= COLOR_MAX) + { + ASSERT(false); + return 0; + } + return s_color_map[index]; +} +c_wnd::c_wnd(): m_status(STATUS_NORMAL), m_attr(ATTR_VISIBLE), m_parent(0), m_top_child(0), m_prev_sibling(0), m_next_sibling(0), +m_str(0), m_font_color(0), m_bg_color(0), m_resource_id(0), m_z_order(Z_ORDER_LEVEL_0), m_focus_child(0), m_surface(0) +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); +} +int c_wnd::connect(c_wnd *parent, unsigned short resource_id, const char* str, + short x, short y, short width, short height, WND_TREE* p_child_tree ) +{ + if(0 == resource_id) + { + ASSERT(false); + return -1; + } + m_resource_id = resource_id; + set_str(str); + m_parent = parent; + m_status = STATUS_NORMAL; + if (parent) + { + m_z_order = parent->m_z_order; + m_surface = parent->m_surface; + } + if(0 == m_surface) + { + ASSERT(false); + return -2; + } + /* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/ + m_wnd_rect.m_left = x; + m_wnd_rect.m_top = y; + m_wnd_rect.m_right = (x + width - 1); + m_wnd_rect.m_bottom = (y + height - 1); + c_rect rect; + get_screen_rect(rect); + ASSERT(m_surface->is_valid(rect)); + pre_create_wnd(); + if ( 0 != parent ) + { + parent->add_child_2_tail(this); + } + if (load_child_wnd(p_child_tree) >= 0) + { + load_cmd_msg(); + on_init_children(); + } + return 0; +} +int c_wnd::load_child_wnd(WND_TREE *p_child_tree) +{ + if (0 == p_child_tree) + { + return 0; + } + int sum = 0; + WND_TREE* p_cur = p_child_tree; + while(p_cur->p_wnd) + { + if (0 != p_cur->p_wnd->m_resource_id) + {//This wnd has been used! Do not share! + ASSERT(false); + return -1; + } + else + { + p_cur->p_wnd->connect(this, p_cur->resource_id, p_cur->str, + p_cur->x, p_cur->y, p_cur->width, p_cur->height,p_cur->p_child_tree); + } + p_cur++; + sum++; + } + return sum; +} +c_wnd* c_wnd::connect_clone(c_wnd *parent, unsigned short resource_id, const char* str, + short x, short y, short width, short height, WND_TREE* p_child_tree ) +{ + if(0 == resource_id) + { + ASSERT(false); + return 0; + } + c_wnd* wnd = clone(); + wnd->m_resource_id = resource_id; + wnd->set_str(str); + wnd->m_parent = parent; + wnd->m_status = STATUS_NORMAL; + if (parent) + { + wnd->m_z_order = parent->m_z_order; + wnd->m_surface = parent->m_surface; + } + else + { + wnd->m_surface = m_surface; + } + if(0 == wnd->m_surface) + { + ASSERT(false); + return 0; + } + /* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/ + wnd->m_wnd_rect.m_left = x; + wnd->m_wnd_rect.m_top = y; + wnd->m_wnd_rect.m_right = (x + width - 1); + wnd->m_wnd_rect.m_bottom = (y + height - 1); + c_rect rect; + wnd->get_screen_rect(rect); + ASSERT(wnd->m_surface->is_valid(rect)); + wnd->pre_create_wnd(); + + if ( 0 != parent ) + { + parent->add_child_2_tail(wnd); + } + if (wnd->load_clone_child_wnd(p_child_tree) >= 0) + { + wnd->load_cmd_msg(); + wnd->on_init_children(); + } + return wnd; +} +int c_wnd::load_clone_child_wnd(WND_TREE *p_child_tree) +{ + if (0 == p_child_tree) + { + return 0; + } + int sum = 0; + WND_TREE* p_cur = p_child_tree; + while(p_cur->p_wnd) + { + p_cur->p_wnd->connect_clone(this, p_cur->resource_id, p_cur->str, + p_cur->x, p_cur->y, p_cur->width, p_cur->height,p_cur->p_child_tree); + p_cur++; + sum++; + } + return sum; +} +void c_wnd::disconnect() +{ + if (0 == m_resource_id) + { + return; + } + if (0 != m_top_child) + { + c_wnd *child = m_top_child; + c_wnd *next_child = 0; + while (child) + { + next_child = child->m_next_sibling; + child->disconnect(); + child = next_child; + } + } + if (0 != m_parent) + { + m_parent->unlink_child(this); + } + m_focus_child = 0; + m_resource_id = 0; +} +c_wnd* c_wnd::get_wnd_ptr(unsigned short id) const +{ + c_wnd *child = m_top_child; + while ( child ) + { + if ( child->get_id() == id ) + { + break; + } + child = child->m_next_sibling; + } + return child; +} +void c_wnd::set_attr(WND_ATTRIBUTION attr) +{ + m_attr = attr; + if ( ATTR_DISABLED == (attr & ATTR_DISABLED) ) + { + m_status = STATUS_DISABLED; + } + else + { + if (m_status == STATUS_DISABLED) + { + m_status = STATUS_NORMAL; + } + } +} +int c_wnd::is_focus_wnd() const +{ + if ( (m_attr & ATTR_VISIBLE) + && !(m_attr & ATTR_DISABLED) + && (m_attr & ATTR_FOCUS)) + { + return true; + } + else + { + return false; + } +} +void c_wnd::set_wnd_pos(short x, short y, short width, short height) +{ + m_wnd_rect.m_left = x; + m_wnd_rect.m_top = y; + m_wnd_rect.m_right = x + width - 1; + m_wnd_rect.m_bottom = y + height - 1; +} +void c_wnd::get_wnd_rect(c_rect &rect) const +{ + rect = m_wnd_rect; +} +void c_wnd::get_screen_rect(c_rect &rect) const +{ + rect.SetRect(0, 0, (m_wnd_rect.Width() - 1), (m_wnd_rect.Height() - 1)); + wnd2screen(rect); +} +void c_wnd::wnd2screen(int &x, int &y) const +{ + c_wnd *parent = m_parent; + c_rect rect; + x += m_wnd_rect.m_left; + y += m_wnd_rect.m_top; + while ( 0 != parent ) + { + parent->get_wnd_rect(rect); + x += rect.m_left; + y += rect.m_top; + parent = parent->m_parent; + } +} +void c_wnd::wnd2screen(c_rect &rect) const +{ + int l = rect.m_left; + int t = rect.m_top; + wnd2screen(l, t); + int r = (l + rect.Width() - 1); + int b = (t + rect.Height() - 1); + rect.SetRect(l, t, r, b); +} +c_wnd* c_wnd::set_child_focus(c_wnd * focus_child) +{ + ASSERT(0 != focus_child); + ASSERT(focus_child->m_parent == this); + c_wnd *old_focus_child = m_focus_child; + if (focus_child->is_focus_wnd()) + { + if (focus_child != old_focus_child ) + { + if (old_focus_child) + { + old_focus_child->on_kill_focus(); + } + m_focus_child = focus_child; + if (m_parent) + { + m_parent->set_child_focus(this); + } + m_focus_child->on_focus(); + } + } + return m_focus_child; +} +void c_wnd::add_child_2_tail(c_wnd *child) +{ + if( 0 == child )return; + if(child == get_wnd_ptr(child->m_resource_id))return; + if ( 0 == m_top_child ) + { + m_top_child = child; + child->m_prev_sibling = 0; + child->m_next_sibling = 0; + } + else + { + c_wnd *last_child = get_last_child(); + if (0 == last_child) + { + ASSERT(false); + } + last_child->m_next_sibling = child; + child->m_prev_sibling = last_child; + child->m_next_sibling = 0; + } +} +c_wnd* c_wnd::get_last_child() const +{ + if ( 0 == m_top_child ) + { + return 0; + } + c_wnd *child = m_top_child; + while ( child->m_next_sibling) + { + child = child->m_next_sibling; + } + return child; +} +int c_wnd::unlink_child(c_wnd *child) +{ + if ((0 == child) + || (this != child->m_parent)) + { + return -1; + } + if (0 == m_top_child) + { + return -2; + } + int find = false; + c_wnd *tmp_child = m_top_child; + if (tmp_child == child) + { + m_top_child = child->m_next_sibling; + if (0 != child->m_next_sibling) + { + child->m_next_sibling->m_prev_sibling = 0; + } + find = true; + } + else + { + while (tmp_child->m_next_sibling) + { + if (child == tmp_child->m_next_sibling) + { + tmp_child->m_next_sibling = child->m_next_sibling; + if (0 != child->m_next_sibling) + { + child->m_next_sibling->m_prev_sibling = tmp_child; + } + find = true; + break; + } + tmp_child = tmp_child->m_next_sibling; + } + } + if (true == find) + { + if (m_focus_child == child) + { + m_focus_child = 0; + } + child->m_next_sibling = 0; + child->m_prev_sibling = 0; + return 1; + } + else + { + return 0; + } +} +void c_wnd::show_window() +{ + if (ATTR_VISIBLE == (m_attr & ATTR_VISIBLE)) + { + on_paint(); + c_wnd *child = m_top_child; + if ( 0 != child ) + { + while ( child ) + { + child->show_window(); + child = child->m_next_sibling; + } + } + } +} +bool c_wnd::on_touch(int x, int y, TOUCH_ACTION action) +{ + c_rect rect; + x -= m_wnd_rect.m_left; + y -= m_wnd_rect.m_top; + c_wnd* child = m_top_child; + c_wnd* target_wnd = 0; + int target_z_order = Z_ORDER_LEVEL_0; + while (child) + { + if (ATTR_VISIBLE == (child->m_attr & ATTR_VISIBLE)) + { + child->get_wnd_rect(rect); + if (true == rect.PtInRect(x, y) || child->m_attr & ATTR_MODAL) + { + if (true == child->is_focus_wnd()) + { + if (child->m_z_order >= target_z_order) + { + target_wnd = child; + target_z_order = child->m_z_order; + } + } + } + } + child = child->m_next_sibling; + } + if (target_wnd == 0) + { + return false; + } + return target_wnd->on_touch(x, y, action); +} +bool c_wnd::on_key(KEY_TYPE key) +{ + ASSERT(key == KEY_FORWARD || key == KEY_BACKWARD || key == KEY_ENTER); + // Find current focus wnd. + c_wnd* old_focus_wnd = m_focus_child; + while (m_focus_child && m_focus_child->m_focus_child) + { + old_focus_wnd = m_focus_child->m_focus_child; + } + if (old_focus_wnd && !old_focus_wnd->on_key(key)) + { + return true; + } + // Default moving focus(Default handle KEY_FOWARD/KEY_BACKWARD) + if (key == KEY_ENTER) + { + return true; + } + if (!old_focus_wnd) + {// No current focus wnd, new one. + c_wnd *child = m_top_child; + c_wnd *new_focus_wnd = 0; + while (child) + { + if (ATTR_VISIBLE == (child->m_attr & ATTR_VISIBLE)) + { + if (true == child->is_focus_wnd()) + { + new_focus_wnd = child; + new_focus_wnd->m_parent->set_child_focus(new_focus_wnd); + child = child->m_top_child; + continue; + } + } + child = child->m_next_sibling; + } + return true; + } + // Move focus from old wnd to next wnd + c_wnd* next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_next_sibling : old_focus_wnd->m_prev_sibling; + while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd())) + {// Search neighbor of old focus wnd + next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling; + } + if (!next_focus_wnd) + {// Search whole brother wnd + next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_parent->m_top_child : old_focus_wnd->m_parent->get_last_child(); + while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd())) + { + next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling; + } + } + if (next_focus_wnd) + { + next_focus_wnd->m_parent->set_child_focus(next_focus_wnd); + } + return true; +} +void c_wnd::notify_parent(unsigned int msg_id, int param) +{ + if (!m_parent) + { + return; + } + const GL_MSG_ENTRY* entry = m_parent->FindMsgEntry(m_parent->GetMSgEntries(), MSG_TYPE_WND, msg_id, m_resource_id); + if (0 == entry) + { + return; + } + MSGFUNCS msg_funcs; + msg_funcs.func = entry->func; + switch (entry->callbackType) + { + case MSG_CALLBACK_VV: + (m_parent->*msg_funcs.func)(); + break; + case MSG_CALLBACK_VVL: + (m_parent->*msg_funcs.func_vvl)(param); + break; + case MSG_CALLBACK_VWV: + (m_parent->*msg_funcs.func_vwv)(m_resource_id); + break; + case MSG_CALLBACK_VWL: + (m_parent->*msg_funcs.func_vwl)(m_resource_id, param); + break; + default: + ASSERT(false); + break; + } +} +#include +#include +#define BUFFER_LEN 16 +unsigned char s_utf8_length_table[256] = +{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 +}; +inline static int get_utf8_code(const char* s, unsigned int& output_utf8_code) +{ + unsigned char* us = (unsigned char*)s; + int utf8_bytes = s_utf8_length_table[*us]; + switch (utf8_bytes) + { + case 1: + output_utf8_code = *us; + break; + case 2: + output_utf8_code = (*us << 8) | (*(us + 1)); + break; + case 3: + output_utf8_code = (*us << 16) | ((*(us + 1)) << 8) | *(us + 2); + break; + case 4: + output_utf8_code = (*us << 24) | ((*(us + 1)) << 16) | (*(us + 2) << 8) | *(us + 3); + break; + default: + ASSERT(false); + break; + } + return utf8_bytes; +} +void c_word::draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + char buf[BUFFER_LEN]; + value_2_string(value, dot_position, buf, BUFFER_LEN); + draw_string_in_rect(surface, z_order, buf, rect, font, font_color, bg_color, align_type); +} +void c_word::draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + char buf[BUFFER_LEN]; + value_2_string(value, dot_position, buf, BUFFER_LEN); + draw_string(surface, z_order, buf, x, y, font, font_color, bg_color, align_type); +} +void c_word::draw_string_in_rect(c_surface* surface, int z_order, const char *s, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + if(0 == s) + { + return; + } + int x, y; + get_string_pos(s, font, rect, align_type, x, y); + draw_string(surface, z_order, s, rect.m_left + x, rect.m_top + y, font, font_color, bg_color, ALIGN_LEFT); +} +void c_word::draw_string(c_surface* surface, int z_order, const char *s, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + if (0 == s) + { + return; + } + int offset = 0; + unsigned int utf8_code; + while (*s) + { + s += get_utf8_code(s, utf8_code); + offset += draw_single_char(surface, z_order, utf8_code, (x + offset), y, font, font_color, bg_color); + } +} +void c_word::value_2_string(int value, int dot_position, char* buf, int len) +{ + memset(buf, 0, len); + switch (dot_position) + { + case 0: + sprintf(buf, "%d", value); + break; + case 1: + sprintf(buf, "%.1f", value*1.0 / 10); + break; + case 2: + sprintf(buf, "%.2f", value*1.0 / 100); + break; + case 3: + sprintf(buf, "%.3f", value*1.0 / 1000); + break; + default: + ASSERT(false); + break; + } +} +const LATTICE* c_word::get_lattice(const FONT_INFO* font, unsigned int utf8_code) +{ + int first = 0; + int last = font->count - 1; + int middle = (first + last) / 2; + while (first <= last) + { + if (font->lattice_array[middle].utf8_code < utf8_code) + first = middle + 1; + else if (font->lattice_array[middle].utf8_code == utf8_code) + { + return &font->lattice_array[middle]; + } + else + { + last = middle - 1; + } + middle = (first + last) / 2; + } + return 0; +} +int c_word::draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color) +{ + unsigned int error_color = 0xFFFFFFFF; + if (font) + { + const LATTICE* p_lattice = get_lattice(font, utf8_code); + if (p_lattice) + { + draw_lattice(surface, z_order, x, y, p_lattice->width, font->height, p_lattice->pixel_gray_array, font_color, bg_color); + return p_lattice->width; + } + } + else + { + error_color = GL_RGB(255, 0, 0); + } + + //lattice/font not found, draw "X" + int len = 16; + for (int y_ = 0; y_ < len; y_++) + { + for (int x_ = 0; x_ < len; x_++) + { + int diff = (x_ - y_); + int sum = (x_ + y_); + (diff == 0 || diff == -1 || diff == 1 || sum == len || sum == (len - 1) || sum == (len + 1)) ? + surface->draw_pixel((x + x_), (y + y_), error_color, z_order) : surface->draw_pixel((x + x_), (y + y_), 0, z_order); + } + } + return len; +} +void c_word::draw_lattice(c_surface* surface, int z_order, int x, int y, int width, int height, + const unsigned char* p_data, unsigned int font_color, unsigned int bg_color) +{ + unsigned int r, g, b, rgb; + unsigned char blk_value = *p_data++; + unsigned char blk_cnt = *p_data++; + b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8; + g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8; + r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8; + rgb = GL_RGB(r, g, b); + for (int y_ = 0; y_ < height; y_++) + { + for (int x_ = 0; x_ < width; x_++) + { + ASSERT(blk_cnt); + if (0x00 == blk_value) + { + if (GL_ARGB_A(bg_color)) + { + surface->draw_pixel(x + x_, y + y_, bg_color, z_order); + } + } + else + { + surface->draw_pixel((x + x_), (y + y_), rgb, z_order); + } + if (--blk_cnt == 0) + {//reload new block + blk_value = *p_data++; + blk_cnt = *p_data++; + b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8; + g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8; + r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8; + rgb = GL_RGB(r, g, b); + } + } + } +} +int c_word::get_str_size(const char *s, const FONT_INFO* font, int& width, int& height) +{ + if(0 == s || 0 == font) + { + width = height = 0; + return -1; + } + int lattice_width = 0; + unsigned int utf8_code; + int utf8_bytes; + while (*s) + { + utf8_bytes = get_utf8_code(s, utf8_code); + const LATTICE* p_lattice = get_lattice(font, utf8_code); + lattice_width += p_lattice?p_lattice->width:font->height; + s += utf8_bytes; + } + width = lattice_width; + height = font->height; + return 0; +} +void c_word::get_string_pos(const char *s, const FONT_INFO* font, c_rect rect, unsigned int align_type, int &x, int &y) +{ + int x_size, y_size; + get_str_size(s, font, x_size, y_size); + int height = rect.m_bottom - rect.m_top + 1; + int width = rect.m_right - rect.m_left + 1; + x = y = 0; + switch (align_type & ALIGN_HMASK) + { + case ALIGN_HCENTER: + //m_text_org_x=0 + if (width > x_size) + { + x = (width - x_size)/2; + } + break; + case ALIGN_LEFT: + x = 0; + break; + case ALIGN_RIGHT: + //m_text_org_x=0 + if (width > x_size) + { + x = width - x_size; + } + break; + default: + ASSERT(0); + break; + } + switch (align_type & ALIGN_VMASK) + { + case ALIGN_VCENTER: + //m_text_org_y=0 + if (height > y_size) + { + y = (height - y_size)/2; + } + break; + case ALIGN_TOP: + y = 0; + break; + case ALIGN_BOTTOM: + //m_text_org_y=0 + if (height > y_size) + { + y = height - y_size; + } + break; + default: + ASSERT(0); + break; + } +} +#include + +static void(*do_assert)(const char* file, int line); +static void(*do_log_out)(const char* log); +void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log)) +{ + do_assert = my_assert; + do_log_out = my_log_out; +} + +void _assert(const char* file, int line) +{ + if(do_assert) + { + do_assert(file, line); + } + while(1); +} + +void log_out(const char* log) +{ + if (do_log_out) + { + do_log_out(log); + } +} + +long get_time_in_second() +{ + return 0; +} + +T_TIME second_to_day(long second) +{ + T_TIME ret = {0}; + return ret; +} + +T_TIME get_time() +{ + T_TIME ret = {0}; + return ret; +} + +void start_real_timer(void (*func)(void* arg)) +{ + log_out("Not support now"); +} + +void register_timer(int milli_second, void func(void* ptmr, void* parg)) +{ + log_out("Not support now"); +} + +unsigned int get_cur_thread_id() +{ + log_out("Not support now"); + return 0; +} + +void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg) +{ + log_out("Not support now"); +} + +extern "C" void delay_ms(unsigned short nms); +void thread_sleep(unsigned int milli_seconds) +{//MCU alway implemnet driver code in APP. + delay_ms(milli_seconds); +} + +int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data) +{ + log_out("Not support now"); + return 0; +} + +c_fifo::c_fifo() +{ + m_head = m_tail = 0; + m_read_sem = m_write_mutex = 0; +} + +int c_fifo::read(void* buf, int len) +{ + unsigned char* pbuf = (unsigned char*)buf; + int i = 0; + while(i < len) + { + if (m_tail == m_head) + {//empty + continue; + } + *pbuf++ = m_buf[m_head]; + m_head = (m_head + 1) % FIFO_BUFFER_LEN; + i++; + } + if(i != len) + { + ASSERT(false); + } + return i; +} + +int c_fifo::write(void* buf, int len) +{ + unsigned char* pbuf = (unsigned char*)buf; + int i = 0; + int tail = m_tail; + + while(i < len) + { + if ((m_tail + 1) % FIFO_BUFFER_LEN == m_head) + {//full, clear data has been written; + m_tail = tail; + log_out("Warning: fifo full\n"); + return 0; + } + m_buf[m_tail] = *pbuf++; + m_tail = (m_tail + 1) % FIFO_BUFFER_LEN; + i++; + } + + if(i != len) + { + ASSERT(false); + } + return i; +} +void c_button::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); +} +void c_button::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_button::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +bool c_button::on_touch(int x, int y, TOUCH_ACTION action) +{ + if (action == TOUCH_DOWN) + { + m_parent->set_child_focus(this); + m_status = STATUS_PUSHED; + on_paint(); + } + else + { + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_BN_CLICKED, 0); + } + return true; +} +bool c_button::on_key(KEY_TYPE key) +{ + if (key == KEY_ENTER) + { + notify_parent(GL_BN_CLICKED, 0); + return false;// Do not handle KEY_ENTER by other wnd. + } + return true;// Handle KEY_FOWARD/KEY_BACKWARD by parent wnd. +} +void c_button::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + case STATUS_FOCUSED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + default: + ASSERT(false); + break; + } +} +DIALOG_ARRAY c_dialog::ms_the_dialogs[SURFACE_CNT_MAX]; +void c_dialog::pre_create_wnd() +{ + m_attr = WND_ATTRIBUTION(0);// no focus/visible + m_z_order = Z_ORDER_LEVEL_1; + m_bg_color = GL_RGB(33, 42, 53); +} +void c_dialog::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + m_surface->fill_rect(rect, m_bg_color, m_z_order); + if (m_str) + { + c_word::draw_string(m_surface, m_z_order, m_str, rect.m_left+35, rect.m_top, c_theme::get_font(FONT_DEFAULT), GL_RGB(255, 255, 255), GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + } +} +c_dialog* c_dialog::get_the_dialog(c_surface* surface) +{ + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + return ms_the_dialogs[i].dialog; + } + } + return 0; +} +int c_dialog::open_dialog(c_dialog* p_dlg, bool modal_mode) +{ + if (0 == p_dlg) + { + ASSERT(false); + return 0; + } + c_dialog* cur_dlg = get_the_dialog(p_dlg->get_surface()); + if (cur_dlg == p_dlg) + { + return 1; + } + if(cur_dlg) + { + cur_dlg->set_attr(WND_ATTRIBUTION(0)); + } + c_rect rc; + p_dlg->get_screen_rect(rc); + p_dlg->get_surface()->set_frame_layer_visible_rect(rc, Z_ORDER_LEVEL_1); + p_dlg->set_attr(modal_mode ? (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL) : (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)); + p_dlg->show_window(); + p_dlg->set_me_the_dialog(); + return 1; +} +int c_dialog::close_dialog(c_surface* surface) +{ + c_dialog* dlg = get_the_dialog(surface); + if (0 == dlg) + { + return 0; + } + c_rect rc; + + dlg->set_attr(WND_ATTRIBUTION(0)); + surface->set_frame_layer_visible_rect(rc, dlg->m_z_order); + //clear the dialog + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + ms_the_dialogs[i].dialog = 0; + return 1; + } + } + ASSERT(false); + return -1; +} +int c_dialog::set_me_the_dialog() +{ + c_surface* surface = get_surface(); + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + ms_the_dialogs[i].dialog = this; + return 0; + } + } + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == 0) + { + ms_the_dialogs[i].dialog = this; + if(this) + { + ms_the_dialogs[i].surface = surface; + } + return 1; + } + } + ASSERT(false); + return -2; +} +#include +#define IDD_KEY_BOARD 0x1 +GL_BEGIN_MESSAGE_MAP(c_edit) +ON_KEYBORAD_UPDATE(IDD_KEY_BOARD, c_edit::on_key_board_click) +GL_END_MESSAGE_MAP() +static c_keyboard s_keyboard; +void c_edit::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_kb_style = STYLE_ALL_BOARD; + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); + memset(m_str_input, 0, sizeof(m_str_input)); + memset(m_str, 0, sizeof(m_str)); + set_text(c_wnd::m_str); +} +void c_edit::set_text(const char* str) +{ + if (str != 0 && strlen(str) < sizeof(m_str)) + { + strcpy(m_str, str); + } +} +bool c_edit::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return true; +} +void c_edit::on_touch_down(int x, int y) +{ + c_rect kb_rect_relate_2_edit_parent; + s_keyboard.get_wnd_rect(kb_rect_relate_2_edit_parent); + kb_rect_relate_2_edit_parent.m_left += m_wnd_rect.m_left; + kb_rect_relate_2_edit_parent.m_right += m_wnd_rect.m_left; + kb_rect_relate_2_edit_parent.m_top += m_wnd_rect.m_top; + kb_rect_relate_2_edit_parent.m_bottom += m_wnd_rect.m_top; + if (m_wnd_rect.PtInRect(x, y)) + {//click edit box + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } + } + else if (kb_rect_relate_2_edit_parent.PtInRect(x,y)) + {//click key board + c_wnd::on_touch(x, y, TOUCH_DOWN); + } + else + { + if (STATUS_PUSHED == m_status) + { + m_status = STATUS_FOCUSED; + on_paint(); + } + } +} +void c_edit::on_touch_up(int x, int y) +{ + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + if (m_wnd_rect.PtInRect(x,y)) + {//click edit box + m_status = STATUS_FOCUSED; + on_paint(); + } + else + { + c_wnd::on_touch(x, y, TOUCH_UP); + } + } +} +void c_edit::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_edit::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +void c_edit::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + c_rect empty_rect; + empty_rect.Empty(); + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + s_keyboard.disconnect(); + m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + s_keyboard.disconnect(); + m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); + show_keyboard(); + } + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_PUSHED), m_parent->get_z_order()); + m_surface->draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_BORDER), m_parent->get_z_order(), 2); + strlen(m_str_input) ? c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str_input, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER) : + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + break; + default: + ASSERT(false); + } +} +void c_edit::show_keyboard() +{ + s_keyboard.connect(this, IDD_KEY_BOARD, m_kb_style); + c_rect kb_rect; + s_keyboard.get_screen_rect(kb_rect); + m_surface->set_frame_layer_visible_rect(kb_rect, s_keyboard.get_z_order()); + s_keyboard.show_window(); +} +void c_edit::on_key_board_click(unsigned int ctrl_id, long param) +{ + switch (param) + { + case CLICK_CHAR: + strcpy(m_str_input, s_keyboard.get_str()); + on_paint(); + break; + case CLICK_ENTER: + if (strlen(m_str_input)) + { + memcpy(m_str, m_str_input, sizeof(m_str_input)); + } + m_status = STATUS_FOCUSED; + on_paint(); + break; + case CLICK_ESC: + memset(m_str_input, 0, sizeof(m_str_input)); + m_status = STATUS_FOCUSED; + on_paint(); + break; + default: + ASSERT(false); + break; + } +} +#include +//#define SWIPE_STEP 300//for arm +#define SWIPE_STEP 10//for PC & ANDROID +#define MOVE_THRESHOLD 10 +c_gesture::c_gesture(c_slide_group* group) +{ + m_slide_group = group; + m_state = TOUCH_IDLE; + m_down_x = m_down_y = m_move_x = m_move_y = 0; +} +bool c_gesture::handle_swipe(int x, int y, TOUCH_ACTION action) +{ + if(action == TOUCH_DOWN)//MOUSE_LBUTTONDOWN + { + if(m_state == TOUCH_IDLE) + { + m_state = TOUCH_MOVE; + m_move_x = m_down_x = x; + return true; + } + else//TOUCH_MOVE + { + return on_move(x); + } + } + else if(action == TOUCH_UP)//MOUSE_LBUTTONUP + { + if(m_state == TOUCH_MOVE) + { + m_state = TOUCH_IDLE; + return on_swipe(x); + } + else + { + return false; + //ASSERT(false); + } + } + return true; +} +bool c_gesture::on_move(int x) +{ + if (m_slide_group == 0) + { + return true; + } + if (abs(x - m_move_x) < MOVE_THRESHOLD) + { + return false; + } + m_slide_group->disabel_all_slide(); + m_move_x = x; + if ((m_move_x - m_down_x) > 0) + { + move_right(); + } + else + { + move_left(); + } + return false; +} +bool c_gesture::on_swipe(int x) +{ + if (m_slide_group == 0) + { + return true; + } + if ((m_down_x == m_move_x) && (abs(x - m_down_x) < MOVE_THRESHOLD)) + { + return true; + } + m_slide_group->disabel_all_slide(); + int page = -1; + m_move_x = x; + if ((m_move_x - m_down_x) > 0) + { + page = swipe_right(); + } + else + { + page = swipe_left(); + } + if (page >= 0) + { + m_slide_group->set_active_slide(page); + } + else + { + m_slide_group->set_active_slide(m_slide_group->get_active_slide_index(), false); + } + return false; +} +int c_gesture::swipe_left() +{ + if (m_slide_group == 0) + { + return -1; + } + int index = m_slide_group->get_active_slide_index(); + if((index + 1) >= MAX_PAGES || + m_slide_group->get_slide(index + 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return -2; + } + c_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + if (s1->get_display() != s2->get_display()) + { + return -3; + } + int step = m_down_x - m_move_x; + c_rect rc; + m_slide_group->get_screen_rect(rc); + while(step < rc.Width()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step); + step += SWIPE_STEP; + } + if (step != rc.Width()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, rc.Width()); + } + return (index + 1); +} +int c_gesture::swipe_right() +{ + if (m_slide_group == 0) + { + return -1; + } + int index = m_slide_group->get_active_slide_index(); + if(index <= 0 || + m_slide_group->get_slide(index - 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return -2; + } + c_surface* s1 = m_slide_group->get_slide(index -1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + if (s1->get_display() != s2->get_display()) + { + return -3; + } + c_rect rc; + m_slide_group->get_screen_rect(rc); + int step = rc.Width() - (m_move_x - m_down_x); + while(step > 0) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step); + step -= SWIPE_STEP; + } + if (step != 0) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, 0); + } + return (index - 1); +} +void c_gesture::move_left() +{ + int index = m_slide_group->get_active_slide_index(); + if((index + 1) >= MAX_PAGES || + m_slide_group->get_slide(index + 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return; + } + c_surface* s1 = m_slide_group->get_slide(index +1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + c_rect rc; + m_slide_group->get_screen_rect(rc); + if(s1->get_display() == s2->get_display()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (m_down_x - m_move_x)); + } +} +void c_gesture::move_right() +{ + int index = m_slide_group->get_active_slide_index(); + if(index <= 0 || + m_slide_group->get_slide(index - 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return; + } + c_surface* s1 = m_slide_group->get_slide(index -1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + c_rect rc; + m_slide_group->get_screen_rect(rc); + if(s1->get_display() == s2->get_display()) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (rc.Width() - (m_move_x - m_down_x))); + } +} +#include +//Changing key width/height will change the width/height of keyboard +#define KEY_WIDTH 65 +#define KEY_HEIGHT 38 +#define KEYBOARD_WIDTH ((KEY_WIDTH + 2) * 10) +#define KEYBOARD_HEIGHT ((KEY_HEIGHT + 2) * 4) +#define NUM_BOARD_WIDTH ((KEY_WIDTH + 2) * 4) +#define NUM_BOARD_HEIGHT ((KEY_HEIGHT + 2) * 4) +#define CAPS_WIDTH (KEY_WIDTH * 3 / 2) +#define DEL_WIDTH (KEY_WIDTH * 3 / 2 + 1) +#define ESC_WIDTH (KEY_WIDTH * 2 + 2) +#define SWITCH_WIDTH (KEY_WIDTH * 3 / 2 ) +#define SPACE_WIDTH (KEY_WIDTH * 3 + 2 * 2) +#define DOT_WIDTH (KEY_WIDTH * 3 / 2 + 3) +#define ENTER_WIDTH (KEY_WIDTH * 2 + 2) +#define POS_X(c) ((KEY_WIDTH * c) + (c + 1) * 2) +#define POS_Y(r) ((KEY_HEIGHT * r) + (r + 1) * 2) +static c_keyboard_button s_button_0,s_button_1, s_button_2, s_button_3, s_button_4, s_button_5, s_button_6, s_button_7, s_button_8, s_button_9; +static c_keyboard_button s_button_A, s_button_B, s_button_C, s_button_D, s_button_E, s_button_F, s_button_G, s_button_H, s_button_I, s_button_J; +static c_keyboard_button s_button_K, s_button_L, s_button_M, s_button_N, s_button_O, s_button_P, s_button_Q, s_button_R, s_button_S, s_button_T; +static c_keyboard_button s_button_U, s_button_V, s_button_W, s_button_X, s_button_Y, s_button_Z; +static c_keyboard_button s_button_dot, s_button_caps, s_button_space, s_button_enter, s_button_del, s_button_esc, s_button_num_switch; +WND_TREE g_key_board_children[] = +{ + //Row 1 + {&s_button_Q, 'Q', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_W, 'W', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_E, 'E', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_R, 'R', 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_T, 'T', 0, POS_X(4), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_Y, 'Y', 0, POS_X(5), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_U, 'U', 0, POS_X(6), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_I, 'I', 0, POS_X(7), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_O, 'O', 0, POS_X(8), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_P, 'P', 0, POS_X(9), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + //Row 2 + {&s_button_A, 'A', 0, ((KEY_WIDTH / 2) + POS_X(0)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_S, 'S', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_D, 'D', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_F, 'F', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_G, 'G', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_H, 'H', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_J, 'J', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_K, 'K', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_L, 'L', 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + //Row 3 + {&s_button_caps, 0x14, 0, POS_X(0), POS_Y(2), CAPS_WIDTH, KEY_HEIGHT}, + {&s_button_Z, 'Z', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_X, 'X', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_C, 'C', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_V, 'V', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_B, 'B', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_N, 'N', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_M, 'M', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_del, 0x7F, 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(2), DEL_WIDTH, KEY_HEIGHT}, + //Row 4 + {&s_button_esc, 0x1B, 0, POS_X(0), POS_Y(3), ESC_WIDTH, KEY_HEIGHT}, + {&s_button_num_switch, 0x90, 0, POS_X(2), POS_Y(3), SWITCH_WIDTH, KEY_HEIGHT}, + {&s_button_space, ' ', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(3), SPACE_WIDTH, KEY_HEIGHT}, + {&s_button_dot, '.', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(3), DOT_WIDTH, KEY_HEIGHT}, + {&s_button_enter, '\n', 0, POS_X(8), POS_Y(3), ENTER_WIDTH, KEY_HEIGHT}, + {0,0,0,0,0,0,0} +}; +WND_TREE g_number_board_children[] = +{ + {&s_button_1, '1', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_2, '2', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_3, '3', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_del, 0x7F, 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT * 2 + 2}, + {&s_button_4, '4', 0, POS_X(0), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_5, '5', 0, POS_X(1), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_6, '6', 0, POS_X(2), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_7, '7', 0, POS_X(0), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_8, '8', 0, POS_X(1), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_9, '9', 0, POS_X(2), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_enter,'\n', 0, POS_X(3), POS_Y(2), KEY_WIDTH, KEY_HEIGHT * 2 + 2}, + {&s_button_esc, 0x1B, 0, POS_X(0), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_0, '0', 0, POS_X(1), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_dot, '.', 0, POS_X(2), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {0,0,0,0,0,0,0} +}; +GL_BEGIN_MESSAGE_MAP(c_keyboard) +ON_GL_BN_CLICKED('A', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('B', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('C', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('D', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('E', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('F', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('G', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('H', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('I', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('J', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('K', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('L', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('M', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('N', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('O', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('P', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Q', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('R', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('S', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('T', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('U', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('V', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('W', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('X', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Y', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Z', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('0', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('1', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('2', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('3', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('4', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('5', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('6', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('7', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('8', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('9', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED(' ', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('.', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED(0x7F, c_keyboard::on_del_clicked) +ON_GL_BN_CLICKED(0x14, c_keyboard::on_caps_clicked) +ON_GL_BN_CLICKED('\n', c_keyboard::on_enter_clicked) +ON_GL_BN_CLICKED(0x1B, c_keyboard::on_esc_clicked) +GL_END_MESSAGE_MAP() +int c_keyboard::connect(c_wnd *user, unsigned short resource_id, KEYBOARD_STYLE style) +{ + c_rect user_rect; + user->get_wnd_rect(user_rect); + if (style == STYLE_ALL_BOARD) + {//Place keyboard at the bottom of user's parent window. + c_rect user_parent_rect; + user->get_parent()->get_wnd_rect(user_parent_rect); + return c_wnd::connect(user, resource_id, 0, (0 - user_rect.m_left), (user_parent_rect.Height() - user_rect.m_top - KEYBOARD_HEIGHT), KEYBOARD_WIDTH, KEYBOARD_HEIGHT, g_key_board_children); + } + else if(style == STYLE_NUM_BOARD) + {//Place keyboard below the user window. + return c_wnd::connect(user, resource_id, 0, 0, user_rect.Height(), NUM_BOARD_WIDTH, NUM_BOARD_HEIGHT, g_number_board_children); + } + else + { + ASSERT(false); + } + return -1; +} +void c_keyboard::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_cap_status = STATUS_UPPERCASE; + memset(m_str, 0, sizeof(m_str)); + m_str_len = 0; +} +void c_keyboard::on_caps_clicked(unsigned int ctrl_id) +{ + m_cap_status = (m_cap_status == STATUS_LOWERCASE) ? STATUS_UPPERCASE : STATUS_LOWERCASE; + show_window(); +} +void c_keyboard::on_enter_clicked(unsigned int ctrl_id) +{ + memset(m_str, 0, sizeof(m_str)); + notify_parent(KEYBORAD_CLICK, CLICK_ENTER); +} +void c_keyboard::on_esc_clicked(unsigned int ctrl_id) +{ + memset(m_str, 0, sizeof(m_str)); + notify_parent(KEYBORAD_CLICK, CLICK_ESC); +} +void c_keyboard::on_del_clicked(unsigned int ctrl_id) +{ + if (m_str_len <= 0) + { + return; + } + m_str[--m_str_len] = 0; + notify_parent(KEYBORAD_CLICK, CLICK_CHAR); +} +void c_keyboard::on_char_clicked(unsigned int ctrl_id) +{//ctrl_id = char ascii code. + if (m_str_len >= sizeof(m_str)) + { + return; + } + if ((ctrl_id >= '0' && ctrl_id <= '9') || ctrl_id == ' ' || ctrl_id == '.') + { + goto InputChar; + } + if (ctrl_id >= 'A' && ctrl_id <= 'Z') + { + if (STATUS_LOWERCASE == m_cap_status) + { + ctrl_id += 0x20; + } + goto InputChar; + } + ASSERT(false); +InputChar: + m_str[m_str_len++] = ctrl_id; + notify_parent(KEYBORAD_CLICK, CLICK_CHAR); +} +void c_keyboard::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + m_surface->fill_rect(rect, GL_RGB(0, 0, 0), m_z_order); +} +void c_keyboard_button::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + break; + case STATUS_FOCUSED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + break; + default: + ASSERT(false); + break; + } + + if (m_resource_id == 0x14) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Caps", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x1B) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Esc", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == ' ') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Space", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == '\n') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Enter", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == '.') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, ".", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x7F) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Back", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x90) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "?123", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + + char letter[] = { 0, 0 }; + if (m_resource_id >= 'A' && m_resource_id <= 'Z') + { + letter[0] = (((c_keyboard*)m_parent)->get_cap_status() == STATUS_UPPERCASE) ? m_resource_id : (m_resource_id + 0x20); + } + else if (m_resource_id >= '0' && m_resource_id <= '9') + { + letter[0] = m_resource_id; + } + c_word::draw_string_in_rect(m_surface, m_z_order, letter, rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); +} +void c_label::pre_create_wnd() +{ + m_attr = ATTR_VISIBLE; + m_font_color = c_theme::get_color(COLOR_WND_FONT); + m_font_type = c_theme::get_font(FONT_DEFAULT); +} +void c_label::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + if (m_str) + { + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, m_parent->get_bg_color(), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, m_parent->get_bg_color(), ALIGN_LEFT | ALIGN_VCENTER); + } +} +#include +#define ITEM_HEIGHT 45 +void c_list_box::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + memset(m_item_array, 0, sizeof(m_item_array)); + m_item_total = 0; + m_selected_item = 0; + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); +} +void c_list_box::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_list_box::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +void c_list_box::on_paint() +{ + c_rect rect, empty_rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, GL_RGB(2, 124, 165), GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER | ALIGN_VCENTER); + //draw list + if (m_item_total > 0) + { + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + } + m_surface->set_frame_layer_visible_rect(m_list_screen_rect, m_z_order); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); + show_list(); + } + break; + default: + ASSERT(false); + } +} +bool c_list_box::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return true; +} +void c_list_box::on_touch_down(int x, int y) +{ + if (m_wnd_rect.PtInRect(x, y) ) + {//click base + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } + } + else if (m_list_wnd_rect.PtInRect(x, y)) + {//click extend list + c_wnd::on_touch(x, y, TOUCH_DOWN); + } + else + { + if (STATUS_PUSHED == m_status) + { + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_LIST_CONFIRM, m_selected_item); + } + } +} +void c_list_box::on_touch_up(int x, int y) +{ + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + if (m_wnd_rect.PtInRect(x, y)) + {//click base + m_status = STATUS_FOCUSED; + on_paint(); + } + else if (m_list_wnd_rect.PtInRect(x, y)) + {//click extend list + m_status = STATUS_FOCUSED; + select_item((y - m_list_wnd_rect.m_top) / ITEM_HEIGHT); + on_paint(); + notify_parent(GL_LIST_CONFIRM, m_selected_item); + } + else + { + c_wnd::on_touch(x, y, TOUCH_UP); + } + } +} +void c_list_box::update_list_size() +{ + m_list_wnd_rect = m_wnd_rect; + m_list_wnd_rect.m_top = m_wnd_rect.m_bottom + 1; + m_list_wnd_rect.m_bottom = m_list_wnd_rect.m_top + m_item_total * ITEM_HEIGHT; + get_screen_rect(m_list_screen_rect); + m_list_screen_rect.m_top = m_list_screen_rect.m_bottom + 1; + m_list_screen_rect.m_bottom = m_list_screen_rect.m_top + m_item_total * ITEM_HEIGHT; +} +void c_list_box::show_list() +{ + //draw all items + c_rect tmp_rect; + for (int i = 0; i < m_item_total; i++) + { + tmp_rect.m_left = m_list_screen_rect.m_left; + tmp_rect.m_right = m_list_screen_rect.m_right; + tmp_rect.m_top = m_list_screen_rect.m_top + i * ITEM_HEIGHT; + tmp_rect.m_bottom = tmp_rect.m_top + ITEM_HEIGHT; + if (m_selected_item == i) + { + m_surface->fill_rect(tmp_rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + } + else + { + m_surface->fill_rect(tmp_rect, GL_RGB(17, 17, 17), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font_type, m_font_color, GL_RGB(17, 17, 17), ALIGN_HCENTER | ALIGN_VCENTER); + } + } +} +int c_list_box::add_item(char* str) +{ + if (m_item_total >= MAX_ITEM_NUM) + { + ASSERT(false); + return -1; + } + m_item_array[m_item_total++] = str; + update_list_size(); + return 0; +} +void c_list_box::clear_item() +{ + m_selected_item = m_item_total = 0; + memset(m_item_array, 0, sizeof(m_item_array)); + update_list_size(); +} +void c_list_box::select_item(short index) +{ + if (index < 0 || index >= m_item_total) + { + ASSERT(false); + } + m_selected_item = index; +} +c_slide_group::c_slide_group() +{ + m_gesture = new c_gesture(this); + for(int i = 0; i < MAX_PAGES; i++) + { + m_slides[i] = 0; + } + m_active_slide_index = 0; +} +int c_slide_group::set_active_slide(int index, bool is_redraw) +{ + if(index >= MAX_PAGES || index < 0) + { + return -1; + } + if(0 == m_slides[index]) + { + return -2; + } + m_active_slide_index = index; + for(int i = 0; i < MAX_PAGES; i++) + { + if(m_slides[i] == 0) + { + continue; + } + if(i == index) + { + m_slides[i]->get_surface()->set_active(true); + add_child_2_tail(m_slides[i]); + if(is_redraw) + { + c_rect rc; + get_screen_rect(rc); + m_slides[i]->get_surface()->flush_screen(rc.m_left, rc.m_top, rc.m_right, rc.m_bottom); + } + } + else + { + m_slides[i]->get_surface()->set_active(false); + } + } + return 0; +} +int c_slide_group::add_slide(c_wnd* slide, unsigned short resource_id, short x, short y, + short width, short height, WND_TREE* p_child_tree, Z_ORDER_LEVEL max_zorder) +{ + if(0 == slide) + { + return -1; + } + c_surface* old_surface = get_surface(); + c_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder); + new_surface->set_active(false); + set_surface(new_surface); + slide->connect(this, resource_id ,0 , x, y, width, height, p_child_tree); + set_surface(old_surface); + int i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == slide) + {//slide has lived + ASSERT(false); + return -2; + } + i++; + } + //new slide + i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == 0) + { + m_slides[i] = slide; + slide->show_window(); + return 0; + } + i++; + } + //no more slide can be add + ASSERT(false); + return -3; +} +int c_slide_group::add_clone_silde(c_wnd* slide, unsigned short resource_id, short x, short y, + short width, short height, WND_TREE* p_child_tree, Z_ORDER_LEVEL max_zorder) +{ + if(0 == slide) + { + return -1; + } + c_surface* old_surface = get_surface(); + c_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder); + new_surface->set_active(false); + set_surface(new_surface); + c_wnd* page_tmp = slide->connect_clone(this,resource_id,0,x,y,width,height,p_child_tree); + set_surface(old_surface); + int i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == page_tmp) + {//slide has lived + ASSERT(false); + return -2; + } + i++; + } + //new slide + i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == 0) + { + m_slides[i] = page_tmp; + page_tmp->show_window(); + return 0; + } + i++; + } + //no more slide can be add + ASSERT(false); + return -3; +} +void c_slide_group::disabel_all_slide() +{ + for(int i = 0; i < MAX_PAGES; i++) + { + if(m_slides[i]) + { + m_slides[i]->get_surface()->set_active(false); + } + } +} +bool c_slide_group::on_touch(int x, int y, TOUCH_ACTION action) +{ + x -= m_wnd_rect.m_left; + y -= m_wnd_rect.m_top; + if (m_gesture->handle_swipe(x, y, action)) + { + if (m_slides[m_active_slide_index]) + { + m_slides[m_active_slide_index]->on_touch(x, y, action); + } + } + return true; +} +bool c_slide_group::on_key(KEY_TYPE key) +{ + if (m_slides[m_active_slide_index]) + { + m_slides[m_active_slide_index]->on_key(key); + } + return true; +} +#define ARROW_BT_HEIGHT 55 +#define ID_BT_ARROW_UP 1 +#define ID_BT_ARROW_DOWN 2 +GL_BEGIN_MESSAGE_MAP(c_spin_box) +ON_GL_BN_CLICKED(ID_BT_ARROW_UP, c_spin_box::on_arrow_up_bt_click) +ON_GL_BN_CLICKED(ID_BT_ARROW_DOWN, c_spin_box::on_arrow_down_bt_click) +GL_END_MESSAGE_MAP() +void c_spin_box::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); + m_max = 6; + m_min = 1; + m_digit = 0; + m_step = 1; + //set arrow button position. + c_rect rect; + get_screen_rect(rect); + m_bt_up_rect.m_left = rect.m_left; + m_bt_up_rect.m_right = rect.m_left + rect.Width() / 2 - 1; + m_bt_up_rect.m_top = rect.m_bottom + 1; + m_bt_up_rect.m_bottom = m_bt_up_rect.m_top + ARROW_BT_HEIGHT; + m_bt_down_rect.m_left = rect.m_left + rect.Width() / 2; + m_bt_down_rect.m_right = rect.m_right; + m_bt_down_rect.m_top = rect.m_bottom + 1; + m_bt_down_rect.m_bottom = m_bt_down_rect.m_top + ARROW_BT_HEIGHT; +} +bool c_spin_box::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return c_wnd::on_touch(x, y, action); +} +void c_spin_box::on_touch_down(int x, int y) +{ + if (false == m_wnd_rect.PtInRect(x, y)) + {//maybe click on up/down arrow button + return; + } + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } +} +void c_spin_box::on_touch_up(int x, int y) +{ + if (false == m_wnd_rect.PtInRect(x, y)) + {//maybe click on up/down arrow button + return; + } + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + m_value = m_cur_value; + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_SPIN_CONFIRM, m_value); + } +} +void c_spin_box::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_spin_box::on_kill_focus() +{ + m_cur_value = m_value; + m_status = STATUS_NORMAL; + on_paint(); +} +void c_spin_box::show_arrow_button() +{ + m_bt_up.connect(this, ID_BT_ARROW_UP, "\xe2\x96\xb2"/*unicode of up arrow*/, 0, m_wnd_rect.Height(), m_bt_up_rect.Width(),m_bt_up_rect.Height()); + m_bt_up.show_window(); + m_bt_down.connect(this, ID_BT_ARROW_DOWN, "\xe2\x96\xbc"/*unicode of down arrow*/, m_bt_up_rect.Width(), m_wnd_rect.Height(), m_bt_down_rect.Width(),m_bt_down_rect.Height()); + m_bt_down.show_window(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); +} +void c_spin_box::hide_arrow_button() +{ + m_bt_up.disconnect(); + m_bt_down.disconnect(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); +} +void c_spin_box::on_paint() +{ + c_rect rect, tmp_rect, empty_rect; + get_screen_rect(rect); + tmp_rect.m_left = rect.m_left; + tmp_rect.m_right = rect.m_right; + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + hide_arrow_button(); + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + hide_arrow_button(); + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + } + tmp_rect.m_top = m_bt_down_rect.m_top; + tmp_rect.m_bottom = m_bt_down_rect.m_bottom; + m_surface->set_frame_layer_visible_rect(tmp_rect, m_z_order); + show_arrow_button(); + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_PUSHED), m_parent->get_z_order()); + m_surface->draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_BORDER), m_parent->get_z_order(), 2); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + break; + default: + ASSERT(false); + } +} +void c_spin_box::on_arrow_up_bt_click(unsigned int ctr_id) +{ + if (m_cur_value + m_step > m_max) + { + return; + } + m_cur_value += m_step; + notify_parent(GL_SPIN_CHANGE, m_cur_value); + on_paint(); +} +void c_spin_box::on_arrow_down_bt_click(unsigned int ctr_id) +{ + if (m_cur_value - m_step < m_min) + { + return; + } + m_cur_value -= m_step; + notify_parent(GL_SPIN_CHANGE, m_cur_value); + on_paint(); +} +void c_table::set_item(int row, int col, char* str, unsigned int color) +{ + draw_item( row, col, str, color); +} +void c_table::draw_item(int row, int col, const char* str, unsigned int color) +{ + c_rect rect = get_item_rect(row, col); + m_surface->fill_rect(rect.m_left+1, rect.m_top+1, rect.m_right-1, rect.m_bottom-1, color, m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, str, rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_align_type); +} +void c_table::set_row_height(unsigned int height) +{ + for (unsigned int i = 0; i < m_row_num; i ++) + { + m_row_height[i] = height; + } +} +void c_table::set_col_width(unsigned int width) +{ + for (unsigned int i = 0; i < m_col_num; i ++) + { + m_col_width[i] = width; + } +} +int c_table::set_row_height(unsigned int index, unsigned int height) +{ + if (m_row_num > index) + { + m_row_height[index] = height; + return index; + } + return -1; +} +int c_table::set_col_width(unsigned int index, unsigned int width) +{ + if (m_col_num > index) + { + m_col_width[index] = width; + return index; + } + return -1; +} +c_rect c_table::get_item_rect(int row, int col) +{ + static c_rect rect; + if (row >= MAX_ROW_NUM || col >= MAX_COL_NUM) + { + return rect; + } + unsigned int width = 0; + unsigned int height = 0; + for (int i = 0; i < col; i++) + { + width += m_col_width[i]; + } + for (int j = 0; j < row; j++) + { + height += m_row_height[j]; + } + c_rect wRect; + get_screen_rect(wRect); + rect.m_left = wRect.m_left + width; + rect.m_right = rect.m_left + m_col_width[col]; + if (rect.m_right > wRect.m_right) + { + rect.m_right = wRect.m_right; + } + rect.m_top = wRect.m_top + height; + rect.m_bottom = rect.m_top + m_row_height[row]; + if (rect.m_bottom > wRect.m_bottom) + { + rect.m_bottom = wRect.m_bottom; + } + return rect; +} +#include +#include +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) +c_wave_buffer::c_wave_buffer() +{ + m_head = m_tail = m_min_old = m_max_old = + m_min_older = m_max_older = m_last_data = m_read_cache_sum = m_refresh_sequence = 0; + memset(m_wave_buf, 0, sizeof(m_wave_buf)); + memset(m_read_cache_min, 0, sizeof(m_read_cache_min)); + memset(m_read_cache_mid, 0, sizeof(m_read_cache_mid)); + memset(m_read_cache_max, 0, sizeof(m_read_cache_max)); +} +short c_wave_buffer::get_cnt() +{ + return (m_tail >= m_head)?(m_tail - m_head):(m_tail - m_head + WAVE_BUFFER_LEN); +} +int c_wave_buffer::write_wave_data(short data) +{ + if ((m_tail + 1) % WAVE_BUFFER_LEN == m_head) + {//full + //log_out("wave buf full\n"); + return BUFFER_FULL; + } + m_wave_buf[m_tail] = data; + m_tail = (m_tail + 1) % WAVE_BUFFER_LEN; + return 1; +} +int c_wave_buffer::read_data() +{ + if (m_head == m_tail) + {//empty + //log_out("wave buf empty\n"); + return BUFFER_EMPTY; + } + int ret = m_wave_buf[m_head]; + m_head = (m_head + 1) % WAVE_BUFFER_LEN; + return ret; +} +int c_wave_buffer::read_wave_data_by_frame(short &max, short &min, short frame_len, unsigned int sequence, short offset) +{ + if (m_refresh_sequence != sequence) + { + m_refresh_sequence = sequence; + m_read_cache_sum = 0; + } + else if(offset < m_read_cache_sum)//(m_refresh_sequence == sequence && offset < m_fb_sum) + { + max = m_read_cache_max[offset]; + min = m_read_cache_min[offset]; + return m_read_cache_mid[offset]; + } + + m_read_cache_sum++; + ASSERT(m_read_cache_sum <= WAVE_READ_CACHE_LEN); + int i, data; + int tmp_min = m_last_data; + int tmp_max = m_last_data; + int mid = (m_min_old + m_max_old)>>1; + i = 0; + while(i++ < frame_len) + { + data = read_data(); + if(BUFFER_EMPTY == data) + { + break; + } + m_last_data = data; + if(data < tmp_min){tmp_min = data;} + if(data > tmp_max){tmp_max = data;} + } + min = m_read_cache_min[offset] = MIN(m_min_old, MIN(tmp_min, m_min_older)); + max = m_read_cache_max[offset] = MAX(m_max_old, MAX(tmp_max, m_max_older)); + m_min_older = m_min_old; + m_max_older = m_max_old; + m_min_old = tmp_min; + m_max_old = tmp_max; + return (m_read_cache_mid[offset] = mid); +} +void c_wave_buffer::clear_data() +{ + m_head = m_tail = 0; + memset(m_wave_buf, 0, sizeof(m_wave_buf)); +} +void c_wave_buffer::reset() +{ + m_head = m_tail; +} +#include +#include +#define CORRECT(x, high_limit, low_limit) {\ + x = (x > high_limit) ? high_limit : x;\ + x = (x < low_limit) ? low_limit : x;\ +}while(0) +#define WAVE_CURSOR_WIDTH 8 +#define WAVE_LINE_WIDTH 1 +#define WAVE_MARGIN 5 +c_wave_ctrl::c_wave_ctrl() +{ + m_wave = 0; + m_bg_fb = 0; + m_wave_name_font = m_wave_unit_font = 0; + m_wave_name = m_wave_unit = 0; + m_max_data = 500; + m_min_data = 0; + m_wave_speed = 1; + m_wave_data_rate = 0; + m_wave_refresh_rate = 1000; + m_frame_len_map_index = 0; + m_wave_name_color = m_wave_unit_color = m_wave_color = GL_RGB(255,0,0); + m_back_color = GL_RGB(0,0,0); +} +void c_wave_ctrl::on_init_children() +{ + c_rect rect; + get_screen_rect(rect); + m_wave_left = rect.m_left + WAVE_MARGIN; + m_wave_right = rect.m_right - WAVE_MARGIN; + m_wave_top = rect.m_top + WAVE_MARGIN; + m_wave_bottom = rect.m_bottom - WAVE_MARGIN; + m_wave_cursor = m_wave_left; + m_bg_fb = (unsigned int*)calloc(rect.Width() * rect.Height(), 4); +} +void c_wave_ctrl::set_max_min(short max_data, short min_data) +{ + m_max_data = max_data; + m_min_data = min_data; +} +void c_wave_ctrl::set_wave_in_out_rate(unsigned int data_rate, unsigned int refresh_rate) +{ + m_wave_data_rate = data_rate; + m_wave_refresh_rate = refresh_rate; + int read_times_per_second = m_wave_speed * 1000 / m_wave_refresh_rate; + memset(m_frame_len_map, 0, sizeof(m_frame_len_map)); + for (unsigned int i = 1; i < sizeof(m_frame_len_map) + 1; i++) + { + m_frame_len_map[i-1] = data_rate * i / read_times_per_second - data_rate * (i-1) / read_times_per_second; + } + m_frame_len_map_index = 0; +} +void c_wave_ctrl::set_wave_speed(unsigned int speed) +{ + m_wave_speed = speed; + set_wave_in_out_rate(m_wave_data_rate, m_wave_refresh_rate); +} +void c_wave_ctrl::clear_data() +{ + if(m_wave == 0) + { + ASSERT(false); + return; + } + m_wave->clear_data(); +} +bool c_wave_ctrl::is_data_enough() +{ + if(m_wave == 0) + { + ASSERT(false); + return false; + } + return (m_wave->get_cnt() - m_frame_len_map[m_frame_len_map_index] * m_wave_speed); +} +void c_wave_ctrl::refresh_wave(unsigned char frame) +{ + if(m_wave == 0) + { + ASSERT(false); + return; + } + short max, min, mid; + for(short offset = 0; offset < m_wave_speed; offset++) + { + //get wave value + mid = m_wave->read_wave_data_by_frame(max, min, + m_frame_len_map[m_frame_len_map_index++], + frame, offset); + m_frame_len_map_index %= sizeof(m_frame_len_map); + + //map to wave ctrl + int y_min,y_max; + if(m_max_data == m_min_data) + { + ASSERT(false); + } + y_max = m_wave_bottom + WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top)*(min - m_min_data)/(m_max_data - m_min_data); + y_min = m_wave_bottom - WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top)*(max - m_min_data)/(m_max_data - m_min_data); + mid = m_wave_bottom - (m_wave_bottom - m_wave_top)*(mid - m_min_data)/(m_max_data - m_min_data); + CORRECT(y_min, m_wave_bottom, m_wave_top); + CORRECT(y_max, m_wave_bottom, m_wave_top); + CORRECT(mid, m_wave_bottom, m_wave_top); + if (m_wave_cursor > m_wave_right) + { + m_wave_cursor = m_wave_left; + } + draw_smooth_vline(y_min, y_max, mid, m_wave_color); + restore_background(); + m_wave_cursor++; + } +} +void c_wave_ctrl::draw_smooth_vline(int y_min, int y_max, int mid, unsigned int rgb) +{ + int dy = y_max - y_min; + short r = GL_RGB_R(rgb); + short g = GL_RGB_G(rgb); + short b = GL_RGB_B(rgb); + int index = (dy >> 1) + 2; + int y; + m_surface->draw_pixel(m_wave_cursor, mid, rgb, m_z_order); + if (dy < 1) + { + return; + } + unsigned char cur_r,cur_g,cur_b; + unsigned int cur_rgb; + for (int i = 1; i <= (dy >> 1) + 1; ++i ) + { + if ( (mid + i) <= y_max ) + { + y = mid + i; + cur_r = r * (index - i) / index; + cur_g = g * (index - i) / index; + cur_b = b * (index - i) / index; + cur_rgb = GL_RGB(cur_r, cur_g, cur_b); + m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order); + } + if ( (mid - i) >= y_min ) + { + y = mid - i; + cur_r = r * (index - i) / index; + cur_g = g * (index - i) / index; + cur_b = b * (index - i) / index; + cur_rgb = GL_RGB(cur_r, cur_g, cur_b); + m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order); + } + } +} +void c_wave_ctrl::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, m_back_color, m_z_order); + + //show name + c_word::draw_string(m_surface, m_z_order, m_wave_name, m_wave_left + 10, rect.m_top, m_wave_name_font, m_wave_name_color, GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + //show unit + c_word::draw_string(m_surface, m_z_order, m_wave_unit, m_wave_left + 60, rect.m_top, m_wave_unit_font, m_wave_unit_color, GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + save_background(); +} +void c_wave_ctrl::clear_wave(void) +{ + m_surface->fill_rect(m_wave_left, m_wave_top, m_wave_right, m_wave_bottom, m_back_color, m_z_order); + m_wave_cursor = m_wave_left; +} +void c_wave_ctrl::restore_background() +{ + int x = m_wave_cursor + WAVE_CURSOR_WIDTH; + if (x > m_wave_right) + { + x -= (m_wave_right - m_wave_left + 1); + } + c_rect rect; + get_screen_rect(rect); + register int width = rect.Width(); + register int top = rect.m_top; + register int left = rect.m_left; + for (int y_pos = (m_wave_top - 1); y_pos <= (m_wave_bottom + 1); y_pos++) + { + (m_bg_fb) ? m_surface->draw_pixel(x, y_pos, m_bg_fb[(y_pos - top) * width + (x - left)], m_z_order) : m_surface->draw_pixel(x, y_pos, 0, m_z_order); + } +} +void c_wave_ctrl::save_background() +{ + if (!m_bg_fb) + { + return; + } + c_rect rect; + get_screen_rect(rect); + + register unsigned int* p_des = m_bg_fb; + for (int y = rect.m_top; y <= rect.m_bottom; y++) + { + for (int x = rect.m_left; x <= rect.m_right; x++) + { + *p_des++ = m_surface->get_pixel(x, y, m_z_order); + } + } +} diff --git a/GuiLite-win.cpp b/GuiLite-win.cpp new file mode 100644 index 0000000..170840c --- /dev/null +++ b/GuiLite-win.cpp @@ -0,0 +1,3887 @@ +#include "GuiLite.h" +void c_bitmap::draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO *pBitmap, int x, int y, unsigned int mask_rgb) +{ + if (0 == pBitmap) + { + return; + } + unsigned short* lower_fb = 0; + int lower_fb_width = surface->m_width; + if (z_order >= Z_ORDER_LEVEL_1) + { + lower_fb = surface->m_frame_layers[z_order - 1].fb; + } + unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); + int xsize = pBitmap->width; + int ysize = pBitmap->height; + const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; + for (int j = 0; j < ysize; j++) + { + for (int i = 0; i < xsize; i++) + { + unsigned int rgb = *pData++; + if (mask_rgb_16 == rgb) + { + if (lower_fb) + {//restore lower layer + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(lower_fb[(y + j) * lower_fb_width + x + i]), z_order); + } + } + else + { + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + } + } + } +} +void c_bitmap::draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO* pBitmap, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb) +{ + if (0 == pBitmap || (src_x + width > pBitmap->width) || (src_y + height > pBitmap->height)) + { + return; + } + unsigned short* lower_fb = 0; + int lower_fb_width = surface->m_width; + if (z_order >= Z_ORDER_LEVEL_1) + { + lower_fb = surface->m_frame_layers[z_order - 1].fb; + } + unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); + const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; + for (int j = 0; j < height; j++) + { + const unsigned short* p = &pData[src_x + (src_y + j) * pBitmap->width]; + for (int i = 0; i < width; i++) + { + unsigned int rgb = *p++; + if (mask_rgb_16 == rgb) + { + if (lower_fb) + {//restore lower layer + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(lower_fb[(y + j) * lower_fb_width + x + i]), z_order); + } + } + else + { + surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + } + } + } +} +GL_MSG_ENTRY c_cmd_target::ms_usr_map_entries[USR_MSG_MAX]; +unsigned short c_cmd_target::ms_user_map_size; +GL_BEGIN_MESSAGE_MAP(c_cmd_target) +GL_END_MESSAGE_MAP() +c_cmd_target::c_cmd_target() +{ +} +c_cmd_target::~c_cmd_target() +{ +} +int c_cmd_target::handle_usr_msg(unsigned int msgId, unsigned int wParam, unsigned int lParam) +{ + int i; + c_cmd_target* p_wnd = 0; + MSGFUNCS msg_funcs; + for (i = 0; i < ms_user_map_size; i++) + { + if (msgId == ms_usr_map_entries[i].msgId) + { + p_wnd = (c_cmd_target*)ms_usr_map_entries[i].pObject; + msg_funcs.func = ms_usr_map_entries[i].func; + (p_wnd->*msg_funcs.func_vwl)(wParam , lParam); + } + } + return 1; +} +void c_cmd_target::load_cmd_msg() +{ + const GL_MSG_ENTRY* p_entry = GetMSgEntries(); + if (0 == p_entry) + { + return; + } + bool bExist = false; + while(MSG_TYPE_INVALID != p_entry->msgType) + { + if (MSG_TYPE_WND == p_entry->msgType) + { + p_entry++; + continue; + } + bExist = false; + for (int i = 0; i < ms_user_map_size; i++) + { + //repeat register, return. + if (p_entry->msgId == ms_usr_map_entries[i].msgId + && ms_usr_map_entries[i].pObject == this) + { + bExist = true; + break; + } + } + if (true == bExist) + { + p_entry++; + continue; + } + if (MSG_TYPE_USR == p_entry->msgType) + { + ms_usr_map_entries[ms_user_map_size] = *p_entry; + ms_usr_map_entries[ms_user_map_size].pObject = this; + ms_user_map_size++; + if (USR_MSG_MAX == ms_user_map_size) + { + ASSERT(false); + } + } + else + { + ASSERT(false); + break; + } + p_entry++; + } +} +const GL_MSG_ENTRY* c_cmd_target::FindMsgEntry(const GL_MSG_ENTRY *pEntry, + unsigned int msgType, unsigned short msgId, unsigned short ctrlId) +{ + if ( MSG_TYPE_INVALID == msgType) + { + return 0; + } + while (MSG_CALLBACK_NULL != pEntry->callbackType) + { + if ( (msgType == pEntry->msgType) && (msgId == pEntry->msgId) && (void*)(unsigned long)ctrlId == pEntry->pObject) + { + return pEntry; + } + pEntry++; + } + return 0; +} +#include +#include +c_display::c_display(void* phy_fb, unsigned int display_width, unsigned int display_height, + unsigned int surface_width, unsigned int surface_height, + unsigned int color_bytes, unsigned int surface_cnt, EXTERNAL_GFX_OP* gfx_op) +{ + if (color_bytes != 2 && color_bytes != 4) + { + log_out("Support 16 bits, 32 bits color only!"); + ASSERT(false); + } + m_width = display_width; + m_height = display_height; + m_color_bytes = color_bytes; + m_phy_fb = phy_fb; + m_phy_read_index = m_phy_write_index = 0; + memset(m_surface_group, 0, sizeof(m_surface_group)); + m_surface_index = 0; + m_surface_cnt = surface_cnt; + ASSERT(m_surface_cnt <= SURFACE_CNT_MAX); + + for (int i = 0; i < m_surface_cnt; i++) + { + m_surface_group[i] = phy_fb ? new c_surface(this, surface_width, surface_height, color_bytes) : new c_surface_no_fb(this, surface_width, surface_height, color_bytes, gfx_op); + } +} +c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder) +{ + if(max_zorder >= Z_ORDER_LEVEL_MAX || m_surface_index >= m_surface_cnt) + { + ASSERT(false); + return 0; + } + int i = m_surface_index++; + m_surface_group[i]->set_surface(max_zorder); + return m_surface_group[i]; +} +int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset) +{ + int surface_width = s0->get_width(); + int surface_height = s0->get_height(); + if (offset < 0 || offset > surface_width || y0 < 0 || y0 >= surface_height || + y1 < 0 || y1 >= surface_height || x0 < 0 || x0 >= surface_width || x1 < 0 || x1 >= surface_width) + { + ASSERT(false); + return -1; + } + int width = (x1 - x0 + 1); + if (width < 0 || width > surface_width || width < offset) + { + ASSERT(false); + return -1; + } + x0 = (x0 >= m_width) ? (m_width - 1) : x0; + x1 = (x1 >= m_width) ? (m_width - 1) : x1; + y0 = (y0 >= m_height) ? (m_height - 1) : y0; + y1 = (y1 >= m_height) ? (m_height - 1) : y1; + + if (m_phy_fb) + { + for (int y = y0; y <= y1; y++) + { + //Left surface + char* addr_s = ((char*)(s0->m_fb) + (y * (s0->get_width()) + x0 + offset) * m_color_bytes); + char* addr_d = ((char*)(m_phy_fb)+(y * m_width + x0) * m_color_bytes); + memcpy(addr_d, addr_s, (width - offset) * m_color_bytes); + //Right surface + addr_s = ((char*)(s1->m_fb) + (y * (s1->get_width()) + x0) * m_color_bytes); + addr_d = ((char*)(m_phy_fb)+(y * m_width + x0 + (width - offset)) * m_color_bytes); + memcpy(addr_d, addr_s, offset * m_color_bytes); + } + } + else if(m_color_bytes == 4) + { + void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel; + for (int y = y0; y <= y1; y++) + { + //Left surface + for (int x = x0; x <= (x1 - offset); x++) + { + draw_pixel(x, y, ((unsigned int*)s0->m_fb)[y * m_width + x + offset]); + } + //Right surface + for (int x = x1 - offset; x <= x1; x++) + { + draw_pixel(x, y, ((unsigned int*)s1->m_fb)[y * m_width + x + offset - x1 + x0]); + } + } + } + else if (m_color_bytes == 2) + { + void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel; + for (int y = y0; y <= y1; y++) + { + //Left surface + for (int x = x0; x <= (x1 - offset); x++) + { + draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s0->m_fb)[y * m_width + x + offset])); + } + //Right surface + for (int x = x1 - offset; x <= x1; x++) + { + draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s1->m_fb)[y * m_width + x + offset - x1 + x0])); + } + } + } + m_phy_write_index++; + return 0; +} +void* c_display::get_updated_fb(int* width, int* height, bool force_update) +{ + if (width && height) + { + *width = get_width(); + *height = get_height(); + } + if (force_update) + { + return m_phy_fb; + } + if (m_phy_read_index == m_phy_write_index) + {//No update + return 0; + } + m_phy_read_index = m_phy_write_index; + return m_phy_fb; +} +int c_display::snap_shot(const char* file_name) +{ + if (!m_phy_fb) + { + return -1; + } + unsigned int width = get_width(); + unsigned int height = get_height(); + //16 bits framebuffer + if (m_color_bytes == 2) + { + return build_bmp(file_name, width, height, (unsigned char*)m_phy_fb); + } + //32 bits framebuffer + unsigned short* p_bmp565_data = new unsigned short[width * height]; + unsigned int* p_raw_data = (unsigned int*)m_phy_fb; + for (int i = 0; i < width * height; i++) + { + unsigned int rgb = *p_raw_data++; + p_bmp565_data[i] = GL_RGB_32_to_16(rgb); + } + int ret = build_bmp(file_name, width, height, (unsigned char*)p_bmp565_data); + delete []p_bmp565_data; + return ret; +} +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) +c_rect::c_rect(const c_rect& rect) +{ + SetRect(rect.m_left,rect.m_top,rect.m_right,rect.m_bottom); +} +c_rect& c_rect::operator=(const c_rect& rect) +{ + SetRect(rect.m_left,rect.m_top,rect.m_right,rect.m_bottom); + return *this; +} +void c_rect::SetRect( int Left, int Top, int Right, int Bottom) +{ + m_left = MIN(Left, Right); + m_top = MIN(Top, Bottom); + m_right = MAX(Left, Right); + m_bottom = MAX(Top, Bottom); +} +c_rect c_rect::operator&(const c_rect& rect) const +{ + c_rect dst; + dst.m_left = MAX(m_left, rect.m_left); + dst.m_top = MAX(m_top, rect.m_top); + dst.m_right = MIN(m_right, rect.m_right); + dst.m_bottom = MIN(m_bottom, rect.m_bottom); + if(dst.m_left >= dst.m_right || dst.m_top >= dst.m_bottom) + dst.Empty(); + return dst; +} +void c_rect::Empty() +{ + m_left = m_top = m_right = m_bottom = 0; +} +void c_rect::Offset(int x, int y) +{ + m_left +=x; + m_right +=x; + m_top += y; + m_bottom += y; +} +int c_rect::IsEmpty() const +{ + return m_top == m_bottom || m_left == m_right; +} +int c_rect::PtInRect(int x, int y) const +{ + return x >= m_left && x <= m_right && y >= m_top && y <= m_bottom; +} +int c_rect::operator==(const c_rect& rect) const +{ + return (m_left == rect.m_left) && (m_top==rect.m_top) && + (m_right == rect.m_right) && (m_bottom==rect.m_bottom); +} +#include +#include +#define GL_ROUND_RGB_32(rgb) (rgb & 0xFFF8FCF8) //make RGB32 = RGB16 +c_surface::c_surface(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes) +{ + m_width = width; + m_height = height; + m_color_bytes = color_bytes; + m_display = display; + m_phy_fb = display->m_phy_fb; + m_phy_write_index = &display->m_phy_write_index; + m_fb = 0; + m_top_zorder = m_max_zorder = Z_ORDER_LEVEL_0; + m_is_active = false; + m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height); +} +void c_surface::set_surface(Z_ORDER_LEVEL max_z_order) +{ + m_max_zorder = max_z_order; + if (m_display->m_surface_cnt > 1) + { + m_fb = calloc(m_width * m_height, m_color_bytes); + } + + for(int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++) + {//Top layber fb always be 0 + m_frame_layers[i].fb = (unsigned short*)calloc(m_width * m_height, sizeof(unsigned short)); + ASSERT(0 != m_frame_layers[i].fb); + } +} +void c_surface::draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order) +{ + if (x >= m_width || y >= m_height || x < 0 || y < 0) + { + return; + } + if (z_order > m_max_zorder) + { + ASSERT(false); + return; + } + rgb = GL_ROUND_RGB_32(rgb); + if (z_order == m_max_zorder) + { + return draw_pixel_on_fb(x, y, rgb); + } + if (z_order > m_top_zorder) + { + m_top_zorder = (Z_ORDER_LEVEL)z_order; + } + if (0 == m_frame_layers[z_order].visible_rect.PtInRect(x, y)) + { + ASSERT(false); + return; + } + ((unsigned short*)(m_frame_layers[z_order].fb))[x + y * m_width] = GL_RGB_32_to_16(rgb); + if (z_order == m_top_zorder) + { + return draw_pixel_on_fb(x, y, rgb); + } + bool is_covered = false; + for (int tmp_z_order = Z_ORDER_LEVEL_MAX - 1; tmp_z_order > z_order; tmp_z_order--) + { + if (true == m_frame_layers[tmp_z_order].visible_rect.PtInRect(x, y)) + { + is_covered = true; + break; + } + } + if (!is_covered) + { + draw_pixel_on_fb(x, y, rgb); + } +} +void c_surface::draw_pixel_on_fb(int x, int y, unsigned int rgb) +{ + if (m_fb) + { + (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb); + } + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + if (m_is_active && (x < display_width) && (y < display_height)) + { + if (m_color_bytes == 4) + { + ((unsigned int*)m_phy_fb)[y * (m_display->get_width()) + x] = rgb; + } + else + { + ((unsigned short*)m_phy_fb)[y * (m_display->get_width()) + x] = GL_RGB_32_to_16(rgb); + } + *m_phy_write_index = *m_phy_write_index + 1; + } +} +void c_surface::fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order) +{ + x0 = (x0 < 0) ? 0 : x0; + y0 = (y0 < 0) ? 0 : y0; + x1 = (x1 > (m_width - 1)) ? (m_width - 1) : x1; + y1 = (y1 > (m_height - 1)) ? (m_height - 1) : y1; + rgb = GL_ROUND_RGB_32(rgb); + if (z_order == m_max_zorder) + { + return fill_rect_on_fb(x0, y0, x1, y1, rgb); + } + if (z_order == m_top_zorder) + { + int x, y; + unsigned short *mem_fb; + unsigned int rgb_16 = GL_RGB_32_to_16(rgb); + for (y = y0; y <= y1; y++) + { + x = x0; + mem_fb = &((unsigned short*)m_frame_layers[z_order].fb)[y * m_width + x]; + for (; x <= x1; x++) + { + *mem_fb++ = rgb_16; + } + } + return fill_rect_on_fb(x0, y0, x1, y1, rgb); + } + for (; y0 <= y1; y0++) + { + draw_hline(x0, x1, y0, rgb, z_order); + } +} +void c_surface::fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) +{ + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + if (m_color_bytes == 4) + { + int x; + unsigned int *fb, *phy_fb; + for (; y0 <= y1; y0++) + { + x = x0; + fb = m_fb ? &((unsigned int*)m_fb)[y0 * m_width + x] : 0; + phy_fb = &((unsigned int*)m_phy_fb)[y0 * display_width + x]; + *m_phy_write_index = *m_phy_write_index + 1; + for (; x <= x1; x++) + { + if (fb) + { + *fb++ = rgb; + } + if (m_is_active && (x < display_width) && (y0 < display_height)) + { + *phy_fb++ = rgb; + } + } + } + } + else if(m_color_bytes == 2) + { + int x; + unsigned short *fb, *phy_fb; + rgb = GL_RGB_32_to_16(rgb); + for (; y0 <= y1; y0++) + { + x = x0; + fb = m_fb ? &((unsigned short*)m_fb)[y0 * m_width + x] : 0; + phy_fb = &((unsigned short*)m_phy_fb)[y0 * display_width + x]; + *m_phy_write_index = *m_phy_write_index + 1; + for (; x <= x1; x++) + { + if (fb) + { + *fb++ = rgb; + } + if (m_is_active && (x < display_width) && (y0 < display_height)) + { + *phy_fb++ = rgb; + } + } + } + } +} +unsigned int c_surface::get_pixel(int x, int y, unsigned int z_order) +{ + if (x >= m_width || y >= m_height || x < 0 || y < 0 || + z_order >= Z_ORDER_LEVEL_MAX) + { + ASSERT(false); + return 0; + } + if (z_order == m_max_zorder) + { + if (m_fb) + { + return (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_fb)[y * m_width + x]); + } + else if(m_phy_fb) + { + return (m_color_bytes == 4) ? ((unsigned int*)m_phy_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_phy_fb)[y * m_width + x]); + } + return 0; + } + + unsigned short rgb_16 = ((unsigned short*)(m_frame_layers[z_order].fb))[y * m_width + x]; + return GL_RGB_16_to_32(rgb_16); +} +void c_surface::draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order) +{ + for (;x0 <= x1; x0++) + { draw_pixel(x0, y, rgb, z_order); } +} +void c_surface::draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order) +{ + for (;y0 <= y1; y0++) + { draw_pixel(x, y0, rgb, z_order); } +} +void c_surface::draw_line(int x1, int y1, int x2, int y2, unsigned int rgb, unsigned int z_order) +{ + int dx, dy, e; + dx = x2 - x1; + dy = y2 - y1; + if ((dx >= 0) && (dy >= 0)) + { + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 <= x2; x1++, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1++; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 <= y2; y1++, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1++; e -= dy; } + } + } + } + else if ((dx >= 0) && (dy < 0)) + { + dy = -dy; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 <= x2; x1++, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1--; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 >= y2; y1--, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1++; e -= dy; } + } + } + } + else if ((dx < 0) && (dy >= 0)) + { + dx = -dx; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 >= x2; x1--, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1++; e -= dx; } + } + } + else + { + e = dx - dy / 2; + for(; y1 <= y2; y1++, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1--; e -= dy; } + } + } + } + else if ((dx < 0) && (dy < 0)) + { + dx = -dx; + dy = -dy; + if (dx >= dy) + { + e = dy - dx / 2; + for(; x1 >= x2; x1--, e += dy) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { y1--; e -= dx; } + } + } + else + { + e = dx - dy / 2; + while (y1-- >= y2) + for(; y1 >= y2; y1--, e += dx) + { + draw_pixel(x1, y1, rgb, z_order); + if (e>0) { x1--; e -= dy; } + } + } + } +} +void c_surface::draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size) +{ + for (unsigned int offset = 0; offset < size; offset++) + { + draw_hline(x0 + offset, x1 - offset, y0 + offset, rgb, z_order); + draw_hline(x0 + offset, x1 - offset, y1 - offset, rgb, z_order); + draw_vline(x0 + offset, y0 + offset, y1 - offset, rgb, z_order); + draw_vline(x1 - offset, y0 + offset, y1 - offset, rgb, z_order); + } +} +int c_surface::set_frame_layer_visible_rect(c_rect& rect, unsigned int z_order) +{ + if (rect == m_frame_layers[z_order].visible_rect) + { + return 0; + } + if (rect.m_left < 0 || rect.m_left >= m_width || + rect.m_right < 0 || rect.m_right >= m_width || + rect.m_top < 0 || rect.m_top >= m_height || + rect.m_bottom < 0 || rect.m_bottom >=m_height) + { + ASSERT(false); + return -1; + } + if (!(z_order > Z_ORDER_LEVEL_0 && z_order < Z_ORDER_LEVEL_MAX)) + { + ASSERT(false); + return -2; + } + if (z_order < m_top_zorder) + { + ASSERT(false); + return -3; + } + m_top_zorder = (Z_ORDER_LEVEL)z_order; + + c_rect old_rect = m_frame_layers[z_order].visible_rect; + //Recover the lower layer + int src_zorder = (Z_ORDER_LEVEL)(z_order - 1); + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + for (int y = old_rect.m_top; y <= old_rect.m_bottom; y++) + { + for (int x = old_rect.m_left; x <= old_rect.m_right; x++) + { + if (!rect.PtInRect(x, y)) + { + unsigned int rgb = ((unsigned short*)(m_frame_layers[src_zorder].fb))[x + y * m_width]; + draw_pixel_on_fb(x, y, GL_RGB_16_to_32(rgb)); + } + } + } + m_frame_layers[z_order].visible_rect = rect; + if (rect.IsEmpty()) + { + m_top_zorder = (Z_ORDER_LEVEL)(z_order - 1); + } + return 0; +} +int c_surface::flush_screen(int left, int top, int right, int bottom) +{ + if(left < 0 || left >= m_width || right < 0 || right >= m_width || + top < 0 || top >= m_height || bottom < 0 || bottom >= m_height) + { + ASSERT(false); + } + if(!m_is_active || (0 == m_phy_fb) || (0 == m_fb)) + { + return -1; + } + int display_width = m_display->get_width(); + int display_height = m_display->get_height(); + left = (left >= display_width) ? (display_width - 1) : left; + right = (right >= display_width) ? (display_width - 1) : right; + top = (top >= display_height) ? (display_height - 1) : top; + bottom = (bottom >= display_height) ? (display_height - 1) : bottom; + for (int y = top; y < bottom; y++) + { + void* s_addr = (char*)m_fb + ((y * m_width + left) * m_color_bytes); + void* d_addr = (char*)m_phy_fb + ((y * display_width + left) * m_color_bytes); + memcpy(d_addr, s_addr, (right - left) * m_color_bytes); + } + *m_phy_write_index = *m_phy_write_index + 1; + return 0; +} +bool c_surface::is_valid(c_rect rect) +{ + if (rect.m_left < 0 || rect.m_top < 0) + { + return false; + } + if (rect.m_right >= m_width || rect.m_bottom >= m_height) + { + return false; + } + return true; +} +////////////////////////////////////////////////////////////////////////////////////// +void c_surface_no_fb::fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) +{ + if (!m_gfx_op) + { + return; + } + if (m_gfx_op->fill_rect) + { + return m_gfx_op->fill_rect(x0, y0, x1, y1, rgb); + } + if (m_gfx_op->draw_pixel && m_is_active) + { + for (int y = y0; y <= y1; y++) + { + for (int x = x0; x <= x1; x++) + { + m_gfx_op->draw_pixel(x, y, rgb); + } + } + } + if (!m_fb) { return; } + if(m_color_bytes == 4) + { + unsigned int *fb; + for (int y = y0; y <= y1; y++) + { + fb = &((unsigned int*)m_fb)[y0 * m_width + x0]; + for (int x = x0; x <= x1; x++) + { + *fb++ = rgb; + } + } + } + else if (m_color_bytes == 2) + { + unsigned short *fb; + rgb = GL_RGB_32_to_16(rgb); + for (int y = y0; y <= y1; y++) + { + fb = &((unsigned short*)m_fb)[y0 * m_width + x0]; + for (int x = x0; x <= x1; x++) + { + *fb++ = rgb; + } + } + } +} +void c_surface_no_fb::draw_pixel_on_fb(int x, int y, unsigned int rgb) +{ + if (m_gfx_op && m_gfx_op->draw_pixel && m_is_active) + { + m_gfx_op->draw_pixel(x, y, rgb); + } + if (!m_fb) { return; } + if (m_color_bytes == 4) + { + ((unsigned int*)m_fb)[y * m_width + x] = rgb; + } + else if (m_color_bytes == 2) + { + ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb); + } +} + +static const FONT_INFO* s_font_map[FONT_MAX]; +static const BITMAP_INFO* s_bmp_map[BITMAP_MAX]; +static unsigned int s_color_map[COLOR_MAX]; + +int c_theme::add_font(FONT_TYPE index, const FONT_INFO* font) +{ + if (index >= FONT_MAX) + { + ASSERT(false); + return -1; + } + s_font_map[index] = font; + return 0; +} + +const FONT_INFO* c_theme::get_font(FONT_TYPE index) +{ + if (index >= FONT_MAX) + { + ASSERT(false); + return 0; + } + return s_font_map[index]; +} + +int c_theme::add_bitmap(BITMAP_TYPE index, const BITMAP_INFO* bmp) +{ + if (index >= BITMAP_MAX) + { + ASSERT(false); + return -1; + } + s_bmp_map[index] = bmp; + return 0; +} + +const BITMAP_INFO* c_theme::get_bmp(BITMAP_TYPE index) +{ + if (index >= BITMAP_MAX) + { + ASSERT(false); + return 0; + } + return s_bmp_map[index]; +} + +int c_theme::add_color(COLOR_TYPE index, const unsigned int color) +{ + if (index >= COLOR_MAX) + { + ASSERT(false); + return -1; + } + s_color_map[index] = color; + return 0; +} + +const unsigned int c_theme::get_color(COLOR_TYPE index) +{ + if (index >= COLOR_MAX) + { + ASSERT(false); + return 0; + } + return s_color_map[index]; +} +c_wnd::c_wnd(): m_status(STATUS_NORMAL), m_attr(ATTR_VISIBLE), m_parent(0), m_top_child(0), m_prev_sibling(0), m_next_sibling(0), +m_str(0), m_font_color(0), m_bg_color(0), m_resource_id(0), m_z_order(Z_ORDER_LEVEL_0), m_focus_child(0), m_surface(0) +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); +} +int c_wnd::connect(c_wnd *parent, unsigned short resource_id, const char* str, + short x, short y, short width, short height, WND_TREE* p_child_tree ) +{ + if(0 == resource_id) + { + ASSERT(false); + return -1; + } + m_resource_id = resource_id; + set_str(str); + m_parent = parent; + m_status = STATUS_NORMAL; + if (parent) + { + m_z_order = parent->m_z_order; + m_surface = parent->m_surface; + } + if(0 == m_surface) + { + ASSERT(false); + return -2; + } + /* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/ + m_wnd_rect.m_left = x; + m_wnd_rect.m_top = y; + m_wnd_rect.m_right = (x + width - 1); + m_wnd_rect.m_bottom = (y + height - 1); + c_rect rect; + get_screen_rect(rect); + ASSERT(m_surface->is_valid(rect)); + pre_create_wnd(); + if ( 0 != parent ) + { + parent->add_child_2_tail(this); + } + if (load_child_wnd(p_child_tree) >= 0) + { + load_cmd_msg(); + on_init_children(); + } + return 0; +} +int c_wnd::load_child_wnd(WND_TREE *p_child_tree) +{ + if (0 == p_child_tree) + { + return 0; + } + int sum = 0; + WND_TREE* p_cur = p_child_tree; + while(p_cur->p_wnd) + { + if (0 != p_cur->p_wnd->m_resource_id) + {//This wnd has been used! Do not share! + ASSERT(false); + return -1; + } + else + { + p_cur->p_wnd->connect(this, p_cur->resource_id, p_cur->str, + p_cur->x, p_cur->y, p_cur->width, p_cur->height,p_cur->p_child_tree); + } + p_cur++; + sum++; + } + return sum; +} +c_wnd* c_wnd::connect_clone(c_wnd *parent, unsigned short resource_id, const char* str, + short x, short y, short width, short height, WND_TREE* p_child_tree ) +{ + if(0 == resource_id) + { + ASSERT(false); + return 0; + } + c_wnd* wnd = clone(); + wnd->m_resource_id = resource_id; + wnd->set_str(str); + wnd->m_parent = parent; + wnd->m_status = STATUS_NORMAL; + if (parent) + { + wnd->m_z_order = parent->m_z_order; + wnd->m_surface = parent->m_surface; + } + else + { + wnd->m_surface = m_surface; + } + if(0 == wnd->m_surface) + { + ASSERT(false); + return 0; + } + /* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/ + wnd->m_wnd_rect.m_left = x; + wnd->m_wnd_rect.m_top = y; + wnd->m_wnd_rect.m_right = (x + width - 1); + wnd->m_wnd_rect.m_bottom = (y + height - 1); + c_rect rect; + wnd->get_screen_rect(rect); + ASSERT(wnd->m_surface->is_valid(rect)); + wnd->pre_create_wnd(); + + if ( 0 != parent ) + { + parent->add_child_2_tail(wnd); + } + if (wnd->load_clone_child_wnd(p_child_tree) >= 0) + { + wnd->load_cmd_msg(); + wnd->on_init_children(); + } + return wnd; +} +int c_wnd::load_clone_child_wnd(WND_TREE *p_child_tree) +{ + if (0 == p_child_tree) + { + return 0; + } + int sum = 0; + WND_TREE* p_cur = p_child_tree; + while(p_cur->p_wnd) + { + p_cur->p_wnd->connect_clone(this, p_cur->resource_id, p_cur->str, + p_cur->x, p_cur->y, p_cur->width, p_cur->height,p_cur->p_child_tree); + p_cur++; + sum++; + } + return sum; +} +void c_wnd::disconnect() +{ + if (0 == m_resource_id) + { + return; + } + if (0 != m_top_child) + { + c_wnd *child = m_top_child; + c_wnd *next_child = 0; + while (child) + { + next_child = child->m_next_sibling; + child->disconnect(); + child = next_child; + } + } + if (0 != m_parent) + { + m_parent->unlink_child(this); + } + m_focus_child = 0; + m_resource_id = 0; +} +c_wnd* c_wnd::get_wnd_ptr(unsigned short id) const +{ + c_wnd *child = m_top_child; + while ( child ) + { + if ( child->get_id() == id ) + { + break; + } + child = child->m_next_sibling; + } + return child; +} +void c_wnd::set_attr(WND_ATTRIBUTION attr) +{ + m_attr = attr; + if ( ATTR_DISABLED == (attr & ATTR_DISABLED) ) + { + m_status = STATUS_DISABLED; + } + else + { + if (m_status == STATUS_DISABLED) + { + m_status = STATUS_NORMAL; + } + } +} +int c_wnd::is_focus_wnd() const +{ + if ( (m_attr & ATTR_VISIBLE) + && !(m_attr & ATTR_DISABLED) + && (m_attr & ATTR_FOCUS)) + { + return true; + } + else + { + return false; + } +} +void c_wnd::set_wnd_pos(short x, short y, short width, short height) +{ + m_wnd_rect.m_left = x; + m_wnd_rect.m_top = y; + m_wnd_rect.m_right = x + width - 1; + m_wnd_rect.m_bottom = y + height - 1; +} +void c_wnd::get_wnd_rect(c_rect &rect) const +{ + rect = m_wnd_rect; +} +void c_wnd::get_screen_rect(c_rect &rect) const +{ + rect.SetRect(0, 0, (m_wnd_rect.Width() - 1), (m_wnd_rect.Height() - 1)); + wnd2screen(rect); +} +void c_wnd::wnd2screen(int &x, int &y) const +{ + c_wnd *parent = m_parent; + c_rect rect; + x += m_wnd_rect.m_left; + y += m_wnd_rect.m_top; + while ( 0 != parent ) + { + parent->get_wnd_rect(rect); + x += rect.m_left; + y += rect.m_top; + parent = parent->m_parent; + } +} +void c_wnd::wnd2screen(c_rect &rect) const +{ + int l = rect.m_left; + int t = rect.m_top; + wnd2screen(l, t); + int r = (l + rect.Width() - 1); + int b = (t + rect.Height() - 1); + rect.SetRect(l, t, r, b); +} +c_wnd* c_wnd::set_child_focus(c_wnd * focus_child) +{ + ASSERT(0 != focus_child); + ASSERT(focus_child->m_parent == this); + c_wnd *old_focus_child = m_focus_child; + if (focus_child->is_focus_wnd()) + { + if (focus_child != old_focus_child ) + { + if (old_focus_child) + { + old_focus_child->on_kill_focus(); + } + m_focus_child = focus_child; + if (m_parent) + { + m_parent->set_child_focus(this); + } + m_focus_child->on_focus(); + } + } + return m_focus_child; +} +void c_wnd::add_child_2_tail(c_wnd *child) +{ + if( 0 == child )return; + if(child == get_wnd_ptr(child->m_resource_id))return; + if ( 0 == m_top_child ) + { + m_top_child = child; + child->m_prev_sibling = 0; + child->m_next_sibling = 0; + } + else + { + c_wnd *last_child = get_last_child(); + if (0 == last_child) + { + ASSERT(false); + } + last_child->m_next_sibling = child; + child->m_prev_sibling = last_child; + child->m_next_sibling = 0; + } +} +c_wnd* c_wnd::get_last_child() const +{ + if ( 0 == m_top_child ) + { + return 0; + } + c_wnd *child = m_top_child; + while ( child->m_next_sibling) + { + child = child->m_next_sibling; + } + return child; +} +int c_wnd::unlink_child(c_wnd *child) +{ + if ((0 == child) + || (this != child->m_parent)) + { + return -1; + } + if (0 == m_top_child) + { + return -2; + } + int find = false; + c_wnd *tmp_child = m_top_child; + if (tmp_child == child) + { + m_top_child = child->m_next_sibling; + if (0 != child->m_next_sibling) + { + child->m_next_sibling->m_prev_sibling = 0; + } + find = true; + } + else + { + while (tmp_child->m_next_sibling) + { + if (child == tmp_child->m_next_sibling) + { + tmp_child->m_next_sibling = child->m_next_sibling; + if (0 != child->m_next_sibling) + { + child->m_next_sibling->m_prev_sibling = tmp_child; + } + find = true; + break; + } + tmp_child = tmp_child->m_next_sibling; + } + } + if (true == find) + { + if (m_focus_child == child) + { + m_focus_child = 0; + } + child->m_next_sibling = 0; + child->m_prev_sibling = 0; + return 1; + } + else + { + return 0; + } +} +void c_wnd::show_window() +{ + if (ATTR_VISIBLE == (m_attr & ATTR_VISIBLE)) + { + on_paint(); + c_wnd *child = m_top_child; + if ( 0 != child ) + { + while ( child ) + { + child->show_window(); + child = child->m_next_sibling; + } + } + } +} +bool c_wnd::on_touch(int x, int y, TOUCH_ACTION action) +{ + c_rect rect; + x -= m_wnd_rect.m_left; + y -= m_wnd_rect.m_top; + c_wnd* child = m_top_child; + c_wnd* target_wnd = 0; + int target_z_order = Z_ORDER_LEVEL_0; + while (child) + { + if (ATTR_VISIBLE == (child->m_attr & ATTR_VISIBLE)) + { + child->get_wnd_rect(rect); + if (true == rect.PtInRect(x, y) || child->m_attr & ATTR_MODAL) + { + if (true == child->is_focus_wnd()) + { + if (child->m_z_order >= target_z_order) + { + target_wnd = child; + target_z_order = child->m_z_order; + } + } + } + } + child = child->m_next_sibling; + } + if (target_wnd == 0) + { + return false; + } + return target_wnd->on_touch(x, y, action); +} +bool c_wnd::on_key(KEY_TYPE key) +{ + ASSERT(key == KEY_FORWARD || key == KEY_BACKWARD || key == KEY_ENTER); + // Find current focus wnd. + c_wnd* old_focus_wnd = m_focus_child; + while (m_focus_child && m_focus_child->m_focus_child) + { + old_focus_wnd = m_focus_child->m_focus_child; + } + if (old_focus_wnd && !old_focus_wnd->on_key(key)) + { + return true; + } + // Default moving focus(Default handle KEY_FOWARD/KEY_BACKWARD) + if (key == KEY_ENTER) + { + return true; + } + if (!old_focus_wnd) + {// No current focus wnd, new one. + c_wnd *child = m_top_child; + c_wnd *new_focus_wnd = 0; + while (child) + { + if (ATTR_VISIBLE == (child->m_attr & ATTR_VISIBLE)) + { + if (true == child->is_focus_wnd()) + { + new_focus_wnd = child; + new_focus_wnd->m_parent->set_child_focus(new_focus_wnd); + child = child->m_top_child; + continue; + } + } + child = child->m_next_sibling; + } + return true; + } + // Move focus from old wnd to next wnd + c_wnd* next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_next_sibling : old_focus_wnd->m_prev_sibling; + while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd())) + {// Search neighbor of old focus wnd + next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling; + } + if (!next_focus_wnd) + {// Search whole brother wnd + next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_parent->m_top_child : old_focus_wnd->m_parent->get_last_child(); + while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd())) + { + next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling; + } + } + if (next_focus_wnd) + { + next_focus_wnd->m_parent->set_child_focus(next_focus_wnd); + } + return true; +} +void c_wnd::notify_parent(unsigned int msg_id, int param) +{ + if (!m_parent) + { + return; + } + const GL_MSG_ENTRY* entry = m_parent->FindMsgEntry(m_parent->GetMSgEntries(), MSG_TYPE_WND, msg_id, m_resource_id); + if (0 == entry) + { + return; + } + MSGFUNCS msg_funcs; + msg_funcs.func = entry->func; + switch (entry->callbackType) + { + case MSG_CALLBACK_VV: + (m_parent->*msg_funcs.func)(); + break; + case MSG_CALLBACK_VVL: + (m_parent->*msg_funcs.func_vvl)(param); + break; + case MSG_CALLBACK_VWV: + (m_parent->*msg_funcs.func_vwv)(m_resource_id); + break; + case MSG_CALLBACK_VWL: + (m_parent->*msg_funcs.func_vwl)(m_resource_id, param); + break; + default: + ASSERT(false); + break; + } +} +#include +#include +#define BUFFER_LEN 16 +unsigned char s_utf8_length_table[256] = +{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 +}; +inline static int get_utf8_code(const char* s, unsigned int& output_utf8_code) +{ + unsigned char* us = (unsigned char*)s; + int utf8_bytes = s_utf8_length_table[*us]; + switch (utf8_bytes) + { + case 1: + output_utf8_code = *us; + break; + case 2: + output_utf8_code = (*us << 8) | (*(us + 1)); + break; + case 3: + output_utf8_code = (*us << 16) | ((*(us + 1)) << 8) | *(us + 2); + break; + case 4: + output_utf8_code = (*us << 24) | ((*(us + 1)) << 16) | (*(us + 2) << 8) | *(us + 3); + break; + default: + ASSERT(false); + break; + } + return utf8_bytes; +} +void c_word::draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + char buf[BUFFER_LEN]; + value_2_string(value, dot_position, buf, BUFFER_LEN); + draw_string_in_rect(surface, z_order, buf, rect, font, font_color, bg_color, align_type); +} +void c_word::draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + char buf[BUFFER_LEN]; + value_2_string(value, dot_position, buf, BUFFER_LEN); + draw_string(surface, z_order, buf, x, y, font, font_color, bg_color, align_type); +} +void c_word::draw_string_in_rect(c_surface* surface, int z_order, const char *s, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + if(0 == s) + { + return; + } + int x, y; + get_string_pos(s, font, rect, align_type, x, y); + draw_string(surface, z_order, s, rect.m_left + x, rect.m_top + y, font, font_color, bg_color, ALIGN_LEFT); +} +void c_word::draw_string(c_surface* surface, int z_order, const char *s, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type) +{ + if (0 == s) + { + return; + } + int offset = 0; + unsigned int utf8_code; + while (*s) + { + s += get_utf8_code(s, utf8_code); + offset += draw_single_char(surface, z_order, utf8_code, (x + offset), y, font, font_color, bg_color); + } +} +void c_word::value_2_string(int value, int dot_position, char* buf, int len) +{ + memset(buf, 0, len); + switch (dot_position) + { + case 0: + sprintf(buf, "%d", value); + break; + case 1: + sprintf(buf, "%.1f", value*1.0 / 10); + break; + case 2: + sprintf(buf, "%.2f", value*1.0 / 100); + break; + case 3: + sprintf(buf, "%.3f", value*1.0 / 1000); + break; + default: + ASSERT(false); + break; + } +} +const LATTICE* c_word::get_lattice(const FONT_INFO* font, unsigned int utf8_code) +{ + int first = 0; + int last = font->count - 1; + int middle = (first + last) / 2; + while (first <= last) + { + if (font->lattice_array[middle].utf8_code < utf8_code) + first = middle + 1; + else if (font->lattice_array[middle].utf8_code == utf8_code) + { + return &font->lattice_array[middle]; + } + else + { + last = middle - 1; + } + middle = (first + last) / 2; + } + return 0; +} +int c_word::draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color) +{ + unsigned int error_color = 0xFFFFFFFF; + if (font) + { + const LATTICE* p_lattice = get_lattice(font, utf8_code); + if (p_lattice) + { + draw_lattice(surface, z_order, x, y, p_lattice->width, font->height, p_lattice->pixel_gray_array, font_color, bg_color); + return p_lattice->width; + } + } + else + { + error_color = GL_RGB(255, 0, 0); + } + + //lattice/font not found, draw "X" + int len = 16; + for (int y_ = 0; y_ < len; y_++) + { + for (int x_ = 0; x_ < len; x_++) + { + int diff = (x_ - y_); + int sum = (x_ + y_); + (diff == 0 || diff == -1 || diff == 1 || sum == len || sum == (len - 1) || sum == (len + 1)) ? + surface->draw_pixel((x + x_), (y + y_), error_color, z_order) : surface->draw_pixel((x + x_), (y + y_), 0, z_order); + } + } + return len; +} +void c_word::draw_lattice(c_surface* surface, int z_order, int x, int y, int width, int height, + const unsigned char* p_data, unsigned int font_color, unsigned int bg_color) +{ + unsigned int r, g, b, rgb; + unsigned char blk_value = *p_data++; + unsigned char blk_cnt = *p_data++; + b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8; + g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8; + r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8; + rgb = GL_RGB(r, g, b); + for (int y_ = 0; y_ < height; y_++) + { + for (int x_ = 0; x_ < width; x_++) + { + ASSERT(blk_cnt); + if (0x00 == blk_value) + { + if (GL_ARGB_A(bg_color)) + { + surface->draw_pixel(x + x_, y + y_, bg_color, z_order); + } + } + else + { + surface->draw_pixel((x + x_), (y + y_), rgb, z_order); + } + if (--blk_cnt == 0) + {//reload new block + blk_value = *p_data++; + blk_cnt = *p_data++; + b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8; + g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8; + r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8; + rgb = GL_RGB(r, g, b); + } + } + } +} +int c_word::get_str_size(const char *s, const FONT_INFO* font, int& width, int& height) +{ + if(0 == s || 0 == font) + { + width = height = 0; + return -1; + } + int lattice_width = 0; + unsigned int utf8_code; + int utf8_bytes; + while (*s) + { + utf8_bytes = get_utf8_code(s, utf8_code); + const LATTICE* p_lattice = get_lattice(font, utf8_code); + lattice_width += p_lattice?p_lattice->width:font->height; + s += utf8_bytes; + } + width = lattice_width; + height = font->height; + return 0; +} +void c_word::get_string_pos(const char *s, const FONT_INFO* font, c_rect rect, unsigned int align_type, int &x, int &y) +{ + int x_size, y_size; + get_str_size(s, font, x_size, y_size); + int height = rect.m_bottom - rect.m_top + 1; + int width = rect.m_right - rect.m_left + 1; + x = y = 0; + switch (align_type & ALIGN_HMASK) + { + case ALIGN_HCENTER: + //m_text_org_x=0 + if (width > x_size) + { + x = (width - x_size)/2; + } + break; + case ALIGN_LEFT: + x = 0; + break; + case ALIGN_RIGHT: + //m_text_org_x=0 + if (width > x_size) + { + x = width - x_size; + } + break; + default: + ASSERT(0); + break; + } + switch (align_type & ALIGN_VMASK) + { + case ALIGN_VCENTER: + //m_text_org_y=0 + if (height > y_size) + { + y = (height - y_size)/2; + } + break; + case ALIGN_TOP: + y = 0; + break; + case ALIGN_BOTTOM: + //m_text_org_y=0 + if (height > y_size) + { + y = height - y_size; + } + break; + default: + ASSERT(0); + break; + } +} +#include +#include +#include +#include +#include +#include +#define MAX_TIMER_CNT 10 +#define TIMER_UNIT 50//ms +static void(*do_assert)(const char* file, int line); +static void(*do_log_out)(const char* log); +void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log)) +{ + do_assert = my_assert; + do_log_out = my_log_out; +} +void _assert(const char* file, int line) +{ + static char s_buf[192]; + if (do_assert) + { + do_assert(file, line); + } + else + { + memset(s_buf, 0, sizeof(s_buf)); + sprintf_s(s_buf, sizeof(s_buf), "vvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\nAssert@ file = %s, line = %d\n\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", file, line); + OutputDebugStringA(s_buf); + printf("%s", s_buf); + fflush(stdout); + assert(false); + } +} +void log_out(const char* log) +{ + if (do_log_out) + { + do_log_out(log); + } + else + { + printf("%s", log); + fflush(stdout); + OutputDebugStringA(log); + } +} +typedef struct _timer_manage +{ + struct _timer_info + { + int state; /* on or off */ + int interval; + int elapse; /* 0~interval */ + void (* timer_proc) (void* ptmr, void* parg); + }timer_info[MAX_TIMER_CNT]; + void (* old_sigfunc)(int); + void (* new_sigfunc)(int); +}_timer_manage_t; +static struct _timer_manage timer_manage; +DWORD WINAPI timer_routine(LPVOID lpParam) +{ + int i; + while(true) + { + for(i = 0; i < MAX_TIMER_CNT; i++) + { + if(timer_manage.timer_info[i].state == 0) + { + continue; + } + timer_manage.timer_info[i].elapse++; + if(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval) + { + timer_manage.timer_info[i].elapse = 0; + timer_manage.timer_info[i].timer_proc(0, 0); + } + } + Sleep(TIMER_UNIT); + } + return 0; +} +static int init_mul_timer() +{ + static bool s_is_init = false; + if(s_is_init == true) + { + return 0; + } + memset(&timer_manage, 0, sizeof(struct _timer_manage)); + DWORD pid; + CreateThread(0, 0, timer_routine, 0, 0, &pid); + s_is_init = true; + return 1; +} +static int set_a_timer(int interval, void (* timer_proc) (void* ptmr, void* parg)) +{ + init_mul_timer(); + int i; + if(timer_proc == 0 || interval <= 0) + { + return (-1); + } + for(i = 0; i < MAX_TIMER_CNT; i++) + { + if(timer_manage.timer_info[i].state == 1) + { + continue; + } + memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i])); + timer_manage.timer_info[i].timer_proc = timer_proc; + timer_manage.timer_info[i].interval = interval; + timer_manage.timer_info[i].elapse = 0; + timer_manage.timer_info[i].state = 1; + break; + } + if(i >= MAX_TIMER_CNT) + { + ASSERT(false); + return (-1); + } + return (i); +} +typedef void (*EXPIRE_ROUTINE)(void* arg); +EXPIRE_ROUTINE s_expire_function; +static c_fifo s_real_timer_fifo; +static DWORD WINAPI fire_real_timer(LPVOID lpParam) +{ + char dummy; + while(1) + { + if(s_real_timer_fifo.read(&dummy, 1) > 0) + { + if(s_expire_function)s_expire_function(0); + } + else + { + ASSERT(false); + } + } + return 0; +} +/*Win32 desktop only +static void CALLBACK trigger_real_timer(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR) +{ + char dummy = 0x33; + s_real_timer_fifo.write(&dummy, 1); +} +*/ +static DWORD WINAPI trigger_real_timer(LPVOID lpParam) +{ + char dummy = 0x33; + while (1) + { + s_real_timer_fifo.write(&dummy, 1); + Sleep(REAL_TIME_TASK_CYCLE_MS); + } + return 0; +} +void start_real_timer(void (*func)(void* arg)) +{ + if(0 == func) + { + return; + } + s_expire_function = func; + //timeSetEvent(REAL_TIME_TASK_CYCLE_MS, 0, trigger_real_timer, 0, TIME_PERIODIC);//Win32 desktop only + static DWORD s_pid; + if(s_pid == 0) + { + CreateThread(0, 0, trigger_real_timer, 0, 0, &s_pid); + CreateThread(0, 0, fire_real_timer, 0, 0, &s_pid); + } +} +unsigned int get_cur_thread_id() +{ + return GetCurrentThreadId(); +} +void register_timer(int milli_second,void func(void* ptmr, void* parg)) +{ + set_a_timer(milli_second/TIMER_UNIT,func); +} +long get_time_in_second() +{ + return time(0); +} +T_TIME get_time() +{ + T_TIME ret = {0}; + + SYSTEMTIME time; + GetLocalTime(&time); + ret.year = time.wYear; + ret.month = time.wMonth; + ret.day = time.wDay; + ret.hour = time.wHour; + ret.minute = time.wMinute; + ret.second = time.wSecond; + return ret; +} +T_TIME second_to_day(long second) +{ + T_TIME ret; + ret.year = 1999; + ret.month = 10; + ret.date = 1; + ret.second = second % 60; + second /= 60; + ret.minute = second % 60; + second /= 60; + ret.hour = (second + 8) % 24;//China time zone. + return ret; +} +void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg) +{ + DWORD pid = 0; + CreateThread(0, 0, LPTHREAD_START_ROUTINE(start_routine), arg, 0, &pid); + *thread_id = pid; +} +void thread_sleep(unsigned int milli_seconds) +{ + Sleep(milli_seconds); +} +#pragma pack(push,1) +typedef struct { + unsigned short bfType; + unsigned int bfSize; + unsigned short bfReserved1; + unsigned short bfReserved2; + unsigned int bfOffBits; +}FileHead; +typedef struct { + unsigned int biSize; + int biWidth; + int biHeight; + unsigned short biPlanes; + unsigned short biBitCount; + unsigned int biCompress; + unsigned int biSizeImage; + int biXPelsPerMeter; + int biYPelsPerMeter; + unsigned int biClrUsed; + unsigned int biClrImportant; + unsigned int biRedMask; + unsigned int biGreenMask; + unsigned int biBlueMask; +}Infohead; +#pragma pack(pop) +int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data) +{ + FileHead bmp_head; + Infohead bmp_info; + int size = width * height * 2; + //initialize bmp head. + bmp_head.bfType = 0x4d42; + bmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead); + bmp_head.bfReserved1 = bmp_head.bfReserved2 = 0; + bmp_head.bfOffBits = bmp_head.bfSize - size; + //initialize bmp info. + bmp_info.biSize = 40; + bmp_info.biWidth = width; + bmp_info.biHeight = height; + bmp_info.biPlanes = 1; + bmp_info.biBitCount = 16; + bmp_info.biCompress = 3; + bmp_info.biSizeImage = size; + bmp_info.biXPelsPerMeter = 0; + bmp_info.biYPelsPerMeter = 0; + bmp_info.biClrUsed = 0; + bmp_info.biClrImportant = 0; + //RGB565 + bmp_info.biRedMask = 0xF800; + bmp_info.biGreenMask = 0x07E0; + bmp_info.biBlueMask = 0x001F; + //copy the data + FILE *fp; + if (!(fp = fopen(filename, "wb"))) + { + return -1; + } + fwrite(&bmp_head, 1, sizeof(FileHead), fp); + fwrite(&bmp_info, 1, sizeof(Infohead), fp); + //fwrite(data, 1, size, fp);//top <-> bottom + for (int i = (height - 1); i >= 0; --i) + { + fwrite(&data[i * width * 2], 1, width * 2, fp); + } + fclose(fp); + return 0; +} +c_fifo::c_fifo() +{ + m_head = m_tail = 0; + m_read_sem = CreateSemaphore(0, // default security attributes + 0, // initial count + 1, // maximum count + 0); // unnamed semaphore + m_write_mutex = CreateMutex(0, false, 0); +} +int c_fifo::read(void* buf, int len) +{ + unsigned char* pbuf = (unsigned char*)buf; + int i = 0; + while (i < len) + { + if (m_tail == m_head) + {//empty + WaitForSingleObject(m_read_sem, INFINITE); + continue; + } + *pbuf++ = m_buf[m_head]; + m_head = (m_head + 1) % FIFO_BUFFER_LEN; + i++; + } + if (i != len) + { + ASSERT(false); + } + return i; +} +int c_fifo::write(void* buf, int len) +{ + unsigned char* pbuf = (unsigned char*)buf; + int i = 0; + int tail = m_tail; + WaitForSingleObject(m_write_mutex, INFINITE); + while (i < len) + { + if ((m_tail + 1) % FIFO_BUFFER_LEN == m_head) + {//full, clear data has been written; + m_tail = tail; + log_out("Warning: fifo full\n"); + ReleaseMutex(m_write_mutex); + return 0; + } + m_buf[m_tail] = *pbuf++; + m_tail = (m_tail + 1) % FIFO_BUFFER_LEN; + i++; + } + ReleaseMutex(m_write_mutex); + if (i != len) + { + ASSERT(false); + } + else + { + ReleaseSemaphore(m_read_sem, 1, 0); + } + return i; +} +#include +#include +#include +#ifndef AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM + #define AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM 0x80000000 +#endif +#define AUDIO_CHANNELS_MONO 1 +#define AUDIO_SAMPLE_RATE 44000 +#define AUDIO_BITS 16 +#define AUDIO_BLOCK_ALIGN (AUDIO_CHANNELS_MONO * (AUDIO_BITS >> 3)) +#define AUDIO_BYTE_RATE (AUDIO_SAMPLE_RATE * AUDIO_BLOCK_ALIGN) +#define AUDIO_OUTPUT_BUF_LEN (10000000 * 5) //5 seconds long. +#define CHECK_ERROR(ret) if(ret != 0){ASSERT(false);} +typedef struct +{ + AUDIO_TYPE type; +}AUDIO_REQUEST; +typedef struct +{ + BYTE* p_data; + int size; +}WAV_RESOURCE; +static WAV_RESOURCE s_wav_resource[AUDIO_MAX]; +static c_fifo s_request_fifo; +static IAudioClient* s_audio_client; +static IAudioRenderClient* s_audio_render_client; +static HANDLE s_audio_event; +//Should be call by UWP, and UWP create audio client. +void set_audio_client(IAudioClient* audio_client) +{ + s_audio_client = audio_client; +} +static WAVEFORMATEX s_wav_format = { + WAVE_FORMAT_PCM, + AUDIO_CHANNELS_MONO, + AUDIO_SAMPLE_RATE, + AUDIO_BYTE_RATE, + AUDIO_BLOCK_ALIGN, + AUDIO_BITS, + 0 +}; +static int register_wav_resouce(AUDIO_TYPE type, const wchar_t* wav_path) +{ + if (s_wav_resource[type].p_data) + { + return 0; + } + + void* hFile = CreateFile(wav_path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (INVALID_HANDLE_VALUE == hFile) + { + log_out("Open wave file failed\n"); + return -1; + } + LARGE_INTEGER ret; + GetFileSizeEx(hFile, &ret); + int size = ret.LowPart; + if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, 0x2C, 0, FILE_BEGIN)) + { + ASSERT(false); + return -2; + } + size -= 0x2C; + BYTE* p_data = (BYTE*)malloc(size); + DWORD read_num; + ReadFile(hFile, p_data, size, &read_num, 0); + s_wav_resource[type].p_data = p_data; + s_wav_resource[type].size = size; + return 0; +} +static int load_wav_chunk(BYTE* p_des, int des_size, BYTE* p_src, int src_size) +{ + if (des_size <= 0 || src_size <= 0) + { + return -1; + } + int write_size = (src_size > des_size) ? des_size : src_size; + memcpy(p_des, p_src, write_size); + memset(p_des + write_size, 0, (des_size - write_size)); + return write_size; +} +static int play_wav(BYTE* p_data, int size) +{ + if (0 == p_data || 0 >= size) + { + return -1; + } + UINT32 bufferFrameCount; + UINT32 numFramesAvailable; + UINT32 numFramesPadding; + BYTE* p_buffer = 0; + int ret = s_audio_client->GetBufferSize(&bufferFrameCount); + CHECK_ERROR(ret); + + int offset = 0; + while (WaitForSingleObject(s_audio_event, INFINITE) == WAIT_OBJECT_0) + { + ret = s_audio_client->GetCurrentPadding(&numFramesPadding); + CHECK_ERROR(ret); + numFramesAvailable = bufferFrameCount - numFramesPadding; + if (numFramesAvailable < 1600) + { + Sleep(10); + continue; + } + ret = s_audio_render_client->GetBuffer(numFramesAvailable, &p_buffer); + CHECK_ERROR(ret); + ret = load_wav_chunk(p_buffer, numFramesAvailable * s_wav_format.nBlockAlign, p_data + offset, (size - offset)); + if (ret > 0) + { + s_audio_render_client->ReleaseBuffer((ret / s_wav_format.nBlockAlign), 0); + offset += ret; + } + else + { + s_audio_render_client->ReleaseBuffer(0, AUDCLNT_BUFFERFLAGS_SILENT); + break; + } + } + return 0; +} +static void* render_thread(void* param) +{ + s_audio_client->Start(); + while (true) + { + AUDIO_REQUEST request; + s_request_fifo.read(&request, sizeof(request)); + + if (AUDIO_MAX <= request.type) + { + ASSERT(false); + continue; + } + play_wav(s_wav_resource[request.type].p_data, s_wav_resource[request.type].size); + } + s_audio_client->Stop(); +} +static int init_audio_client() +{ + if (s_audio_client) + { + return 0; + } + //For desktop only, could not pass Windows Store certification. + /* + int ret = CoInitializeEx(0, COINIT_MULTITHREADED); + CHECK_ERROR(ret); + IMMDeviceEnumerator *pEnumerator = nullptr; + ret = CoCreateInstance(__uuidof(MMDeviceEnumerator), 0, + CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), + (void**)&pEnumerator); + CHECK_ERROR(ret); + IMMDevice* audio_output_device; + pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &audio_output_device); + if (0 == audio_output_device) + { + ASSERT(false); + } + ret = audio_output_device->Activate(__uuidof(IAudioClient), CLSCTX_ALL, 0, (void**)&s_audio_client); + CHECK_ERROR(ret); + return 0; + */ + return -1; +} +void c_audio::init() +{ + static bool s_flag = false; + if (s_flag) + { + return; + } + register_wav_resouce(AUDIO_HEART_BEAT, L"heart_beat.wav"); + + if (0 > init_audio_client()) + { + return; + } + int ret = s_audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, + AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + AUDIO_OUTPUT_BUF_LEN * 2, 0, &s_wav_format, 0); + CHECK_ERROR(ret); + //s_audio_event = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS); + s_audio_event = CreateEvent(0, 0, 0, 0); + ret = s_audio_client->SetEventHandle(s_audio_event); + CHECK_ERROR(ret); + ret = s_audio_client->GetService(__uuidof(IAudioRenderClient), (void**)&s_audio_render_client); + CHECK_ERROR(ret); + unsigned long pid; + create_thread(&pid, 0, render_thread, 0); + s_flag = true; +} +int c_audio::play(AUDIO_TYPE type) +{ + if (AUDIO_MAX <= type) + { + return -1; + } + init(); + if (!s_audio_client || !s_audio_render_client) + { + return -2; + } + AUDIO_REQUEST request; + request.type = type; + s_request_fifo.write(&request, sizeof(request)); + return 0; +} +void c_button::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); +} +void c_button::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_button::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +bool c_button::on_touch(int x, int y, TOUCH_ACTION action) +{ + if (action == TOUCH_DOWN) + { + m_parent->set_child_focus(this); + m_status = STATUS_PUSHED; + on_paint(); + } + else + { + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_BN_CLICKED, 0); + } + return true; +} +bool c_button::on_key(KEY_TYPE key) +{ + if (key == KEY_ENTER) + { + notify_parent(GL_BN_CLICKED, 0); + return false;// Do not handle KEY_ENTER by other wnd. + } + return true;// Handle KEY_FOWARD/KEY_BACKWARD by parent wnd. +} +void c_button::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + case STATUS_FOCUSED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + if (m_str) + { + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + } + break; + default: + ASSERT(false); + break; + } +} +DIALOG_ARRAY c_dialog::ms_the_dialogs[SURFACE_CNT_MAX]; +void c_dialog::pre_create_wnd() +{ + m_attr = WND_ATTRIBUTION(0);// no focus/visible + m_z_order = Z_ORDER_LEVEL_1; + m_bg_color = GL_RGB(33, 42, 53); +} +void c_dialog::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + m_surface->fill_rect(rect, m_bg_color, m_z_order); + if (m_str) + { + c_word::draw_string(m_surface, m_z_order, m_str, rect.m_left+35, rect.m_top, c_theme::get_font(FONT_DEFAULT), GL_RGB(255, 255, 255), GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + } +} +c_dialog* c_dialog::get_the_dialog(c_surface* surface) +{ + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + return ms_the_dialogs[i].dialog; + } + } + return 0; +} +int c_dialog::open_dialog(c_dialog* p_dlg, bool modal_mode) +{ + if (0 == p_dlg) + { + ASSERT(false); + return 0; + } + c_dialog* cur_dlg = get_the_dialog(p_dlg->get_surface()); + if (cur_dlg == p_dlg) + { + return 1; + } + if(cur_dlg) + { + cur_dlg->set_attr(WND_ATTRIBUTION(0)); + } + c_rect rc; + p_dlg->get_screen_rect(rc); + p_dlg->get_surface()->set_frame_layer_visible_rect(rc, Z_ORDER_LEVEL_1); + p_dlg->set_attr(modal_mode ? (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL) : (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)); + p_dlg->show_window(); + p_dlg->set_me_the_dialog(); + return 1; +} +int c_dialog::close_dialog(c_surface* surface) +{ + c_dialog* dlg = get_the_dialog(surface); + if (0 == dlg) + { + return 0; + } + c_rect rc; + + dlg->set_attr(WND_ATTRIBUTION(0)); + surface->set_frame_layer_visible_rect(rc, dlg->m_z_order); + //clear the dialog + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + ms_the_dialogs[i].dialog = 0; + return 1; + } + } + ASSERT(false); + return -1; +} +int c_dialog::set_me_the_dialog() +{ + c_surface* surface = get_surface(); + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == surface) + { + ms_the_dialogs[i].dialog = this; + return 0; + } + } + for(int i = 0; i < SURFACE_CNT_MAX; i++) + { + if(ms_the_dialogs[i].surface == 0) + { + ms_the_dialogs[i].dialog = this; + if(this) + { + ms_the_dialogs[i].surface = surface; + } + return 1; + } + } + ASSERT(false); + return -2; +} +#include +#define IDD_KEY_BOARD 0x1 +GL_BEGIN_MESSAGE_MAP(c_edit) +ON_KEYBORAD_UPDATE(IDD_KEY_BOARD, c_edit::on_key_board_click) +GL_END_MESSAGE_MAP() +static c_keyboard s_keyboard; +void c_edit::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_kb_style = STYLE_ALL_BOARD; + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); + memset(m_str_input, 0, sizeof(m_str_input)); + memset(m_str, 0, sizeof(m_str)); + set_text(c_wnd::m_str); +} +void c_edit::set_text(const char* str) +{ + if (str != 0 && strlen(str) < sizeof(m_str)) + { + strcpy(m_str, str); + } +} +bool c_edit::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return true; +} +void c_edit::on_touch_down(int x, int y) +{ + c_rect kb_rect_relate_2_edit_parent; + s_keyboard.get_wnd_rect(kb_rect_relate_2_edit_parent); + kb_rect_relate_2_edit_parent.m_left += m_wnd_rect.m_left; + kb_rect_relate_2_edit_parent.m_right += m_wnd_rect.m_left; + kb_rect_relate_2_edit_parent.m_top += m_wnd_rect.m_top; + kb_rect_relate_2_edit_parent.m_bottom += m_wnd_rect.m_top; + if (m_wnd_rect.PtInRect(x, y)) + {//click edit box + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } + } + else if (kb_rect_relate_2_edit_parent.PtInRect(x,y)) + {//click key board + c_wnd::on_touch(x, y, TOUCH_DOWN); + } + else + { + if (STATUS_PUSHED == m_status) + { + m_status = STATUS_FOCUSED; + on_paint(); + } + } +} +void c_edit::on_touch_up(int x, int y) +{ + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + if (m_wnd_rect.PtInRect(x,y)) + {//click edit box + m_status = STATUS_FOCUSED; + on_paint(); + } + else + { + c_wnd::on_touch(x, y, TOUCH_UP); + } + } +} +void c_edit::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_edit::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +void c_edit::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + c_rect empty_rect; + empty_rect.Empty(); + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + s_keyboard.disconnect(); + m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + s_keyboard.disconnect(); + m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); + show_keyboard(); + } + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_PUSHED), m_parent->get_z_order()); + m_surface->draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_BORDER), m_parent->get_z_order(), 2); + strlen(m_str_input) ? c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str_input, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER) : + c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + break; + default: + ASSERT(false); + } +} +void c_edit::show_keyboard() +{ + s_keyboard.connect(this, IDD_KEY_BOARD, m_kb_style); + c_rect kb_rect; + s_keyboard.get_screen_rect(kb_rect); + m_surface->set_frame_layer_visible_rect(kb_rect, s_keyboard.get_z_order()); + s_keyboard.show_window(); +} +void c_edit::on_key_board_click(unsigned int ctrl_id, long param) +{ + switch (param) + { + case CLICK_CHAR: + strcpy(m_str_input, s_keyboard.get_str()); + on_paint(); + break; + case CLICK_ENTER: + if (strlen(m_str_input)) + { + memcpy(m_str, m_str_input, sizeof(m_str_input)); + } + m_status = STATUS_FOCUSED; + on_paint(); + break; + case CLICK_ESC: + memset(m_str_input, 0, sizeof(m_str_input)); + m_status = STATUS_FOCUSED; + on_paint(); + break; + default: + ASSERT(false); + break; + } +} +#include +//#define SWIPE_STEP 300//for arm +#define SWIPE_STEP 10//for PC & ANDROID +#define MOVE_THRESHOLD 10 +c_gesture::c_gesture(c_slide_group* group) +{ + m_slide_group = group; + m_state = TOUCH_IDLE; + m_down_x = m_down_y = m_move_x = m_move_y = 0; +} +bool c_gesture::handle_swipe(int x, int y, TOUCH_ACTION action) +{ + if(action == TOUCH_DOWN)//MOUSE_LBUTTONDOWN + { + if(m_state == TOUCH_IDLE) + { + m_state = TOUCH_MOVE; + m_move_x = m_down_x = x; + return true; + } + else//TOUCH_MOVE + { + return on_move(x); + } + } + else if(action == TOUCH_UP)//MOUSE_LBUTTONUP + { + if(m_state == TOUCH_MOVE) + { + m_state = TOUCH_IDLE; + return on_swipe(x); + } + else + { + return false; + //ASSERT(false); + } + } + return true; +} +bool c_gesture::on_move(int x) +{ + if (m_slide_group == 0) + { + return true; + } + if (abs(x - m_move_x) < MOVE_THRESHOLD) + { + return false; + } + m_slide_group->disabel_all_slide(); + m_move_x = x; + if ((m_move_x - m_down_x) > 0) + { + move_right(); + } + else + { + move_left(); + } + return false; +} +bool c_gesture::on_swipe(int x) +{ + if (m_slide_group == 0) + { + return true; + } + if ((m_down_x == m_move_x) && (abs(x - m_down_x) < MOVE_THRESHOLD)) + { + return true; + } + m_slide_group->disabel_all_slide(); + int page = -1; + m_move_x = x; + if ((m_move_x - m_down_x) > 0) + { + page = swipe_right(); + } + else + { + page = swipe_left(); + } + if (page >= 0) + { + m_slide_group->set_active_slide(page); + } + else + { + m_slide_group->set_active_slide(m_slide_group->get_active_slide_index(), false); + } + return false; +} +int c_gesture::swipe_left() +{ + if (m_slide_group == 0) + { + return -1; + } + int index = m_slide_group->get_active_slide_index(); + if((index + 1) >= MAX_PAGES || + m_slide_group->get_slide(index + 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return -2; + } + c_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + if (s1->get_display() != s2->get_display()) + { + return -3; + } + int step = m_down_x - m_move_x; + c_rect rc; + m_slide_group->get_screen_rect(rc); + while(step < rc.Width()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step); + step += SWIPE_STEP; + } + if (step != rc.Width()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, rc.Width()); + } + return (index + 1); +} +int c_gesture::swipe_right() +{ + if (m_slide_group == 0) + { + return -1; + } + int index = m_slide_group->get_active_slide_index(); + if(index <= 0 || + m_slide_group->get_slide(index - 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return -2; + } + c_surface* s1 = m_slide_group->get_slide(index -1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + if (s1->get_display() != s2->get_display()) + { + return -3; + } + c_rect rc; + m_slide_group->get_screen_rect(rc); + int step = rc.Width() - (m_move_x - m_down_x); + while(step > 0) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step); + step -= SWIPE_STEP; + } + if (step != 0) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, 0); + } + return (index - 1); +} +void c_gesture::move_left() +{ + int index = m_slide_group->get_active_slide_index(); + if((index + 1) >= MAX_PAGES || + m_slide_group->get_slide(index + 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return; + } + c_surface* s1 = m_slide_group->get_slide(index +1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + c_rect rc; + m_slide_group->get_screen_rect(rc); + if(s1->get_display() == s2->get_display()) + { + s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (m_down_x - m_move_x)); + } +} +void c_gesture::move_right() +{ + int index = m_slide_group->get_active_slide_index(); + if(index <= 0 || + m_slide_group->get_slide(index - 1) == 0 || + m_slide_group->get_slide(index) == 0) + { + return; + } + c_surface* s1 = m_slide_group->get_slide(index -1)->get_surface(); + c_surface* s2 = m_slide_group->get_slide(index)->get_surface(); + c_rect rc; + m_slide_group->get_screen_rect(rc); + if(s1->get_display() == s2->get_display()) + { + s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (rc.Width() - (m_move_x - m_down_x))); + } +} +#include +//Changing key width/height will change the width/height of keyboard +#define KEY_WIDTH 65 +#define KEY_HEIGHT 38 +#define KEYBOARD_WIDTH ((KEY_WIDTH + 2) * 10) +#define KEYBOARD_HEIGHT ((KEY_HEIGHT + 2) * 4) +#define NUM_BOARD_WIDTH ((KEY_WIDTH + 2) * 4) +#define NUM_BOARD_HEIGHT ((KEY_HEIGHT + 2) * 4) +#define CAPS_WIDTH (KEY_WIDTH * 3 / 2) +#define DEL_WIDTH (KEY_WIDTH * 3 / 2 + 1) +#define ESC_WIDTH (KEY_WIDTH * 2 + 2) +#define SWITCH_WIDTH (KEY_WIDTH * 3 / 2 ) +#define SPACE_WIDTH (KEY_WIDTH * 3 + 2 * 2) +#define DOT_WIDTH (KEY_WIDTH * 3 / 2 + 3) +#define ENTER_WIDTH (KEY_WIDTH * 2 + 2) +#define POS_X(c) ((KEY_WIDTH * c) + (c + 1) * 2) +#define POS_Y(r) ((KEY_HEIGHT * r) + (r + 1) * 2) +static c_keyboard_button s_button_0,s_button_1, s_button_2, s_button_3, s_button_4, s_button_5, s_button_6, s_button_7, s_button_8, s_button_9; +static c_keyboard_button s_button_A, s_button_B, s_button_C, s_button_D, s_button_E, s_button_F, s_button_G, s_button_H, s_button_I, s_button_J; +static c_keyboard_button s_button_K, s_button_L, s_button_M, s_button_N, s_button_O, s_button_P, s_button_Q, s_button_R, s_button_S, s_button_T; +static c_keyboard_button s_button_U, s_button_V, s_button_W, s_button_X, s_button_Y, s_button_Z; +static c_keyboard_button s_button_dot, s_button_caps, s_button_space, s_button_enter, s_button_del, s_button_esc, s_button_num_switch; +WND_TREE g_key_board_children[] = +{ + //Row 1 + {&s_button_Q, 'Q', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_W, 'W', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_E, 'E', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_R, 'R', 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_T, 'T', 0, POS_X(4), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_Y, 'Y', 0, POS_X(5), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_U, 'U', 0, POS_X(6), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_I, 'I', 0, POS_X(7), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_O, 'O', 0, POS_X(8), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_P, 'P', 0, POS_X(9), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + //Row 2 + {&s_button_A, 'A', 0, ((KEY_WIDTH / 2) + POS_X(0)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_S, 'S', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_D, 'D', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_F, 'F', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_G, 'G', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_H, 'H', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_J, 'J', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_K, 'K', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_L, 'L', 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + //Row 3 + {&s_button_caps, 0x14, 0, POS_X(0), POS_Y(2), CAPS_WIDTH, KEY_HEIGHT}, + {&s_button_Z, 'Z', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_X, 'X', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_C, 'C', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_V, 'V', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_B, 'B', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_N, 'N', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_M, 'M', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_del, 0x7F, 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(2), DEL_WIDTH, KEY_HEIGHT}, + //Row 4 + {&s_button_esc, 0x1B, 0, POS_X(0), POS_Y(3), ESC_WIDTH, KEY_HEIGHT}, + {&s_button_num_switch, 0x90, 0, POS_X(2), POS_Y(3), SWITCH_WIDTH, KEY_HEIGHT}, + {&s_button_space, ' ', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(3), SPACE_WIDTH, KEY_HEIGHT}, + {&s_button_dot, '.', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(3), DOT_WIDTH, KEY_HEIGHT}, + {&s_button_enter, '\n', 0, POS_X(8), POS_Y(3), ENTER_WIDTH, KEY_HEIGHT}, + {0,0,0,0,0,0,0} +}; +WND_TREE g_number_board_children[] = +{ + {&s_button_1, '1', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_2, '2', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_3, '3', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_del, 0x7F, 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT * 2 + 2}, + {&s_button_4, '4', 0, POS_X(0), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_5, '5', 0, POS_X(1), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_6, '6', 0, POS_X(2), POS_Y(1), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_7, '7', 0, POS_X(0), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_8, '8', 0, POS_X(1), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_9, '9', 0, POS_X(2), POS_Y(2), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_enter,'\n', 0, POS_X(3), POS_Y(2), KEY_WIDTH, KEY_HEIGHT * 2 + 2}, + {&s_button_esc, 0x1B, 0, POS_X(0), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_0, '0', 0, POS_X(1), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {&s_button_dot, '.', 0, POS_X(2), POS_Y(3), KEY_WIDTH, KEY_HEIGHT}, + {0,0,0,0,0,0,0} +}; +GL_BEGIN_MESSAGE_MAP(c_keyboard) +ON_GL_BN_CLICKED('A', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('B', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('C', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('D', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('E', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('F', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('G', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('H', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('I', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('J', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('K', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('L', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('M', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('N', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('O', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('P', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Q', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('R', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('S', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('T', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('U', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('V', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('W', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('X', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Y', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('Z', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('0', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('1', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('2', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('3', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('4', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('5', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('6', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('7', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('8', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('9', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED(' ', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED('.', c_keyboard::on_char_clicked) +ON_GL_BN_CLICKED(0x7F, c_keyboard::on_del_clicked) +ON_GL_BN_CLICKED(0x14, c_keyboard::on_caps_clicked) +ON_GL_BN_CLICKED('\n', c_keyboard::on_enter_clicked) +ON_GL_BN_CLICKED(0x1B, c_keyboard::on_esc_clicked) +GL_END_MESSAGE_MAP() +int c_keyboard::connect(c_wnd *user, unsigned short resource_id, KEYBOARD_STYLE style) +{ + c_rect user_rect; + user->get_wnd_rect(user_rect); + if (style == STYLE_ALL_BOARD) + {//Place keyboard at the bottom of user's parent window. + c_rect user_parent_rect; + user->get_parent()->get_wnd_rect(user_parent_rect); + return c_wnd::connect(user, resource_id, 0, (0 - user_rect.m_left), (user_parent_rect.Height() - user_rect.m_top - KEYBOARD_HEIGHT), KEYBOARD_WIDTH, KEYBOARD_HEIGHT, g_key_board_children); + } + else if(style == STYLE_NUM_BOARD) + {//Place keyboard below the user window. + return c_wnd::connect(user, resource_id, 0, 0, user_rect.Height(), NUM_BOARD_WIDTH, NUM_BOARD_HEIGHT, g_number_board_children); + } + else + { + ASSERT(false); + } + return -1; +} +void c_keyboard::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_cap_status = STATUS_UPPERCASE; + memset(m_str, 0, sizeof(m_str)); + m_str_len = 0; +} +void c_keyboard::on_caps_clicked(unsigned int ctrl_id) +{ + m_cap_status = (m_cap_status == STATUS_LOWERCASE) ? STATUS_UPPERCASE : STATUS_LOWERCASE; + show_window(); +} +void c_keyboard::on_enter_clicked(unsigned int ctrl_id) +{ + memset(m_str, 0, sizeof(m_str)); + notify_parent(KEYBORAD_CLICK, CLICK_ENTER); +} +void c_keyboard::on_esc_clicked(unsigned int ctrl_id) +{ + memset(m_str, 0, sizeof(m_str)); + notify_parent(KEYBORAD_CLICK, CLICK_ESC); +} +void c_keyboard::on_del_clicked(unsigned int ctrl_id) +{ + if (m_str_len <= 0) + { + return; + } + m_str[--m_str_len] = 0; + notify_parent(KEYBORAD_CLICK, CLICK_CHAR); +} +void c_keyboard::on_char_clicked(unsigned int ctrl_id) +{//ctrl_id = char ascii code. + if (m_str_len >= sizeof(m_str)) + { + return; + } + if ((ctrl_id >= '0' && ctrl_id <= '9') || ctrl_id == ' ' || ctrl_id == '.') + { + goto InputChar; + } + if (ctrl_id >= 'A' && ctrl_id <= 'Z') + { + if (STATUS_LOWERCASE == m_cap_status) + { + ctrl_id += 0x20; + } + goto InputChar; + } + ASSERT(false); +InputChar: + m_str[m_str_len++] = ctrl_id; + notify_parent(KEYBORAD_CLICK, CLICK_CHAR); +} +void c_keyboard::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + m_surface->fill_rect(rect, GL_RGB(0, 0, 0), m_z_order); +} +void c_keyboard_button::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + break; + case STATUS_FOCUSED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + break; + default: + ASSERT(false); + break; + } + + if (m_resource_id == 0x14) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Caps", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x1B) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Esc", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == ' ') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Space", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == '\n') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Enter", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == '.') + { + return c_word::draw_string_in_rect(m_surface, m_z_order, ".", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x7F) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "Back", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + else if (m_resource_id == 0x90) + { + return c_word::draw_string_in_rect(m_surface, m_z_order, "?123", rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); + } + + char letter[] = { 0, 0 }; + if (m_resource_id >= 'A' && m_resource_id <= 'Z') + { + letter[0] = (((c_keyboard*)m_parent)->get_cap_status() == STATUS_UPPERCASE) ? m_resource_id : (m_resource_id + 0x20); + } + else if (m_resource_id >= '0' && m_resource_id <= '9') + { + letter[0] = m_resource_id; + } + c_word::draw_string_in_rect(m_surface, m_z_order, letter, rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr); +} +void c_label::pre_create_wnd() +{ + m_attr = ATTR_VISIBLE; + m_font_color = c_theme::get_color(COLOR_WND_FONT); + m_font_type = c_theme::get_font(FONT_DEFAULT); +} +void c_label::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + if (m_str) + { + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, m_parent->get_bg_color(), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font_type, m_font_color, m_parent->get_bg_color(), ALIGN_LEFT | ALIGN_VCENTER); + } +} +#include +#define ITEM_HEIGHT 45 +void c_list_box::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + memset(m_item_array, 0, sizeof(m_item_array)); + m_item_total = 0; + m_selected_item = 0; + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); +} +void c_list_box::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_list_box::on_kill_focus() +{ + m_status = STATUS_NORMAL; + on_paint(); +} +void c_list_box::on_paint() +{ + c_rect rect, empty_rect; + get_screen_rect(rect); + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order); + m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font_type, GL_RGB(2, 124, 165), GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER | ALIGN_VCENTER); + //draw list + if (m_item_total > 0) + { + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + } + m_surface->set_frame_layer_visible_rect(m_list_screen_rect, m_z_order); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); + show_list(); + } + break; + default: + ASSERT(false); + } +} +bool c_list_box::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return true; +} +void c_list_box::on_touch_down(int x, int y) +{ + if (m_wnd_rect.PtInRect(x, y) ) + {//click base + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } + } + else if (m_list_wnd_rect.PtInRect(x, y)) + {//click extend list + c_wnd::on_touch(x, y, TOUCH_DOWN); + } + else + { + if (STATUS_PUSHED == m_status) + { + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_LIST_CONFIRM, m_selected_item); + } + } +} +void c_list_box::on_touch_up(int x, int y) +{ + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + if (m_wnd_rect.PtInRect(x, y)) + {//click base + m_status = STATUS_FOCUSED; + on_paint(); + } + else if (m_list_wnd_rect.PtInRect(x, y)) + {//click extend list + m_status = STATUS_FOCUSED; + select_item((y - m_list_wnd_rect.m_top) / ITEM_HEIGHT); + on_paint(); + notify_parent(GL_LIST_CONFIRM, m_selected_item); + } + else + { + c_wnd::on_touch(x, y, TOUCH_UP); + } + } +} +void c_list_box::update_list_size() +{ + m_list_wnd_rect = m_wnd_rect; + m_list_wnd_rect.m_top = m_wnd_rect.m_bottom + 1; + m_list_wnd_rect.m_bottom = m_list_wnd_rect.m_top + m_item_total * ITEM_HEIGHT; + get_screen_rect(m_list_screen_rect); + m_list_screen_rect.m_top = m_list_screen_rect.m_bottom + 1; + m_list_screen_rect.m_bottom = m_list_screen_rect.m_top + m_item_total * ITEM_HEIGHT; +} +void c_list_box::show_list() +{ + //draw all items + c_rect tmp_rect; + for (int i = 0; i < m_item_total; i++) + { + tmp_rect.m_left = m_list_screen_rect.m_left; + tmp_rect.m_right = m_list_screen_rect.m_right; + tmp_rect.m_top = m_list_screen_rect.m_top + i * ITEM_HEIGHT; + tmp_rect.m_bottom = tmp_rect.m_top + ITEM_HEIGHT; + if (m_selected_item == i) + { + m_surface->fill_rect(tmp_rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + } + else + { + m_surface->fill_rect(tmp_rect, GL_RGB(17, 17, 17), m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font_type, m_font_color, GL_RGB(17, 17, 17), ALIGN_HCENTER | ALIGN_VCENTER); + } + } +} +int c_list_box::add_item(char* str) +{ + if (m_item_total >= MAX_ITEM_NUM) + { + ASSERT(false); + return -1; + } + m_item_array[m_item_total++] = str; + update_list_size(); + return 0; +} +void c_list_box::clear_item() +{ + m_selected_item = m_item_total = 0; + memset(m_item_array, 0, sizeof(m_item_array)); + update_list_size(); +} +void c_list_box::select_item(short index) +{ + if (index < 0 || index >= m_item_total) + { + ASSERT(false); + } + m_selected_item = index; +} +c_slide_group::c_slide_group() +{ + m_gesture = new c_gesture(this); + for(int i = 0; i < MAX_PAGES; i++) + { + m_slides[i] = 0; + } + m_active_slide_index = 0; +} +int c_slide_group::set_active_slide(int index, bool is_redraw) +{ + if(index >= MAX_PAGES || index < 0) + { + return -1; + } + if(0 == m_slides[index]) + { + return -2; + } + m_active_slide_index = index; + for(int i = 0; i < MAX_PAGES; i++) + { + if(m_slides[i] == 0) + { + continue; + } + if(i == index) + { + m_slides[i]->get_surface()->set_active(true); + add_child_2_tail(m_slides[i]); + if(is_redraw) + { + c_rect rc; + get_screen_rect(rc); + m_slides[i]->get_surface()->flush_screen(rc.m_left, rc.m_top, rc.m_right, rc.m_bottom); + } + } + else + { + m_slides[i]->get_surface()->set_active(false); + } + } + return 0; +} +int c_slide_group::add_slide(c_wnd* slide, unsigned short resource_id, short x, short y, + short width, short height, WND_TREE* p_child_tree, Z_ORDER_LEVEL max_zorder) +{ + if(0 == slide) + { + return -1; + } + c_surface* old_surface = get_surface(); + c_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder); + new_surface->set_active(false); + set_surface(new_surface); + slide->connect(this, resource_id ,0 , x, y, width, height, p_child_tree); + set_surface(old_surface); + int i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == slide) + {//slide has lived + ASSERT(false); + return -2; + } + i++; + } + //new slide + i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == 0) + { + m_slides[i] = slide; + slide->show_window(); + return 0; + } + i++; + } + //no more slide can be add + ASSERT(false); + return -3; +} +int c_slide_group::add_clone_silde(c_wnd* slide, unsigned short resource_id, short x, short y, + short width, short height, WND_TREE* p_child_tree, Z_ORDER_LEVEL max_zorder) +{ + if(0 == slide) + { + return -1; + } + c_surface* old_surface = get_surface(); + c_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder); + new_surface->set_active(false); + set_surface(new_surface); + c_wnd* page_tmp = slide->connect_clone(this,resource_id,0,x,y,width,height,p_child_tree); + set_surface(old_surface); + int i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == page_tmp) + {//slide has lived + ASSERT(false); + return -2; + } + i++; + } + //new slide + i = 0; + while(i < MAX_PAGES) + { + if(m_slides[i] == 0) + { + m_slides[i] = page_tmp; + page_tmp->show_window(); + return 0; + } + i++; + } + //no more slide can be add + ASSERT(false); + return -3; +} +void c_slide_group::disabel_all_slide() +{ + for(int i = 0; i < MAX_PAGES; i++) + { + if(m_slides[i]) + { + m_slides[i]->get_surface()->set_active(false); + } + } +} +bool c_slide_group::on_touch(int x, int y, TOUCH_ACTION action) +{ + x -= m_wnd_rect.m_left; + y -= m_wnd_rect.m_top; + if (m_gesture->handle_swipe(x, y, action)) + { + if (m_slides[m_active_slide_index]) + { + m_slides[m_active_slide_index]->on_touch(x, y, action); + } + } + return true; +} +bool c_slide_group::on_key(KEY_TYPE key) +{ + if (m_slides[m_active_slide_index]) + { + m_slides[m_active_slide_index]->on_key(key); + } + return true; +} +#define ARROW_BT_HEIGHT 55 +#define ID_BT_ARROW_UP 1 +#define ID_BT_ARROW_DOWN 2 +GL_BEGIN_MESSAGE_MAP(c_spin_box) +ON_GL_BN_CLICKED(ID_BT_ARROW_UP, c_spin_box::on_arrow_up_bt_click) +ON_GL_BN_CLICKED(ID_BT_ARROW_DOWN, c_spin_box::on_arrow_down_bt_click) +GL_END_MESSAGE_MAP() +void c_spin_box::pre_create_wnd() +{ + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); + m_font_type = c_theme::get_font(FONT_DEFAULT); + m_font_color = c_theme::get_color(COLOR_WND_FONT); + m_max = 6; + m_min = 1; + m_digit = 0; + m_step = 1; + //set arrow button position. + c_rect rect; + get_screen_rect(rect); + m_bt_up_rect.m_left = rect.m_left; + m_bt_up_rect.m_right = rect.m_left + rect.Width() / 2 - 1; + m_bt_up_rect.m_top = rect.m_bottom + 1; + m_bt_up_rect.m_bottom = m_bt_up_rect.m_top + ARROW_BT_HEIGHT; + m_bt_down_rect.m_left = rect.m_left + rect.Width() / 2; + m_bt_down_rect.m_right = rect.m_right; + m_bt_down_rect.m_top = rect.m_bottom + 1; + m_bt_down_rect.m_bottom = m_bt_down_rect.m_top + ARROW_BT_HEIGHT; +} +bool c_spin_box::on_touch(int x, int y, TOUCH_ACTION action) +{ + (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y); + return c_wnd::on_touch(x, y, action); +} +void c_spin_box::on_touch_down(int x, int y) +{ + if (false == m_wnd_rect.PtInRect(x, y)) + {//maybe click on up/down arrow button + return; + } + if (STATUS_NORMAL == m_status) + { + m_parent->set_child_focus(this); + } +} +void c_spin_box::on_touch_up(int x, int y) +{ + if (false == m_wnd_rect.PtInRect(x, y)) + {//maybe click on up/down arrow button + return; + } + if (STATUS_FOCUSED == m_status) + { + m_status = STATUS_PUSHED; + on_paint(); + } + else if (STATUS_PUSHED == m_status) + { + m_value = m_cur_value; + m_status = STATUS_FOCUSED; + on_paint(); + notify_parent(GL_SPIN_CONFIRM, m_value); + } +} +void c_spin_box::on_focus() +{ + m_status = STATUS_FOCUSED; + on_paint(); +} +void c_spin_box::on_kill_focus() +{ + m_cur_value = m_value; + m_status = STATUS_NORMAL; + on_paint(); +} +void c_spin_box::show_arrow_button() +{ + m_bt_up.connect(this, ID_BT_ARROW_UP, "\xe2\x96\xb2"/*unicode of up arrow*/, 0, m_wnd_rect.Height(), m_bt_up_rect.Width(),m_bt_up_rect.Height()); + m_bt_up.show_window(); + m_bt_down.connect(this, ID_BT_ARROW_DOWN, "\xe2\x96\xbc"/*unicode of down arrow*/, m_bt_up_rect.Width(), m_wnd_rect.Height(), m_bt_down_rect.Width(),m_bt_down_rect.Height()); + m_bt_down.show_window(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_MODAL); +} +void c_spin_box::hide_arrow_button() +{ + m_bt_up.disconnect(); + m_bt_down.disconnect(); + m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); +} +void c_spin_box::on_paint() +{ + c_rect rect, tmp_rect, empty_rect; + get_screen_rect(rect); + tmp_rect.m_left = rect.m_left; + tmp_rect.m_right = rect.m_right; + switch(m_status) + { + case STATUS_NORMAL: + if (m_z_order > m_parent->get_z_order()) + { + hide_arrow_button(); + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_FOCUSED: + if (m_z_order > m_parent->get_z_order()) + { + hide_arrow_button(); + m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); + m_z_order = m_parent->get_z_order(); + } + m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER); + break; + case STATUS_PUSHED: + if (m_z_order == m_parent->get_z_order()) + { + m_z_order++; + } + tmp_rect.m_top = m_bt_down_rect.m_top; + tmp_rect.m_bottom = m_bt_down_rect.m_bottom; + m_surface->set_frame_layer_visible_rect(tmp_rect, m_z_order); + show_arrow_button(); + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_PUSHED), m_parent->get_z_order()); + m_surface->draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_BORDER), m_parent->get_z_order(), 2); + c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font_type, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER); + break; + default: + ASSERT(false); + } +} +void c_spin_box::on_arrow_up_bt_click(unsigned int ctr_id) +{ + if (m_cur_value + m_step > m_max) + { + return; + } + m_cur_value += m_step; + notify_parent(GL_SPIN_CHANGE, m_cur_value); + on_paint(); +} +void c_spin_box::on_arrow_down_bt_click(unsigned int ctr_id) +{ + if (m_cur_value - m_step < m_min) + { + return; + } + m_cur_value -= m_step; + notify_parent(GL_SPIN_CHANGE, m_cur_value); + on_paint(); +} +void c_table::set_item(int row, int col, char* str, unsigned int color) +{ + draw_item( row, col, str, color); +} +void c_table::draw_item(int row, int col, const char* str, unsigned int color) +{ + c_rect rect = get_item_rect(row, col); + m_surface->fill_rect(rect.m_left+1, rect.m_top+1, rect.m_right-1, rect.m_bottom-1, color, m_z_order); + c_word::draw_string_in_rect(m_surface, m_z_order, str, rect, m_font_type, m_font_color, GL_ARGB(0, 0, 0, 0), m_align_type); +} +void c_table::set_row_height(unsigned int height) +{ + for (unsigned int i = 0; i < m_row_num; i ++) + { + m_row_height[i] = height; + } +} +void c_table::set_col_width(unsigned int width) +{ + for (unsigned int i = 0; i < m_col_num; i ++) + { + m_col_width[i] = width; + } +} +int c_table::set_row_height(unsigned int index, unsigned int height) +{ + if (m_row_num > index) + { + m_row_height[index] = height; + return index; + } + return -1; +} +int c_table::set_col_width(unsigned int index, unsigned int width) +{ + if (m_col_num > index) + { + m_col_width[index] = width; + return index; + } + return -1; +} +c_rect c_table::get_item_rect(int row, int col) +{ + static c_rect rect; + if (row >= MAX_ROW_NUM || col >= MAX_COL_NUM) + { + return rect; + } + unsigned int width = 0; + unsigned int height = 0; + for (int i = 0; i < col; i++) + { + width += m_col_width[i]; + } + for (int j = 0; j < row; j++) + { + height += m_row_height[j]; + } + c_rect wRect; + get_screen_rect(wRect); + rect.m_left = wRect.m_left + width; + rect.m_right = rect.m_left + m_col_width[col]; + if (rect.m_right > wRect.m_right) + { + rect.m_right = wRect.m_right; + } + rect.m_top = wRect.m_top + height; + rect.m_bottom = rect.m_top + m_row_height[row]; + if (rect.m_bottom > wRect.m_bottom) + { + rect.m_bottom = wRect.m_bottom; + } + return rect; +} +#include +#include +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) +c_wave_buffer::c_wave_buffer() +{ + m_head = m_tail = m_min_old = m_max_old = + m_min_older = m_max_older = m_last_data = m_read_cache_sum = m_refresh_sequence = 0; + memset(m_wave_buf, 0, sizeof(m_wave_buf)); + memset(m_read_cache_min, 0, sizeof(m_read_cache_min)); + memset(m_read_cache_mid, 0, sizeof(m_read_cache_mid)); + memset(m_read_cache_max, 0, sizeof(m_read_cache_max)); +} +short c_wave_buffer::get_cnt() +{ + return (m_tail >= m_head)?(m_tail - m_head):(m_tail - m_head + WAVE_BUFFER_LEN); +} +int c_wave_buffer::write_wave_data(short data) +{ + if ((m_tail + 1) % WAVE_BUFFER_LEN == m_head) + {//full + //log_out("wave buf full\n"); + return BUFFER_FULL; + } + m_wave_buf[m_tail] = data; + m_tail = (m_tail + 1) % WAVE_BUFFER_LEN; + return 1; +} +int c_wave_buffer::read_data() +{ + if (m_head == m_tail) + {//empty + //log_out("wave buf empty\n"); + return BUFFER_EMPTY; + } + int ret = m_wave_buf[m_head]; + m_head = (m_head + 1) % WAVE_BUFFER_LEN; + return ret; +} +int c_wave_buffer::read_wave_data_by_frame(short &max, short &min, short frame_len, unsigned int sequence, short offset) +{ + if (m_refresh_sequence != sequence) + { + m_refresh_sequence = sequence; + m_read_cache_sum = 0; + } + else if(offset < m_read_cache_sum)//(m_refresh_sequence == sequence && offset < m_fb_sum) + { + max = m_read_cache_max[offset]; + min = m_read_cache_min[offset]; + return m_read_cache_mid[offset]; + } + + m_read_cache_sum++; + ASSERT(m_read_cache_sum <= WAVE_READ_CACHE_LEN); + int i, data; + int tmp_min = m_last_data; + int tmp_max = m_last_data; + int mid = (m_min_old + m_max_old)>>1; + i = 0; + while(i++ < frame_len) + { + data = read_data(); + if(BUFFER_EMPTY == data) + { + break; + } + m_last_data = data; + if(data < tmp_min){tmp_min = data;} + if(data > tmp_max){tmp_max = data;} + } + min = m_read_cache_min[offset] = MIN(m_min_old, MIN(tmp_min, m_min_older)); + max = m_read_cache_max[offset] = MAX(m_max_old, MAX(tmp_max, m_max_older)); + m_min_older = m_min_old; + m_max_older = m_max_old; + m_min_old = tmp_min; + m_max_old = tmp_max; + return (m_read_cache_mid[offset] = mid); +} +void c_wave_buffer::clear_data() +{ + m_head = m_tail = 0; + memset(m_wave_buf, 0, sizeof(m_wave_buf)); +} +void c_wave_buffer::reset() +{ + m_head = m_tail; +} +#include +#include +#define CORRECT(x, high_limit, low_limit) {\ + x = (x > high_limit) ? high_limit : x;\ + x = (x < low_limit) ? low_limit : x;\ +}while(0) +#define WAVE_CURSOR_WIDTH 8 +#define WAVE_LINE_WIDTH 1 +#define WAVE_MARGIN 5 +c_wave_ctrl::c_wave_ctrl() +{ + m_wave = 0; + m_bg_fb = 0; + m_wave_name_font = m_wave_unit_font = 0; + m_wave_name = m_wave_unit = 0; + m_max_data = 500; + m_min_data = 0; + m_wave_speed = 1; + m_wave_data_rate = 0; + m_wave_refresh_rate = 1000; + m_frame_len_map_index = 0; + m_wave_name_color = m_wave_unit_color = m_wave_color = GL_RGB(255,0,0); + m_back_color = GL_RGB(0,0,0); +} +void c_wave_ctrl::on_init_children() +{ + c_rect rect; + get_screen_rect(rect); + m_wave_left = rect.m_left + WAVE_MARGIN; + m_wave_right = rect.m_right - WAVE_MARGIN; + m_wave_top = rect.m_top + WAVE_MARGIN; + m_wave_bottom = rect.m_bottom - WAVE_MARGIN; + m_wave_cursor = m_wave_left; + m_bg_fb = (unsigned int*)calloc(rect.Width() * rect.Height(), 4); +} +void c_wave_ctrl::set_max_min(short max_data, short min_data) +{ + m_max_data = max_data; + m_min_data = min_data; +} +void c_wave_ctrl::set_wave_in_out_rate(unsigned int data_rate, unsigned int refresh_rate) +{ + m_wave_data_rate = data_rate; + m_wave_refresh_rate = refresh_rate; + int read_times_per_second = m_wave_speed * 1000 / m_wave_refresh_rate; + memset(m_frame_len_map, 0, sizeof(m_frame_len_map)); + for (unsigned int i = 1; i < sizeof(m_frame_len_map) + 1; i++) + { + m_frame_len_map[i-1] = data_rate * i / read_times_per_second - data_rate * (i-1) / read_times_per_second; + } + m_frame_len_map_index = 0; +} +void c_wave_ctrl::set_wave_speed(unsigned int speed) +{ + m_wave_speed = speed; + set_wave_in_out_rate(m_wave_data_rate, m_wave_refresh_rate); +} +void c_wave_ctrl::clear_data() +{ + if(m_wave == 0) + { + ASSERT(false); + return; + } + m_wave->clear_data(); +} +bool c_wave_ctrl::is_data_enough() +{ + if(m_wave == 0) + { + ASSERT(false); + return false; + } + return (m_wave->get_cnt() - m_frame_len_map[m_frame_len_map_index] * m_wave_speed); +} +void c_wave_ctrl::refresh_wave(unsigned char frame) +{ + if(m_wave == 0) + { + ASSERT(false); + return; + } + short max, min, mid; + for(short offset = 0; offset < m_wave_speed; offset++) + { + //get wave value + mid = m_wave->read_wave_data_by_frame(max, min, + m_frame_len_map[m_frame_len_map_index++], + frame, offset); + m_frame_len_map_index %= sizeof(m_frame_len_map); + + //map to wave ctrl + int y_min,y_max; + if(m_max_data == m_min_data) + { + ASSERT(false); + } + y_max = m_wave_bottom + WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top)*(min - m_min_data)/(m_max_data - m_min_data); + y_min = m_wave_bottom - WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top)*(max - m_min_data)/(m_max_data - m_min_data); + mid = m_wave_bottom - (m_wave_bottom - m_wave_top)*(mid - m_min_data)/(m_max_data - m_min_data); + CORRECT(y_min, m_wave_bottom, m_wave_top); + CORRECT(y_max, m_wave_bottom, m_wave_top); + CORRECT(mid, m_wave_bottom, m_wave_top); + if (m_wave_cursor > m_wave_right) + { + m_wave_cursor = m_wave_left; + } + draw_smooth_vline(y_min, y_max, mid, m_wave_color); + restore_background(); + m_wave_cursor++; + } +} +void c_wave_ctrl::draw_smooth_vline(int y_min, int y_max, int mid, unsigned int rgb) +{ + int dy = y_max - y_min; + short r = GL_RGB_R(rgb); + short g = GL_RGB_G(rgb); + short b = GL_RGB_B(rgb); + int index = (dy >> 1) + 2; + int y; + m_surface->draw_pixel(m_wave_cursor, mid, rgb, m_z_order); + if (dy < 1) + { + return; + } + unsigned char cur_r,cur_g,cur_b; + unsigned int cur_rgb; + for (int i = 1; i <= (dy >> 1) + 1; ++i ) + { + if ( (mid + i) <= y_max ) + { + y = mid + i; + cur_r = r * (index - i) / index; + cur_g = g * (index - i) / index; + cur_b = b * (index - i) / index; + cur_rgb = GL_RGB(cur_r, cur_g, cur_b); + m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order); + } + if ( (mid - i) >= y_min ) + { + y = mid - i; + cur_r = r * (index - i) / index; + cur_g = g * (index - i) / index; + cur_b = b * (index - i) / index; + cur_rgb = GL_RGB(cur_r, cur_g, cur_b); + m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order); + } + } +} +void c_wave_ctrl::on_paint() +{ + c_rect rect; + get_screen_rect(rect); + + m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, m_back_color, m_z_order); + + //show name + c_word::draw_string(m_surface, m_z_order, m_wave_name, m_wave_left + 10, rect.m_top, m_wave_name_font, m_wave_name_color, GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + //show unit + c_word::draw_string(m_surface, m_z_order, m_wave_unit, m_wave_left + 60, rect.m_top, m_wave_unit_font, m_wave_unit_color, GL_ARGB(0, 0, 0, 0), ALIGN_LEFT); + save_background(); +} +void c_wave_ctrl::clear_wave(void) +{ + m_surface->fill_rect(m_wave_left, m_wave_top, m_wave_right, m_wave_bottom, m_back_color, m_z_order); + m_wave_cursor = m_wave_left; +} +void c_wave_ctrl::restore_background() +{ + int x = m_wave_cursor + WAVE_CURSOR_WIDTH; + if (x > m_wave_right) + { + x -= (m_wave_right - m_wave_left + 1); + } + c_rect rect; + get_screen_rect(rect); + register int width = rect.Width(); + register int top = rect.m_top; + register int left = rect.m_left; + for (int y_pos = (m_wave_top - 1); y_pos <= (m_wave_bottom + 1); y_pos++) + { + (m_bg_fb) ? m_surface->draw_pixel(x, y_pos, m_bg_fb[(y_pos - top) * width + (x - left)], m_z_order) : m_surface->draw_pixel(x, y_pos, 0, m_z_order); + } +} +void c_wave_ctrl::save_background() +{ + if (!m_bg_fb) + { + return; + } + c_rect rect; + get_screen_rect(rect); + + register unsigned int* p_des = m_bg_fb; + for (int y = rect.m_top; y <= rect.m_bottom; y++) + { + for (int x = rect.m_left; x <= rect.m_right; x++) + { + *p_des++ = m_surface->get_pixel(x, y, m_z_order); + } + } +} diff --git a/GuiLite.h b/GuiLite.h new file mode 100644 index 0000000..7bbf614 --- /dev/null +++ b/GuiLite.h @@ -0,0 +1,900 @@ +#ifndef GUILITE_CORE_INCLUDE_API_H +#define GUILITE_CORE_INCLUDE_API_H + +#define REAL_TIME_TASK_CYCLE_MS 50 + +#define GL_ARGB(a, r, g, b) ((((unsigned int)(a)) << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b))) +#define GL_ARGB_A(rgb) ((((unsigned int)(rgb)) >> 24) & 0xFF) + +#define GL_RGB(r, g, b) ((0xFF << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b))) +#define GL_RGB_R(rgb) ((((unsigned int)(rgb)) >> 16) & 0xFF) +#define GL_RGB_G(rgb) ((((unsigned int)(rgb)) >> 8) & 0xFF) +#define GL_RGB_B(rgb) (((unsigned int)(rgb)) & 0xFF) +#define GL_RGB_32_to_16(rgb) (((((unsigned int)(rgb)) & 0xFF) >> 3) | ((((unsigned int)(rgb)) & 0xFC00) >> 5) | ((((unsigned int)(rgb)) & 0xF80000) >> 8)) +#define GL_RGB_16_to_32(rgb) ((0xFF << 24) | ((((unsigned int)(rgb)) & 0x1F) << 3) | ((((unsigned int)(rgb)) & 0x7E0) << 5) | ((((unsigned int)(rgb)) & 0xF800) << 8)) + +#define ALIGN_HCENTER 0x00000000L +#define ALIGN_LEFT 0x01000000L +#define ALIGN_RIGHT 0x02000000L +#define ALIGN_HMASK 0x03000000L + +#define ALIGN_VCENTER 0x00000000L +#define ALIGN_TOP 0x00100000L +#define ALIGN_BOTTOM 0x00200000L +#define ALIGN_VMASK 0x00300000L + +typedef struct +{ + unsigned short year; + unsigned short month; + unsigned short date; + unsigned short day; + unsigned short hour; + unsigned short minute; + unsigned short second; +}T_TIME; + +void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log)); +void _assert(const char* file, int line); +#define ASSERT(condition) \ + do{ \ + if(!(condition))_assert(__FILE__, __LINE__);\ + }while(0) +void log_out(const char* log); + +long get_time_in_second(); +T_TIME second_to_day(long second); +T_TIME get_time(); + +void start_real_timer(void (*func)(void* arg)); +void register_timer(int milli_second, void func(void* ptmr, void* parg)); + +unsigned int get_cur_thread_id(); +void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg); +void thread_sleep(unsigned int milli_seconds); +int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data); + +#define FIFO_BUFFER_LEN 1024 +class c_fifo +{ +public: + c_fifo(); + int read(void* buf, int len); + int write(void* buf, int len); +private: + unsigned char m_buf[FIFO_BUFFER_LEN]; + int m_head; + int m_tail; + void* m_read_sem; + void* m_write_mutex; +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_CMD_TARGET_H +#define GUILITE_CORE_INCLUDE_CMD_TARGET_H +class c_cmd_target; +#define MSG_TYPE_INVALID 0xFFFF +#define MSG_TYPE_WND 0x0001 +#define MSG_TYPE_USR 0x0002 +#define USR_MSG_MAX 32 +typedef void (c_cmd_target::*MsgFuncVV)(); +enum MSG_CALLBACK_TYPE +{ + MSG_CALLBACK_NULL = 0, + MSG_CALLBACK_VV, + MSG_CALLBACK_IWL, + MSG_CALLBACK_IWV, + MSG_CALLBACK_VWV, + MSG_CALLBACK_VVL, + MSG_CALLBACK_VWL, + MSG_CALLBACK_IVV +}; +typedef union +{ + void (c_cmd_target::*func)(); + void (c_cmd_target::*func_vwv)(unsigned int w_param); + int (c_cmd_target::*func_iwl)(unsigned int w_param, long l_param); + int (c_cmd_target::*func_iwv)(unsigned int w_param); + void (c_cmd_target::*func_vvl)(long l_param); + void (c_cmd_target::*func_vwl)(unsigned int w_param, long l_param); + int (c_cmd_target::*func_ivv)(); +}MSGFUNCS; +struct GL_MSG_ENTRY +{ + unsigned int msgType; + unsigned int msgId; + c_cmd_target* pObject; + MSG_CALLBACK_TYPE callbackType; + MsgFuncVV func; +}; +#define ON_GL_USER_MSG(msgId, func) \ +{MSG_TYPE_USR, msgId, 0, MSG_CALLBACK_VWL, (MsgFuncVV)(static_cast(&func))}, +#define GL_DECLARE_MESSAGE_MAP() \ +protected: \ +virtual const GL_MSG_ENTRY* GetMSgEntries() const; \ +private: \ +static const GL_MSG_ENTRY mMsgEntries[]; +#define GL_BEGIN_MESSAGE_MAP(theClass) \ +const GL_MSG_ENTRY* theClass::GetMSgEntries() const \ +{ \ + return theClass::mMsgEntries; \ +} \ +const GL_MSG_ENTRY theClass::mMsgEntries[] = \ +{ +#define GL_END_MESSAGE_MAP() \ +{MSG_TYPE_INVALID, 0, (c_cmd_target*)0, MSG_CALLBACK_NULL, (MsgFuncVV)0}}; +class c_cmd_target +{ +public: + c_cmd_target(); + virtual ~c_cmd_target(); + static int handle_usr_msg(unsigned int msgId, unsigned int wParam, unsigned int lParam); +protected: + void load_cmd_msg(); + const GL_MSG_ENTRY* FindMsgEntry(const GL_MSG_ENTRY *pEntry, + unsigned int msgType, unsigned short msgId, unsigned short ctrlId); +private: + static GL_MSG_ENTRY ms_usr_map_entries[USR_MSG_MAX]; + static unsigned short ms_user_map_size; + GL_DECLARE_MESSAGE_MAP() +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_RECT_H +#define GUILITE_CORE_INCLUDE_RECT_H +class c_rect +{ +public: + c_rect(){Empty();} + c_rect(int left, int top, int right, int bottom){m_left = left;m_top = top;m_right = right;m_bottom = bottom;}; + void SetRect( int left, int top, int right, int bottom); + c_rect(const c_rect&); + c_rect& operator=(const c_rect&); + void Empty(); + void Offset(int x, int y); + int IsEmpty() const ; + int PtInRect(int x, int y) const ; + int operator==(const c_rect& ) const; + c_rect operator&(const c_rect& aRect) const; + int Width() const {return m_right - m_left + 1;} + int Height() const {return m_bottom - m_top + 1;} + int m_left; + int m_top; + int m_right; + int m_bottom; +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_RESOURCE_H +#define GUILITE_CORE_INCLUDE_RESOURCE_H +//BITMAP +typedef struct struct_bitmap_info +{ + unsigned short width; + unsigned short height; + unsigned short color_bits;//support 16 bits only + const unsigned short* pixel_color_array; +} BITMAP_INFO; +//FONT +typedef struct struct_lattice +{ + unsigned int utf8_code; + unsigned char width; + const unsigned char* pixel_gray_array; +} LATTICE; +typedef struct struct_font_info +{ + unsigned char height; + unsigned int count; + LATTICE* lattice_array; +} FONT_INFO; +#endif +#ifndef GUILITE_CORE_INCLUDE_THEME_H +#define GUILITE_CORE_INCLUDE_THEME_H +typedef struct struct_font_info FONT_INFO; +typedef struct struct_color_rect COLOR_RECT; +typedef struct struct_bitmap_info BITMAP_INFO; +//Rebuild gui library once you change this file +enum FONT_TYPE +{ + FONT_NULL, + FONT_DEFAULT, + FONT_CUSTOM1, + FONT_CUSTOM2, + FONT_CUSTOM3, + FONT_CUSTOM4, + FONT_CUSTOM5, + FONT_CUSTOM6, + FONT_MAX +}; +enum BITMAP_TYPE +{ + BITMAP_CUSTOM1, + BITMAP_CUSTOM2, + BITMAP_CUSTOM3, + BITMAP_CUSTOM4, + BITMAP_CUSTOM5, + BITMAP_CUSTOM6, + BITMAP_MAX +}; +enum COLOR_TYPE +{ + COLOR_WND_FONT, + COLOR_WND_NORMAL, + COLOR_WND_PUSHED, + COLOR_WND_FOCUS, + COLOR_WND_BORDER, + COLOR_CUSTOME1, + COLOR_CUSTOME2, + COLOR_CUSTOME3, + COLOR_CUSTOME4, + COLOR_CUSTOME5, + COLOR_CUSTOME6, + COLOR_MAX +}; +class c_theme +{ +public: + static int add_font(FONT_TYPE index, const FONT_INFO* font); + static const FONT_INFO* get_font(FONT_TYPE index); + static int add_bitmap(BITMAP_TYPE index, const BITMAP_INFO* bmp); + static const BITMAP_INFO* get_bmp(BITMAP_TYPE index); + static int add_color(COLOR_TYPE index, const unsigned int color); + static const unsigned int get_color(COLOR_TYPE index); +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_SURFACE_H +#define GUILITE_CORE_INCLUDE_SURFACE_H +class c_frame_layer +{ +public: + c_frame_layer() { fb = 0;} + unsigned short* fb; + c_rect visible_rect; +}; +typedef enum +{ + Z_ORDER_LEVEL_0,//view/wave/page + Z_ORDER_LEVEL_1,//dialog + Z_ORDER_LEVEL_2,//editbox/spinbox/listbox/keyboard + Z_ORDER_LEVEL_MAX +}Z_ORDER_LEVEL; +struct EXTERNAL_GFX_OP +{ + void(*draw_pixel)(int x, int y, unsigned int rgb); + void(*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb); +}; +class c_display; +class c_surface { + friend class c_display; friend class c_bitmap; +public: + int get_width() { return m_width; } + int get_height() { return m_height; } + unsigned int get_pixel(int x, int y, unsigned int z_order); + void draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order); + void fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order); + void draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order); + void draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order); + void draw_line(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order); + void draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size = 1); + inline void draw_rect(c_rect rect, unsigned int rgb, unsigned int size, unsigned int z_order) + { + draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order, size); + } + inline void fill_rect(c_rect rect, unsigned int rgb, unsigned int z_order) + { + fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order); + } + int flush_screen(int left, int top, int right, int bottom); + bool is_valid(c_rect rect); + bool is_active() { return m_is_active; } + c_display* get_display() { return m_display; } + int set_frame_layer_visible_rect(c_rect& rect, unsigned int z_order); + void set_active(bool flag){m_is_active = flag;} +protected: + virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb); + virtual void draw_pixel_on_fb(int x, int y, unsigned int rgb); + void set_surface(Z_ORDER_LEVEL max_z_order); + c_surface(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes); + int m_width; //in pixels + int m_height; //in pixels + int m_color_bytes; //16 bits, 32 bits only + void* m_fb; //Top frame buffer you could see + c_frame_layer m_frame_layers[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0 + bool m_is_active; + Z_ORDER_LEVEL m_max_zorder; + Z_ORDER_LEVEL m_top_zorder; + void* m_phy_fb; + int* m_phy_write_index; + c_display* m_display; +}; +class c_surface_no_fb : public c_surface {//No physical framebuffer, memory fb is 32 bits + friend class c_display; + c_surface_no_fb(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) : + c_surface(display, width, height, color_bytes) {m_gfx_op = gfx_op;} +protected: + virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb); + virtual void draw_pixel_on_fb(int x, int y, unsigned int rgb); + struct EXTERNAL_GFX_OP* m_gfx_op;//Rendering by external method +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_DISPLAY_H +#define GUILITE_CORE_INCLUDE_DISPLAY_H +#define SURFACE_CNT_MAX 6//root + pages +class c_hid_pipe; +class c_surface; +class c_display { + friend class c_surface; +public: + c_display(void* phy_fb, unsigned int display_width, unsigned int display_height, + unsigned int surface_width, unsigned int surface_height, + unsigned int color_bytes, unsigned int surface_cnt, EXTERNAL_GFX_OP* gfx_op = 0); + c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder); + int swipe_surface(c_surface* s1, c_surface* s2, int x0, int x1, int y0, int y2, int offset); + unsigned int get_width() { return m_width; } + unsigned int get_height() { return m_height; } + void* get_updated_fb(int* width, int* height, bool force_update = false); + int snap_shot(const char* file_name); +private: + unsigned int m_width; //in pixels + unsigned int m_height; //in pixels + unsigned int m_color_bytes; //16 bits, 32 bits only + void* m_phy_fb; + int m_phy_read_index; + int m_phy_write_index; + c_surface* m_surface_group[SURFACE_CNT_MAX]; + unsigned int m_surface_cnt; + unsigned int m_surface_index; +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_WORD_H +#define GUILITE_CORE_INCLUDE_WORD_H +class c_surface; +class c_word +{ +public: + static void draw_string(c_surface* surface, int z_order, const char *s, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT); + static void draw_string_in_rect(c_surface* surface, int z_order, const char *s, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT); + static void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT); + static void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT); + static void value_2_string(int value, int dot_position, char* buf, int len); + static int get_str_size(const char *s, const FONT_INFO* font, int& width, int& height); +private: + static int draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color); + static void draw_lattice(c_surface* surface, int z_order, int x, int y, int width, int height, const unsigned char* p_data, unsigned int font_color, unsigned int bg_color); + + static const LATTICE* get_lattice(const FONT_INFO* font, unsigned int utf8_code); + static void get_string_pos(const char *s, const FONT_INFO* font, c_rect rect, unsigned int align_type, int &x, int &y); +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_BITMAP_H +#define GUILITE_CORE_INCLUDE_BITMAP_H +#define DEFAULT_MASK_COLOR 0xFF080408 +class c_surface; +class c_bitmap +{ +public: + static void draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO *pBitmap, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR); + static void draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO* pBitmap, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR); +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_WND_H +#define GUILITE_CORE_INCLUDE_WND_H +typedef struct struct_font_info FONT_INFO; +typedef struct struct_color_rect COLOR_RECT; +class c_wnd; +class c_surface; +typedef enum +{ + ATTR_VISIBLE = 0x80000000L, + ATTR_DISABLED = 0x40000000L, + ATTR_FOCUS = 0x20000000L, + ATTR_MODAL = 0x10000000L// Handle touch action at high priority +}WND_ATTRIBUTION; +typedef enum +{ + STATUS_NORMAL, + STATUS_PUSHED, + STATUS_FOCUSED, + STATUS_DISABLED +}WND_STATUS; +typedef enum +{ + KEY_FORWARD, + KEY_BACKWARD, + KEY_ENTER +}KEY_TYPE; +typedef enum +{ + TOUCH_DOWN, + TOUCH_UP +}TOUCH_ACTION; +typedef struct struct_wnd_tree +{ + c_wnd* p_wnd; + unsigned int resource_id; + const char* str; + short x; + short y; + short width; + short height; + struct struct_wnd_tree* p_child_tree; +}WND_TREE; +class c_wnd : public c_cmd_target +{ + friend class c_dialog; +public: + c_wnd(); + virtual ~c_wnd() {}; + virtual int connect(c_wnd *parent, unsigned short resource_id, const char* str, + short x, short y, short width, short height, WND_TREE* p_child_tree = 0); + virtual c_wnd* connect_clone(c_wnd *parent, unsigned short resource_id, const char* str, + short x, short y, short width, short height, WND_TREE* p_child_tree = 0); + void disconnect(); + virtual c_wnd* clone() = 0; + virtual void on_init_children() {} + virtual void on_paint() {} + virtual void show_window(); + unsigned short get_id() const { return m_resource_id; } + int get_z_order() { return m_z_order; } + c_wnd* get_wnd_ptr(unsigned short id) const; + unsigned int get_attr() const { return m_attr; } + void set_attr(WND_ATTRIBUTION attr); + void set_str(const char* str) { m_str = str; } + int is_focus_wnd() const; + void set_font_color(unsigned int color) { m_font_color = color; } + unsigned int get_font_color() { return m_font_color; } + void set_bg_color(unsigned int color) { m_bg_color = color; } + unsigned int get_bg_color() { return m_bg_color; } + void set_font_type(const FONT_INFO *font_type) { m_font_type = font_type; } + const FONT_INFO* get_font_type() { return m_font_type; } + void set_wnd_pos(short x, short y, short width, short height); + void get_wnd_rect(c_rect &rect) const; + void get_screen_rect(c_rect &rect) const; + c_wnd* set_child_focus(c_wnd *focus_child); + c_wnd* get_parent() const { return m_parent; } + c_wnd* get_last_child() const; + int unlink_child(c_wnd *child); + c_wnd* get_prev_sibling() const { return m_prev_sibling; } + c_wnd* get_next_sibling() const { return m_next_sibling; } + void notify_parent(unsigned int msg_id, int param); + virtual bool on_touch(int x, int y, TOUCH_ACTION action);// return true: handled; false: not be handled. + virtual bool on_key(KEY_TYPE key);// return false: skip handling by parent; + c_surface* get_surface() { return m_surface; } + void set_surface(c_surface* surface) { m_surface = surface; } +protected: + virtual void pre_create_wnd() {}; + void add_child_2_tail(c_wnd *child); + void wnd2screen(int &x, int &y) const; + void wnd2screen(c_rect &rect) const; + int load_child_wnd(WND_TREE *p_child_tree); + int load_clone_child_wnd(WND_TREE *p_child_tree); + void set_active_child(c_wnd* child) { m_focus_child = child; } + virtual void on_focus() {}; + virtual void on_kill_focus() {}; +protected: + WND_STATUS m_status; + WND_ATTRIBUTION m_attr; + c_rect m_wnd_rect;// position relative to parent wnd. + c_wnd* m_parent; + c_wnd* m_top_child; + c_wnd* m_prev_sibling; + c_wnd* m_next_sibling; + const char* m_str; + const FONT_INFO* m_font_type; + unsigned int m_font_color; + unsigned int m_bg_color; + unsigned short m_resource_id; + int m_z_order; + c_wnd* m_focus_child;//current focused wnd + c_surface* m_surface; +private: + c_wnd(const c_wnd &win); + c_wnd& operator=(const c_wnd &win); +}; +#endif +#ifndef GUILITE_CORE_INCLUDE_AUDIO_H +#define GUILITE_CORE_INCLUDE_AUDIO_H +enum AUDIO_TYPE +{ + AUDIO_HEART_BEAT, + AUDIO_ALARM, + AUDIO_MAX +}; +class c_audio +{ +public: + static int play(AUDIO_TYPE type); +private: + static void init(); +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_BUTTON_H +#define GUILITE_WIDGETS_INCLUDE_BUTTON_H +#define GL_BN_CLICKED 0x1111 +#define ON_GL_BN_CLICKED(ctrlId, func) \ +{MSG_TYPE_WND, GL_BN_CLICKED, (c_cmd_target*)ctrlId, MSG_CALLBACK_VWV, (MsgFuncVV)(static_cast(&func))}, +typedef struct struct_bitmap_info BITMAP_INFO; +class c_button : public c_wnd +{ +public: + virtual c_wnd* clone(){return new c_button();} +protected: + virtual void on_paint(); + virtual void on_focus(); + virtual void on_kill_focus(); + virtual void pre_create_wnd(); + virtual bool on_touch(int x, int y, TOUCH_ACTION action); + virtual bool on_key(KEY_TYPE key); +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_DIALOG_H +#define GUILITE_WIDGETS_INCLUDE_DIALOG_H +class c_surface; +class c_dialog; +typedef struct +{ + c_dialog* dialog; + c_surface* surface; +} DIALOG_ARRAY; +class c_dialog : public c_wnd +{ +public: + static int open_dialog(c_dialog* p_dlg, bool modal_mode = true); + static int close_dialog(c_surface* surface); + static c_dialog* get_the_dialog(c_surface* surface); +protected: + virtual const char* get_class_name(void) const {return "c_dialog";} + virtual void pre_create_wnd(); + virtual void on_paint(); + static DIALOG_ARRAY ms_the_dialogs[SURFACE_CNT_MAX]; +private: + int set_me_the_dialog(); +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_KEYBOARD_H +#define GUILITE_WIDGETS_INCLUDE_KEYBOARD_H +#define KEYBORAD_CLICK 0x5014 +#define ON_KEYBORAD_UPDATE(ctrlId, func) \ +{MSG_TYPE_WND, KEYBORAD_CLICK, (c_cmd_target*)ctrlId, MSG_CALLBACK_VWL, (MsgFuncVV)(static_cast(&func))}, +typedef enum +{ + STATUS_UPPERCASE, + STATUS_LOWERCASE +}KEYBOARD_STATUS; +typedef enum +{ + STYLE_ALL_BOARD, + STYLE_NUM_BOARD +}KEYBOARD_STYLE; +typedef enum +{ + CLICK_CHAR, + CLICK_ENTER, + CLICK_ESC +}CLICK_STATUS; +class c_keyboard: public c_wnd +{ +public: + virtual int connect(c_wnd *user, unsigned short resource_id, KEYBOARD_STYLE style); + KEYBOARD_STATUS get_cap_status(){return m_cap_status;} + char* get_str() { return m_str; } +protected: + virtual void pre_create_wnd(); + virtual c_wnd* clone(){return new c_keyboard();} + virtual void on_paint(); + void on_char_clicked(unsigned int ctrl_id); + void on_del_clicked(unsigned int ctrl_id); + void on_caps_clicked(unsigned int ctrl_id); + void on_enter_clicked(unsigned int ctrl_id); + void on_esc_clicked(unsigned int ctrl_id); + GL_DECLARE_MESSAGE_MAP() +private: + char m_str[32]; + int m_str_len; + KEYBOARD_STATUS m_cap_status; +}; +class c_keyboard_button : public c_button +{ +protected: + virtual c_wnd* clone(){return new c_keyboard_button();} + virtual void on_paint(); +}; +#endif /* KEYBOARD_H_ */ +#ifndef GUILITE_WIDGETS_INCLUDE_EDIT_H +#define GUILITE_WIDGETS_INCLUDE_EDIT_H +#define MAX_EDIT_STRLEN 32 +class c_edit : public c_wnd +{ + friend class c_keyboard; +public: + virtual c_wnd* clone(){return new c_edit();} + const char* get_text(){return m_str;} + void set_text(const char* str); + void set_keyboard_style(KEYBOARD_STYLE kb_sytle) { m_kb_style = kb_sytle; } + +protected: + virtual void pre_create_wnd(); + virtual void on_paint(); + virtual void on_focus(); + virtual void on_kill_focus(); + virtual bool on_touch(int x, int y, TOUCH_ACTION action); + + void on_key_board_click(unsigned int ctrl_id, long param); + GL_DECLARE_MESSAGE_MAP() +private: + void show_keyboard(); + void on_touch_down(int x, int y); + void on_touch_up(int x, int y); + KEYBOARD_STYLE m_kb_style; + char m_str_input[MAX_EDIT_STRLEN]; + char m_str[MAX_EDIT_STRLEN]; +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_GESTURE_H +#define GUILITE_WIDGETS_INCLUDE_GESTURE_H +typedef enum{ + TOUCH_MOVE, + TOUCH_IDLE +}TOUCH_STATE; +class c_slide_group; +class c_gesture{ +public: + c_gesture(c_slide_group* group); + bool handle_swipe(int x, int y, TOUCH_ACTION action); +private: + bool on_move(int x); + bool on_swipe(int x); + int swipe_left(); + int swipe_right(); + void move_left(); + void move_right(); + int m_down_x; + int m_down_y; + int m_move_x; + int m_move_y; + TOUCH_STATE m_state; + c_slide_group* m_slide_group; +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_LABEL_H +#define GUILITE_WIDGETS_INCLUDE_LABEL_H +class c_label : public c_wnd +{ +public: + virtual c_wnd* clone(){return new c_label();} + virtual void on_paint(); +protected: + virtual void pre_create_wnd(); +private: +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_LIST_BOX_H +#define GUILITE_WIDGETS_INCLUDE_LIST_BOX_H +#define MAX_ITEM_NUM 4 +#define GL_LIST_CONFIRM 0x1 +#define ON_LIST_CONFIRM(ctrlId, func) \ +{MSG_TYPE_WND, GL_LIST_CONFIRM, (c_cmd_target*)ctrlId, MSG_CALLBACK_VWL, (MsgFuncVV)(static_cast(&func))}, +class c_list_box : public c_wnd +{ +public: + int add_item(char* str); + void clear_item(); + short get_item_count() { return m_item_total; } + void select_item(short index); + +protected: + virtual c_wnd* clone(){return new c_list_box();} + virtual void pre_create_wnd(); + virtual void on_paint(); + virtual void on_focus(); + virtual void on_kill_focus(); + virtual bool on_touch(int x, int y, TOUCH_ACTION action); + +private: + void update_list_size(); + void show_list(); + void on_touch_down(int x, int y); + void on_touch_up(int x, int y); + short m_selected_item; + short m_item_total; + char* m_item_array[MAX_ITEM_NUM]; + c_rect m_list_wnd_rect; //rect relative to parent wnd. + c_rect m_list_screen_rect; //rect relative to physical screen(frame buffer) +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_SLIDE_GROUP_H +#define GUILITE_WIDGETS_INCLUDE_SLIDE_GROUP_H +#define MAX_PAGES 5 +class c_gesture; +class c_slide_group : public c_wnd { +public: + c_slide_group(); + int set_active_slide(int index, bool is_redraw = true); + c_wnd* get_slide(int index){return m_slides[index];} + c_wnd* get_active_slide(){return m_slides[m_active_slide_index];} + int get_active_slide_index(){return m_active_slide_index;} + int add_slide(c_wnd* slide, unsigned short resource_id, short x, short y, + short width, short height, WND_TREE* p_child_tree = 0, + Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0); + int add_clone_silde(c_wnd* slide, unsigned short resource_id, short x, short y, + short width, short height, WND_TREE* p_child_tree = 0, + Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0); + void disabel_all_slide(); + virtual bool on_touch(int x, int y, TOUCH_ACTION action); + virtual bool on_key(KEY_TYPE key); +protected: + virtual c_wnd* clone(){return new c_slide_group();} + c_wnd* m_slides[MAX_PAGES]; + int m_active_slide_index; + c_gesture* m_gesture; +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_SPINBOX_H +#define GUILITE_WIDGETS_INCLUDE_SPINBOX_H +#define GL_SPIN_CONFIRM 0x2222 +#define GL_SPIN_CHANGE 0x3333 +#define ON_SPIN_CONFIRM(ctrlId, func) \ +{MSG_TYPE_WND, GL_SPIN_CONFIRM, (c_cmd_target*)ctrlId, MSG_CALLBACK_VWL, (MsgFuncVV)(static_cast(&func))}, +#define ON_SPIN_CHANGE(ctrlId, func) \ +{MSG_TYPE_WND, GL_SPIN_CHANGE, (c_cmd_target*)ctrlId, MSG_CALLBACK_VWL, (MsgFuncVV)(static_cast(&func))}, +class c_spin_box : public c_wnd +{ +public: + short get_value(){return m_value;} + void set_value(unsigned short value){m_value = m_cur_value = value;} + void set_max_min(short max, short min){m_max = max; m_min = min;} + void set_step(short step){m_step = step;} + short get_min(){return m_min;} + short get_max(){return m_max;} + short get_step(){return m_step;} + void set_value_digit(short digit){m_digit = digit;} + short get_value_digit(){return m_digit;} + +protected: + virtual c_wnd* clone(){return new c_spin_box();} + virtual void on_paint(); + virtual void on_focus(); + virtual void on_kill_focus(); + virtual void pre_create_wnd(); + virtual bool on_touch(int x, int y, TOUCH_ACTION action); + void on_arrow_up_bt_click(unsigned int ctr_id); + void on_arrow_down_bt_click(unsigned int ctr_id); + GL_DECLARE_MESSAGE_MAP() +private: + void show_arrow_button(); + void hide_arrow_button(); + void on_touch_down(int x, int y); + void on_touch_up(int x, int y); +protected: + short m_cur_value; + short m_value; + short m_step; + short m_max; + short m_min; + short m_digit; + c_button m_bt_up; + c_button m_bt_down; + c_rect m_bt_up_rect; + c_rect m_bt_down_rect; +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_TABLE_H +#define GUILITE_WIDGETS_INCLUDE_TABLE_H +#define MAX_COL_NUM 30 +#define MAX_ROW_NUM 30 +class c_table: public c_wnd +{ +public: + virtual c_wnd* clone(){return new c_table();} + void set_sheet_align(unsigned int align_type){ m_align_type = align_type;} + void set_row_num(unsigned int row_num){ m_row_num = row_num;} + void set_col_num(unsigned int col_num){ m_col_num = col_num;} + void set_row_height(unsigned int height); + void set_col_width(unsigned int width); + int set_row_height(unsigned int index, unsigned int height); + int set_col_width(unsigned int index, unsigned int width); + void set_item(int row, int col, char* str, unsigned int color); + unsigned int get_row_num(){ return m_row_num;} + unsigned int get_col_num(){ return m_col_num;} + c_rect get_item_rect(int row, int col); +protected: + void draw_item(int col, int row, const char* str, unsigned int color); + unsigned int m_align_type; + unsigned int m_row_num; + unsigned int m_col_num; + unsigned int m_row_height[MAX_ROW_NUM]; + unsigned int m_col_width[MAX_COL_NUM]; +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_WAVE_BUFFER_H +#define GUILITE_WIDGETS_INCLUDE_WAVE_BUFFER_H +#define WAVE_BUFFER_LEN 1024 +#define WAVE_READ_CACHE_LEN 8 +#define BUFFER_EMPTY -1111 +#define BUFFER_FULL -2222; +class c_wave_buffer +{ +public: + c_wave_buffer(); + int write_wave_data(short data); + int read_wave_data_by_frame(short &max, short &min, short frame_len, unsigned int sequence, short offset); + void reset(); + void clear_data(); + short get_cnt(); +private: + int read_data(); + short m_wave_buf[WAVE_BUFFER_LEN]; + short m_head; + short m_tail; + int m_min_old; + int m_max_old; + int m_min_older; + int m_max_older; + int m_last_data; + short m_read_cache_min[WAVE_READ_CACHE_LEN]; + short m_read_cache_mid[WAVE_READ_CACHE_LEN]; + short m_read_cache_max[WAVE_READ_CACHE_LEN]; + short m_read_cache_sum; + unsigned int m_refresh_sequence; +}; +#endif +#ifndef GUILITE_WIDGETS_INCLUDE_WAVE_CTRL_H +#define GUILITE_WIDGETS_INCLUDE_WAVE_CTRL_H +typedef enum +{ + FILL_MODE, + SCAN_MODE +}E_WAVE_DRAW_MODE; +class c_wave_buffer; +class c_wave_ctrl : public c_wnd +{ +public: + c_wave_ctrl(); + virtual c_wnd* clone(){return new c_wave_ctrl();} + virtual void on_init_children(); + virtual void on_paint(); + void set_wave_name(char* wave_name){ m_wave_name = wave_name;} + void set_wave_unit(char* wave_unit){ m_wave_unit = wave_unit;} + void set_wave_name_font(const FONT_INFO* wave_name_font_type){ m_wave_name_font = wave_name_font_type;} + void set_wave_unit_font(const FONT_INFO* wave_unit_font_type){ m_wave_unit_font = wave_unit_font_type;} + void set_wave_name_color(unsigned int wave_name_color){ m_wave_name_color = wave_name_color;} + void set_wave_unit_color(unsigned int wave_unit_color){ m_wave_unit_color = wave_unit_color;} + void set_wave_color(unsigned int color){ m_wave_color = color;} + void set_wave_in_out_rate(unsigned int data_rate, unsigned int refresh_rate); + void set_wave_speed(unsigned int speed); + void set_max_min(short max_data, short min_data); + void set_wave(c_wave_buffer* wave){m_wave = wave;} + c_wave_buffer* get_wave(){return m_wave;} + void clear_data(); + bool is_data_enough(); + void refresh_wave(unsigned char frame); + void clear_wave(); + +protected: + void draw_smooth_vline(int y_min, int y_max, int mid, unsigned int rgb); + void restore_background(); + void save_background(); + char* m_wave_name; + char* m_wave_unit; + const FONT_INFO* m_wave_name_font; + const FONT_INFO* m_wave_unit_font; + unsigned int m_wave_name_color; + unsigned int m_wave_unit_color; + unsigned int m_wave_color; + unsigned int m_back_color; + int m_wave_left; + int m_wave_right; + int m_wave_top; + int m_wave_bottom; + short m_max_data; + short m_min_data; + +private: + c_wave_buffer* m_wave; + unsigned int* m_bg_fb; //background frame buffer, could be used to draw scale line. + int m_wave_cursor; + int m_wave_speed; //pixels per refresh + unsigned int m_wave_data_rate; //data sample rate + unsigned int m_wave_refresh_rate;//refresh cycle in millisecond + unsigned char m_frame_len_map[64]; + unsigned char m_frame_len_map_index; +}; +#endif diff --git a/README.md b/README.md index 928ce60..46e63e7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- Image + Image

# GuiLite - The smallest GUI library @@ -14,7 +14,7 @@ *** ## Introduction GuiLite is the smallest GUI library with 5000 lines of code, could run on **all platforms**(e.g, iOS/macOS/WathOS, Android, Linux, Windows, Docker and MCU without OS), and work with **many languages**(e.g. Swift, Java, Javascript, C#, Golang). -- ✂️Small: 5,000 lines of C++ code, could be merged into 1 header & 1 source file(GuiLite.h/GuiLite.cpp) - Easy to [build & port](doc/HowToBuild.md) +- ✂️Small: 5,000 lines of C++ code, could be merged into 1 header & 1 source file(GuiLite.h/GuiLite.cpp) - Easy to [build & port](documents/HowToBuild.md) - ⚡Fast: Render GUI within one invoking, independent of any OS and any third party library - Make GUI run quickly and smoothly - 💉Inject: Run inside Qt/MFC/Winform/Cocoa/Web - Keep Qt/MFC code reusable, and speed it up by local GuiLite-optimization - ⚙️️Hardware Minimum Requirment: @@ -27,36 +27,36 @@ GuiLite is the smallest GUI library with 5000 lines of code, could run on **all Run GuiLite both on MCU and Apple Watch: | MCU | Apple Watch | | --- | --- | -| ![Hello3D](doc/Hello3D.gif) | ![iWatch.hello3D](doc/iWatch.hello3D.gif) | -| ![MCU](doc/HelloWave.gif) | ![iWatch.helloWave](doc/iWatch.helloWave.gif) | +| ![Hello3D](documents/Hello3D.gif) | ![iWatch.hello3D](documents/iWatch.hello3D.gif) | +| ![MCU](documents/HelloWave.gif) | ![iWatch.helloWave](documents/iWatch.helloWave.gif) | ## ✨Features ### ⚔️Cross platform | ARM Linux | STM32 Without OS | | --- | --- | -| ![ARM Linux](doc/Linux.gif) | ![MCU](doc/HelloParticle.gif) ![MCU](doc/HelloWave.gif) | +| ![ARM Linux](documents/Linux.gif) | ![MCU](documents/HelloParticle.gif) ![MCU](documents/HelloWave.gif) | | Windows Mixed Reality | Android | | --- | --- | -| ![Win MR](doc/WinMR.gif) | ![Android](doc/Android.gif) | +| ![Win MR](documents/WinMR.gif) | ![Android](documents/Android.gif) | | macOS | iOS & Aplle Watch | | --- | --- | -| ![macOS](doc/Mac.gif) | ![iOS.hostMonitor](doc/iOS.gif) ![iOS.particle](doc/iOS.particle.gif) ![iWatch.helloWave](doc/iWatch.helloWave.gif) | +| ![macOS](documents/Mac.gif) | ![iOS.hostMonitor](documents/iOS.gif) ![iOS.particle](documents/iOS.particle.gif) ![iWatch.helloWave](documents/iWatch.helloWave.gif) | *** ### 🔍GuiLite previewer(WYSIWYG extension for GuiLite) [GuiLite Previewer](https://github.com/idea4good/GuiLitePreviewer) is a Visual Studio Code extension, could extract GUI information from C++ code and preview GUI at preview page(What you see is what you get) -![GuiLitePreviewer](doc/Previewer.gif) +![GuiLitePreviewer](documents/Previewer.gif) *** ### 😎Gorgeous UI -![HostMonitor](doc/HostMonitor.gif)![HelloNets-pc](doc/HelloNets-pc.gif) +![HostMonitor](documents/HostMonitor.gif)![HelloNets-pc](documents/HelloNets-pc.gif) *** ### 🔣Multi-language: -![unicode](doc/unicode.jpg) +![unicode](documents/unicode.jpg) *** ### 🌐IoT Solution & 📊Code Telemetry -- Report build activities to cloud:
![BuildInfo](doc/BuildInfo.png) -- Sync running data to cloud:
![DataOnCloud](doc/data_on_cloud.png) +- Report build activities to cloud:
![BuildInfo](documents/BuildInfo.png) +- Sync running data to cloud:
![DataOnCloud](documents/data_on_cloud.png) - ⚠️To stop telemetry, remove script files(e,g: sync_build.bat .sync.sh .sync_build.sh) *** ### 🐋Support Docker @@ -64,7 +64,7 @@ We build GuiLite demo as docker image, you can update/deploy/run the latest GuiL - `sudo docker run -it --privileged -v /dev:/dev-share idea4good/gui-lite:latest bash /run.sh` *** ## 📦3D -- ![GuiLiteGraphic](doc/GuiLite3D.gif) ![Hello3D](doc/Hello3D.gif) +- ![GuiLiteGraphic](documents/GuiLite3D.gif) ![Hello3D](documents/Hello3D.gif) - Run GuiLite Samples[(HelloParticle, HelloWave)](https://gitee.com/idea4good/GuiLiteSamples) on Web and 3D scenario, [source code here](https://github.com/idea4good/GuiLiteWeb/blob/master/CubeEx/main.js) - Run GuiLite-Sample-Hello3D on MCU and Windows/Linux/Qt platform *** @@ -95,15 +95,15 @@ GuiLite is the smallest and simplest GUI library. 2. Only use basic C++ feature(class, virtual function), no complex syntax 3. All rendering base on draw_pixel, no algorithm 4. Full documents and small live demos for reference - - [Design specification](doc/HowToWork.md) - - [How to build & port?](doc/HowToBuild.md) - - [How to Layout widgets?](doc/HowLayoutWork.md) + - [Design specification](documents/HowToWork.md) + - [How to build & port?](documents/HowToBuild.md) + - [How to Layout widgets?](documents/HowLayoutWork.md) - [How to build unicode font/bitmap resource?](https://github.com/idea4good/GuiLiteToolkit) - [How to switch theme?](https://github.com/idea4good/GuiLiteSamples/blob/master/HostMonitor/UIcode/source/resource/resource.cpp) - - [How to dispatch messages?](doc/HowMessageWork.md) - - [UML chart of GuiLite core](doc/UML.md) + - [How to dispatch messages?](documents/HowMessageWork.md) + - [UML chart of GuiLite core](documents/UML.md) - How GuiLite multi-layers work? - - ![GuiLiteGraphic](doc/GuiLiteGraphic.gif) + - ![GuiLiteGraphic](documents/GuiLiteGraphic.gif) - [Full video](https://www.youtube.com/watch?v=QzZJnU5KmDQ) - [Tutorial Source code](https://github.com/idea4good/GuiLiteWeb/blob/master/Graphic/main.js) @@ -126,4 +126,4 @@ GuiLite is the smallest and simplest GUI library. ## 📞Community Channel Thanks for the help from community, you guys make GuiLite better! And welcome new friend to join us. - [**@Twitter**](https://twitter.com/idea4good) -- QQ code: [](https://jq.qq.com/?_wv=1027&k=5EO8D9i) +- QQ code: [](https://jq.qq.com/?_wv=1027&k=5EO8D9i) diff --git a/README_zh.md b/README_zh.md index cf1ccb5..9903b71 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,5 +1,5 @@

- Image + Image

# GuiLite(超轻量UI框架)- 最小的GUI库 @@ -13,7 +13,7 @@ *** ## GuiLite是什么鬼? GuiLite是5千行的图形界面库,可以运行在**所有平台**(例如:iOS/macOS/WathOS,Android,Linux(ARM/x86-64),Windows(包含VR),Docker和MCU)上;也可以与**多种语言**(例如: Swift, Java, Javascript, C#, Golang)协同工作。 -- ✂️轻量: 5千行C++代码,可合并在:1个头文件(GuiLite.h),1个实现文件(GuiLite.cpp)中 - 轻松[编译/移植](doc/HowToBuild.md) +- ✂️轻量: 5千行C++代码,可合并在:1个头文件(GuiLite.h),1个实现文件(GuiLite.cpp)中 - 轻松[编译/移植](documents/HowToBuild.md) - ⚡超快: 一次调用就可以完成图形渲染,与操作系统及第三方库无关 - 程序更快速,UI更流畅 - 💉可注入: 可注入在Qt/MFC/Winform/Cocoa/Web程序中运行 - 充分利用现有Qt/MFC代码,局部GuiLite优化,亦可显著提升效率 - ⚙️️最低硬件要求: @@ -26,43 +26,43 @@ GuiLite是5千行的图形界面库,可以运行在**所有平台**(例如 GuiLite程序,可以同时运行在单片机和苹果“手表”上: | MCU | Apple Watch | | --- | --- | -| ![Hello3D](doc/Hello3D.gif) | ![iWatch.hello3D](doc/iWatch.hello3D.gif) | -| ![MCU](doc/HelloWave.gif) | ![iWatch.helloWave](doc/iWatch.helloWave.gif) | +| ![Hello3D](documents/Hello3D.gif) | ![iWatch.hello3D](documents/iWatch.hello3D.gif) | +| ![MCU](documents/HelloWave.gif) | ![iWatch.helloWave](documents/iWatch.helloWave.gif) | ## ✨功能介绍 ### ⚔️卓越的跨平台能力 | ARM Linux | STM32 Without OS | | --- | --- | -| ![ARM Linux](doc/Linux.gif) | ![MCU](doc/HelloParticle.gif) ![MCU](doc/HelloWave.gif) | +| ![ARM Linux](documents/Linux.gif) | ![MCU](documents/HelloParticle.gif) ![MCU](documents/HelloWave.gif) | | Windows Mixed Reality | Android | | --- | --- | -| ![Win MR](doc/WinMR.gif) | ![Android](doc/Android.gif) | +| ![Win MR](documents/WinMR.gif) | ![Android](documents/Android.gif) | | macOS | iOS & Apple Watch | | --- | --- | -| ![macOS](doc/Mac.gif) | ![iOS.hostMonitor](doc/iOS.gif) ![iOS.particle](doc/iOS.particle.gif) ![iWatch.helloWave](doc/iWatch.helloWave.gif) | +| ![macOS](documents/Mac.gif) | ![iOS.hostMonitor](documents/iOS.gif) ![iOS.particle](documents/iOS.particle.gif) ![iWatch.helloWave](documents/iWatch.helloWave.gif) | *** ### 🔍GuiLite Previewer(所见即所得的GuiLite开发插件) [GuiLite Previewer](https://github.com/idea4good/GuiLitePreviewer)是一个Visual Studio Code插件,它可以自动提取源代码的GUI布局信息,并实时显示在“预览”页面上(所见即所得) -![GuiLitePreviewer](doc/Previewer.gif) +![GuiLitePreviewer](documents/Previewer.gif) *** ### 😎浮夸的UI效果 -![HostMonitor](doc/HostMonitor.gif)![HelloNets-pc](doc/HelloNets-pc.gif) +![HostMonitor](documents/HostMonitor.gif)![HelloNets-pc](documents/HelloNets-pc.gif) *** ### 🔣万国语(unicode): -![unicode](doc/unicode.jpg) +![unicode](documents/unicode.jpg) *** ### 🌐IoT(物联网)和📊数据分析 -- 上报“编译/运行”情况至“云端”:
![BuildInfo](doc/BuildInfo.png) -- 同步“运行数据”至“云端”:
![DataOnCloud](doc/data_on_cloud.png) +- 上报“编译/运行”情况至“云端”:
![BuildInfo](documents/BuildInfo.png) +- 同步“运行数据”至“云端”:
![DataOnCloud](documents/data_on_cloud.png) *** ### 🐋支持Docker 我们把GuiLite demo做成了Docker映像,只需一行命令,就可以将最新的GuiLite demo升级/部署/运行在你的设备上了。 - `sudo docker run -it --privileged -v /dev:/dev-share idea4good/gui-lite:latest bash /run.sh` *** ## 📦3D -- ![GuiLiteGraphic](doc/GuiLite3D.gif) ![Hello3D](doc/Hello3D.gif) +- ![GuiLiteGraphic](documents/GuiLite3D.gif) ![Hello3D](documents/Hello3D.gif) - GuiLite实例[(HelloParticle, HelloWave)](https://gitee.com/idea4good/GuiLiteSamples)运行在Web及3D环境,[代码在这里](https://github.com/idea4good/GuiLiteWeb/blob/master/CubeEx/main.js) - 在单片机上也能运行3D效果(具体参看GuiLiteSamples:Hello3D) *** @@ -93,15 +93,15 @@ GuiLite是最简单,易学的GUI库。 2. 只使用C++的基本特性(类和虚函数),不涉及复杂语法 3. 图形绘制以描点为基础,不使用任何算法 4. 设计简单,配有丰富的文档和实例程序;遇到问题,可以在QQ群获得帮助 - - [软件设计说明](doc/HowToWork-cn.md) - - [如何编译和移植?](doc/HowToBuild.md) - - [如何布局UI?](doc/HowLayoutWork.md) + - [软件设计说明](documents/HowToWork-cn.md) + - [如何编译和移植?](documents/HowToBuild.md) + - [如何布局UI?](documents/HowLayoutWork.md) - [如何制作多种文字/位图资源?](https://github.com/idea4good/GuiLiteToolkit) - [如何“换肤”?](https://gitee.com/idea4good/GuiLiteSamples/blob/master/HostMonitor/UIcode/source/resource/resource.cpp) - - [如何传递消息?](doc/HowMessageWork.md) - - [核心UML示意图](doc/UML.md) + - [如何传递消息?](documents/HowMessageWork.md) + - [核心UML示意图](documents/UML.md) - GuiLite滑动,及多层叠加原理 - - ![GuiLiteGraphic](doc/GuiLiteGraphic.gif) + - ![GuiLiteGraphic](documents/GuiLiteGraphic.gif) - [完整视频](https://v.youku.com/v_show/id_XNDI4ODE1ODcwOA) - [Source code](https://github.com/idea4good/GuiLiteWeb/blob/master/Graphic/main.js) @@ -122,4 +122,4 @@ GuiLite是最简单,易学的GUI库。 [GitHub链接](https://github.com/idea4good/GuiLite) ## 📞社区交流 -- 感谢开发者群的所有同学,是你们塑造了今天的GuiLite!也欢迎新的大神/小白加入我们。
[](https://jq.qq.com/?_wv=1027&k=5EO8D9i) +- 感谢开发者群的所有同学,是你们塑造了今天的GuiLite!也欢迎新的大神/小白加入我们。
[](https://jq.qq.com/?_wv=1027&k=5EO8D9i) diff --git a/doc/Android.gif b/documents/Android.gif similarity index 100% rename from doc/Android.gif rename to documents/Android.gif diff --git a/doc/BuildInfo.png b/documents/BuildInfo.png similarity index 100% rename from doc/BuildInfo.png rename to documents/BuildInfo.png diff --git a/doc/GraphicLayer.png b/documents/GraphicLayer.png similarity index 100% rename from doc/GraphicLayer.png rename to documents/GraphicLayer.png diff --git a/doc/GuiLite3D.gif b/documents/GuiLite3D.gif similarity index 100% rename from doc/GuiLite3D.gif rename to documents/GuiLite3D.gif diff --git a/doc/GuiLiteCube.gif b/documents/GuiLiteCube.gif similarity index 100% rename from doc/GuiLiteCube.gif rename to documents/GuiLiteCube.gif diff --git a/doc/GuiLiteGraphic.gif b/documents/GuiLiteGraphic.gif similarity index 100% rename from doc/GuiLiteGraphic.gif rename to documents/GuiLiteGraphic.gif diff --git a/doc/Hello3D.gif b/documents/Hello3D.gif similarity index 100% rename from doc/Hello3D.gif rename to documents/Hello3D.gif diff --git a/doc/HelloNets-pc.gif b/documents/HelloNets-pc.gif similarity index 100% rename from doc/HelloNets-pc.gif rename to documents/HelloNets-pc.gif diff --git a/doc/HelloParticle.gif b/documents/HelloParticle.gif similarity index 100% rename from doc/HelloParticle.gif rename to documents/HelloParticle.gif diff --git a/doc/HelloStar.gif b/documents/HelloStar.gif similarity index 100% rename from doc/HelloStar.gif rename to documents/HelloStar.gif diff --git a/doc/HelloWave.gif b/documents/HelloWave.gif similarity index 100% rename from doc/HelloWave.gif rename to documents/HelloWave.gif diff --git a/doc/HelloWidgets.gif b/documents/HelloWidgets.gif similarity index 100% rename from doc/HelloWidgets.gif rename to documents/HelloWidgets.gif diff --git a/doc/HostMonitor.gif b/documents/HostMonitor.gif similarity index 100% rename from doc/HostMonitor.gif rename to documents/HostMonitor.gif diff --git a/doc/HowLayoutWork.md b/documents/HowLayoutWork.md similarity index 100% rename from doc/HowLayoutWork.md rename to documents/HowLayoutWork.md diff --git a/doc/HowMessageWork.md b/documents/HowMessageWork.md similarity index 100% rename from doc/HowMessageWork.md rename to documents/HowMessageWork.md diff --git a/doc/HowToBuild.md b/documents/HowToBuild.md similarity index 100% rename from doc/HowToBuild.md rename to documents/HowToBuild.md diff --git a/doc/HowToWork-cn.md b/documents/HowToWork-cn.md similarity index 100% rename from doc/HowToWork-cn.md rename to documents/HowToWork-cn.md diff --git a/doc/HowToWork.md b/documents/HowToWork.md similarity index 100% rename from doc/HowToWork.md rename to documents/HowToWork.md diff --git a/doc/Linux.gif b/documents/Linux.gif similarity index 100% rename from doc/Linux.gif rename to documents/Linux.gif diff --git a/doc/Mac.gif b/documents/Mac.gif similarity index 100% rename from doc/Mac.gif rename to documents/Mac.gif diff --git a/doc/Previewer.gif b/documents/Previewer.gif similarity index 100% rename from doc/Previewer.gif rename to documents/Previewer.gif diff --git a/doc/UML.md b/documents/UML.md similarity index 100% rename from doc/UML.md rename to documents/UML.md diff --git a/doc/WinMR.gif b/documents/WinMR.gif similarity index 100% rename from doc/WinMR.gif rename to documents/WinMR.gif diff --git a/doc/click_button.png b/documents/click_button.png similarity index 100% rename from doc/click_button.png rename to documents/click_button.png diff --git a/doc/data_on_cloud.png b/documents/data_on_cloud.png similarity index 100% rename from doc/data_on_cloud.png rename to documents/data_on_cloud.png diff --git a/doc/draw_wav.png b/documents/draw_wav.png similarity index 100% rename from doc/draw_wav.png rename to documents/draw_wav.png diff --git a/doc/flip.png b/documents/flip.png similarity index 100% rename from doc/flip.png rename to documents/flip.png diff --git a/doc/iOS.gif b/documents/iOS.gif similarity index 100% rename from doc/iOS.gif rename to documents/iOS.gif diff --git a/doc/iOS.particle.gif b/documents/iOS.particle.gif similarity index 100% rename from doc/iOS.particle.gif rename to documents/iOS.particle.gif diff --git a/doc/iWatch.hello3D.gif b/documents/iWatch.hello3D.gif similarity index 100% rename from doc/iWatch.hello3D.gif rename to documents/iWatch.hello3D.gif diff --git a/doc/iWatch.helloWave.gif b/documents/iWatch.helloWave.gif similarity index 100% rename from doc/iWatch.helloWave.gif rename to documents/iWatch.helloWave.gif diff --git a/doc/layout_dialog.png b/documents/layout_dialog.png similarity index 100% rename from doc/layout_dialog.png rename to documents/layout_dialog.png diff --git a/doc/layout_single_slide.png b/documents/layout_single_slide.png similarity index 100% rename from doc/layout_single_slide.png rename to documents/layout_single_slide.png diff --git a/doc/layout_slide_group.png b/documents/layout_slide_group.png similarity index 100% rename from doc/layout_slide_group.png rename to documents/layout_slide_group.png diff --git a/doc/qq.group.jpg b/documents/qq.group.jpg similarity index 100% rename from doc/qq.group.jpg rename to documents/qq.group.jpg diff --git a/doc/uml-class.png b/documents/uml-class.png similarity index 100% rename from doc/uml-class.png rename to documents/uml-class.png diff --git a/doc/uml-ui-process.png b/documents/uml-ui-process.png similarity index 100% rename from doc/uml-ui-process.png rename to documents/uml-ui-process.png diff --git a/doc/unicode.jpg b/documents/unicode.jpg similarity index 100% rename from doc/unicode.jpg rename to documents/unicode.jpg diff --git a/doc/vs-configure.jpg b/documents/vs-configure.jpg similarity index 100% rename from doc/vs-configure.jpg rename to documents/vs-configure.jpg diff --git a/workspace/.DS_Store b/workspace/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..739627559bc036903e115ad9e4e16c1bf0d085c3 GIT binary patch literal 6148 zcmeHK+fD*85It2A3=rT=ANL0&;SV+lF(m2>AAsCcbOVN)__lwpXWC+1SJUuf(9Dp| z>9#YS>1omIn0}tAKBTapqWH60oc6 z?9gX~8NU*&F%J5baY?(W&1=Q{mAn9njWT9GsFa(z0uK@XjPb(QSAT6X&wTHX?J++ckWT*)F{nAaHh%!}(E zh*Zm3@42dnwsZb|KD@I