[
  {
    "path": ".github/FUNDING.yml",
    "content": "custom: https://idea4good.github.io/\n"
  },
  {
    "path": ".github/workflows/ccpp.yml",
    "content": "name: C/C++ CI\n\non: [push]\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n    \n    steps:\n    - uses: actions/checkout@v1\n    - name: cmake\n      run: cd src && cmake .\n    - name: make\n      run: cd src && make\n"
  },
  {
    "path": "GuiLite.h",
    "content": "#pragma once\n#define REAL_TIME_TASK_CYCLE_MS\t\t50\n#define MAX(a,b) (((a)>(b))?(a):(b))\n#define MIN(a,b) (((a)<(b))?(a):(b))\n#define GL_ARGB(a, r, g, b) ((((unsigned int)(a)) << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))\n#define GL_ARGB_A(rgb) ((((unsigned int)(rgb)) >> 24) & 0xFF)\n#define GL_RGB(r, g, b) ((0xFF << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))\n#define GL_RGB_R(rgb) ((((unsigned int)(rgb)) >> 16) & 0xFF)\n#define GL_RGB_G(rgb) ((((unsigned int)(rgb)) >> 8) & 0xFF)\n#define GL_RGB_B(rgb) (((unsigned int)(rgb)) & 0xFF)\n#define GL_RGB_32_to_16(rgb) (((((unsigned int)(rgb)) & 0xFF) >> 3) | ((((unsigned int)(rgb)) & 0xFC00) >> 5) | ((((unsigned int)(rgb)) & 0xF80000) >> 8))\n#define GL_RGB_16_to_32(rgb) ((0xFF << 24) | ((((unsigned int)(rgb)) & 0x1F) << 3) | ((((unsigned int)(rgb)) & 0x7E0) << 5) | ((((unsigned int)(rgb)) & 0xF800) << 8))\n#define ALIGN_HCENTER\t\t0x00000000L\n#define ALIGN_LEFT\t\t\t0x01000000L\n#define ALIGN_RIGHT\t\t\t0x02000000L\n#define ALIGN_HMASK\t\t\t0x03000000L\n#define ALIGN_VCENTER\t\t0x00000000L\n#define ALIGN_TOP\t\t\t0x00100000L\n#define ALIGN_BOTTOM\t\t0x00200000L\n#define ALIGN_VMASK\t\t\t0x00300000L\ntypedef struct\n{\n\tunsigned short year;\n\tunsigned short month;\n\tunsigned short date;\n\tunsigned short day;\n\tunsigned short hour;\n\tunsigned short minute;\n\tunsigned short second;\n}T_TIME;\nvoid register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log));\nvoid _assert(const char* file, int line);\n#define ASSERT(condition)\t\\\n\tdo{                     \\\n\tif(!(condition))_assert(__FILE__, __LINE__);\\\n\t}while(0)\nvoid log_out(const char* log);\nlong get_time_in_second();\nT_TIME second_to_day(long second);\nT_TIME get_time();\nvoid start_real_timer(void (*func)(void* arg));\nvoid register_timer(int milli_second, void func(void* param), void* param);\nunsigned int get_cur_thread_id();\nvoid create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg);\nvoid thread_sleep(unsigned int milli_seconds);\nint build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data);\n#define FIFO_BUFFER_LEN\t\t1024\nclass c_fifo\n{\npublic:\n\tc_fifo();\n\tint read(void* buf, int len);\n\tint write(void* buf, int len);\nprivate:\n\tunsigned char \tm_buf[FIFO_BUFFER_LEN];\n\tint\t\tm_head;\n\tint\t\tm_tail;\n\tvoid* m_read_sem;\n\tvoid* m_write_mutex;\n};\nclass c_rect\n{\npublic:\n\tc_rect(){ m_left = m_top = m_right = m_bottom = -1; }//empty rect\n\tc_rect(int left, int top, int width, int height)\n\t{\n\t\tset_rect(left, top, width, height);\n\t}\n\tvoid set_rect(int left, int top, int width, int height)\n\t{\n\t\tASSERT(width > 0 && height > 0);\n\t\tm_left = left;\n\t\tm_top = top;\n\t\tm_right = left + width - 1;\n\t\tm_bottom = top + height -1;\n\t}\n\tbool pt_in_rect(int x, int y) const\n\t{\n\t\treturn x >= m_left && x <= m_right && y >= m_top && y <= m_bottom;\n\t}\n\tint operator==(const c_rect& rect) const\n\t{\n\t\treturn (m_left == rect.m_left) && (m_top == rect.m_top) && (m_right == rect.m_right) && (m_bottom == rect.m_bottom);\n\t}\n\tint width() const { return m_right - m_left + 1; }\n\tint height() const { return m_bottom - m_top + 1 ; }\n\tint\t    m_left;\n\tint     m_top;\n\tint     m_right;\n\tint     m_bottom;\n};\n//BITMAP\ntypedef struct struct_bitmap_info\n{\n\tunsigned short width;\n\tunsigned short height;\n\tunsigned short color_bits;//support 16 bits only\n\tconst unsigned short* pixel_color_array;\n} BITMAP_INFO;\n//FONT\ntypedef struct struct_lattice\n{\n\tunsigned int\t\t\tutf8_code;\n\tunsigned char\t\t\twidth;\n\tconst unsigned char*\tpixel_buffer;\n} LATTICE;\ntypedef struct struct_lattice_font_info\n{\n\tunsigned char\theight;\n\tunsigned int\tcount;\n\tLATTICE*\t\tlattice_array;\n} LATTICE_FONT_INFO;\n//Rebuild gui library once you change this file\nenum FONT_LIST\n{\n\tFONT_NULL,\n\tFONT_DEFAULT,\n\tFONT_CUSTOM1,\n\tFONT_CUSTOM2,\n\tFONT_CUSTOM3,\n\tFONT_CUSTOM4,\n\tFONT_CUSTOM5,\n\tFONT_CUSTOM6,\n\tFONT_MAX\n};\nenum IMAGE_LIST\n{\n\tIMAGE_CUSTOM1,\n\tIMAGE_CUSTOM2,\n\tIMAGE_CUSTOM3,\n\tIMAGE_CUSTOM4,\n\tIMAGE_CUSTOM5,\n\tIMAGE_CUSTOM6,\n\tIMAGE_MAX\n};\nenum COLOR_LIST\n{\n\tCOLOR_WND_FONT,\n\tCOLOR_WND_NORMAL,\n\tCOLOR_WND_PUSHED,\n\tCOLOR_WND_FOCUS,\n\tCOLOR_WND_BORDER,\n\tCOLOR_CUSTOME1,\n\tCOLOR_CUSTOME2,\n\tCOLOR_CUSTOME3,\n\tCOLOR_CUSTOME4,\n\tCOLOR_CUSTOME5,\n\tCOLOR_CUSTOME6,\n\tCOLOR_MAX\n};\nclass c_theme\n{\npublic:\n\tstatic int add_font(FONT_LIST index, const void* font)\n\t{\n\t\tif (index >= FONT_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\ts_font_map[index] = font;\n\t\treturn 0;\n\t}\n\tstatic const void* get_font(FONT_LIST index)\n\t{\n\t\tif (index >= FONT_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\treturn s_font_map[index];\n\t}\n\tstatic int add_image(IMAGE_LIST index, const void* image_info)\n\t{\n\t\tif (index >= IMAGE_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\ts_image_map[index] = image_info;\n\t\treturn 0;\n\t}\n\tstatic const void* get_image(IMAGE_LIST index)\n\t{\n\t\tif (index >= IMAGE_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\treturn s_image_map[index];\n\t}\n\t\n\tstatic int add_color(COLOR_LIST index, const unsigned int color)\n\t{\n\t\tif (index >= COLOR_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\ts_color_map[index] = color;\n\t\treturn 0;\n\t}\n\tstatic const unsigned int get_color(COLOR_LIST index)\n\t{\n\t\tif (index >= COLOR_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\treturn s_color_map[index];\n\t}\nprivate:\n\tstatic const void* s_font_map[FONT_MAX];\n\tstatic const void* s_image_map[IMAGE_MAX];\n\tstatic unsigned int s_color_map[COLOR_MAX];\n};\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#define SURFACE_CNT_MAX\t6//root + pages\ntypedef enum\n{\n\tZ_ORDER_LEVEL_0,//lowest graphic level\n\tZ_ORDER_LEVEL_1,//middle graphic level, call activate_layer before use it, draw everything inside the active rect.\n\tZ_ORDER_LEVEL_2,//highest graphic level, call activate_layer before use it, draw everything inside the active rect.\n\tZ_ORDER_LEVEL_MAX\n}Z_ORDER_LEVEL;\nstruct DISPLAY_DRIVER\n{\n\tvoid(*draw_pixel)(int x, int y, unsigned int rgb);\n\tvoid(*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);\n};\nclass c_surface;\nclass c_display {\n\tfriend class c_surface;\npublic:\n\tinline c_display(void* phy_fb, int display_width, int display_height, c_surface* surface, DISPLAY_DRIVER* driver = 0);//single custom surface\n\tinline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, DISPLAY_DRIVER* driver = 0);//multiple surface\n\tinline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect layer_rect = c_rect());//for slide group\n\tinline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset);\n\tint get_width() { return m_width; }\n\tint get_height() { return m_height; }\n\tvoid* get_phy_fb() { return m_phy_fb; }\n\tvoid* get_updated_fb(int* width, int* height, bool force_update = false)\n\t{\n\t\tif (width && height)\n\t\t{\n\t\t\t*width = m_width;\n\t\t\t*height = m_height;\n\t\t}\n\t\tif (force_update)\n\t\t{\n\t\t\treturn m_phy_fb;\n\t\t}\n\t\tif (m_phy_read_index == m_phy_write_index)\n\t\t{//No update\n\t\t\treturn 0;\n\t\t}\n\t\tm_phy_read_index = m_phy_write_index;\n\t\treturn m_phy_fb;\n\t}\n\tint snap_shot(const char* file_name)\n\t{\n\t\tif (!m_phy_fb || (m_color_bytes !=2 && m_color_bytes != 4))\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\t//16 bits framebuffer\n\t\tif (m_color_bytes == 2)\n\t\t{\n\t\t\treturn build_bmp(file_name, m_width, m_height, (unsigned char*)m_phy_fb);\n\t\t}\n\t\t//32 bits framebuffer\n\t\tunsigned short* p_bmp565_data = new unsigned short[m_width * m_height];\n\t\tunsigned int* p_raw_data = (unsigned int*)m_phy_fb;\n\t\tfor (int i = 0; i < m_width * m_height; i++)\n\t\t{\n\t\t\tunsigned int rgb = *p_raw_data++;\n\t\t\tp_bmp565_data[i] = GL_RGB_32_to_16(rgb);\n\t\t}\n\t\tint ret = build_bmp(file_name, m_width, m_height, (unsigned char*)p_bmp565_data);\n\t\tdelete[]p_bmp565_data;\n\t\treturn ret;\n\t}\nprotected:\n\tvirtual void draw_pixel(int x, int y, unsigned int rgb)\n\t{\n\t\tif ((x >= m_width) || (y >= m_height)) { return; }\n\t\tif (m_driver && m_driver->draw_pixel)\n\t\t{\n\t\t\treturn m_driver->draw_pixel(x, y, rgb);\n\t\t}\n\t\tif (m_color_bytes == 2)\n\t\t{\n\t\t\t((unsigned short*)m_phy_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t((unsigned int*)m_phy_fb)[y * m_width + x] = rgb;\n\t\t}\n\t}\n\tvirtual void fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb)\n\t{\n\t\tif (m_driver && m_driver->fill_rect)\n\t\t{\n\t\t\treturn m_driver->fill_rect(x0, y0, x1, y1, rgb);\n\t\t}\n\t\tif (m_driver && m_driver->draw_pixel)\n\t\t{\n\t\t\tfor (int y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tfor (int x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\tm_driver->draw_pixel(x, y, rgb);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tint _width = m_width;\n\t\tint _height = m_height;\n\t\tint x, y;\n\t\tif (m_color_bytes == 2)\n\t\t{\n\t\t\tunsigned short* phy_fb;\n\t\t\tunsigned int rgb_16 = GL_RGB_32_to_16(rgb);\n\t\t\tfor (y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tphy_fb = &((unsigned short*)m_phy_fb)[y * _width + x0];\n\t\t\t\tfor (x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\tif ((x < _width) && (y < _height))\n\t\t\t\t\t{\n\t\t\t\t\t\t*phy_fb++ = rgb_16;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tunsigned int* phy_fb;\n\t\t\tfor (y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tphy_fb = &((unsigned int*)m_phy_fb)[y * _width + x0];\n\t\t\t\tfor (x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\tif ((x < _width) && (y < _height))\n\t\t\t\t\t{\n\t\t\t\t\t\t*phy_fb++ = rgb;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvirtual int flush_screen(int left, int top, int right, int bottom, void* fb, int fb_width)\n\t{\n\t\tif ((0 == m_phy_fb) || (0 == fb))\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tint _width = m_width;\n\t\tint _height = m_height;\n\t\tleft = (left >= _width) ? (_width - 1) : left;\n\t\tright = (right >= _width) ? (_width - 1) : right;\n\t\ttop = (top >= _height) ? (_height - 1) : top;\n\t\tbottom = (bottom >= _height) ? (_height - 1) : bottom;\n\t\tfor (int y = top; y < bottom; y++)\n\t\t{\n\t\t\tvoid* s_addr = (char*)fb + ((y * fb_width + left) * m_color_bytes);\n\t\t\tvoid* d_addr = (char*)m_phy_fb + ((y * _width + left) * m_color_bytes);\n\t\t\tmemcpy(d_addr, s_addr, (right - left) * m_color_bytes);\n\t\t}\n\t\treturn 0;\n\t}\n\tint\t\t\t\t\t\tm_width;\t\t//in pixels\n\tint\t\t\t\t\t\tm_height;\t\t//in pixels\n\tint\t\t\t\t\t\tm_color_bytes;\t//16/32 bits for default\n\tvoid*\t\t\t\t\tm_phy_fb;\t\t//physical framebuffer for default\n\tstruct DISPLAY_DRIVER*  m_driver;\t\t//Rendering by external method without default physical framebuffer\n\tint\t\t\t\tm_phy_read_index;\n\tint\t\t\t\tm_phy_write_index;\n\tc_surface*\t\tm_surface_group[SURFACE_CNT_MAX];\n\tint\t\t\t\tm_surface_cnt;\t//surface count\n\tint\t\t\t\tm_surface_index;\n\t\n};\nclass c_layer\n{\npublic:\n\tc_layer() { fb = 0; }\n\tvoid* fb;\t\t//framebuffer\n\tc_rect rect;\t//framebuffer area\n\tc_rect active_rect;\n};\nclass c_surface {\n\tfriend class c_display; friend class c_bitmap_operator;\npublic:\n\tZ_ORDER_LEVEL get_max_z_order() { return m_max_zorder; }\n\tc_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0, c_rect overlpa_rect = c_rect()) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_write_index(0), m_display(0)\n\t{\n\t\t(overlpa_rect == c_rect()) ? set_surface(max_zorder, c_rect(0, 0, width, height)) : set_surface(max_zorder, overlpa_rect);\n\t}\n\tunsigned int get_pixel(int x, int y, unsigned int z_order)\n\t{\n\t\tif (x >= m_width || y >= m_height || x < 0 || y < 0 || z_order >= Z_ORDER_LEVEL_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\tif (m_layers[z_order].fb)\n\t\t{\n\t\t\treturn (m_color_bytes == 2) ? GL_RGB_16_to_32(((unsigned short*)(m_layers[z_order].fb))[y * m_width + x]) : ((unsigned int*)(m_layers[z_order].fb))[y * m_width + x];\n\t\t}\n\t\telse if (m_fb)\n\t\t{\n\t\t\treturn (m_color_bytes == 2) ? GL_RGB_16_to_32(((unsigned short*)m_fb)[y * m_width + x]) : ((unsigned int*)m_fb)[y * m_width + x];\n\t\t}\n\t\telse if (m_display->m_phy_fb)\n\t\t{\n\t\t\treturn (m_color_bytes == 2) ? GL_RGB_16_to_32(((unsigned short*)m_display->m_phy_fb)[y * m_width + x]) : ((unsigned int*)m_display->m_phy_fb)[y * m_width + x];\n\t\t}\n\t\treturn 0;\n\t}\n\tvirtual void draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tif (x >= m_width || y >= m_height || x < 0 || y < 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tif (z_order > (unsigned int)m_max_zorder)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn;\n\t\t}\n\t\tif (z_order > (unsigned int)m_top_zorder)\n\t\t{\n\t\t\tm_top_zorder = (Z_ORDER_LEVEL)z_order;\n\t\t}\n\t\tif (z_order == m_max_zorder)\n\t\t{\n\t\t\treturn draw_pixel_low_level(x, y, rgb);\n\t\t}\n\t\tif (m_layers[z_order].rect.pt_in_rect(x, y))\n\t\t{\n\t\t\tc_rect layer_rect = m_layers[z_order].rect;\n\t\t\tif (m_color_bytes == 2)\n\t\t\t{\n\t\t\t\t((unsigned short*)(m_layers[z_order].fb))[(x - layer_rect.m_left) + (y - layer_rect.m_top) * layer_rect.width()] = GL_RGB_32_to_16(rgb);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t((unsigned int*)(m_layers[z_order].fb))[(x - layer_rect.m_left) + (y - layer_rect.m_top) * layer_rect.width()] = rgb;\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (z_order == m_top_zorder)\n\t\t{\n\t\t\treturn draw_pixel_low_level(x, y, rgb);\n\t\t}\n\t\tbool be_overlapped = false;\n\t\tfor (unsigned int tmp_z_order = Z_ORDER_LEVEL_MAX - 1; tmp_z_order > z_order; tmp_z_order--)\n\t\t{\n\t\t\tif (m_layers[tmp_z_order].active_rect.pt_in_rect(x, y))\n\t\t\t{\n\t\t\t\tbe_overlapped = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!be_overlapped)\n\t\t{\n\t\t\tdraw_pixel_low_level(x, y, rgb);\n\t\t}\n\t}\n\tvirtual void fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tx0 = (x0 < 0) ? 0 : x0;\n\t\ty0 = (y0 < 0) ? 0 : y0;\n\t\tx1 = (x1 > (m_width - 1)) ? (m_width - 1) : x1;\n\t\ty1 = (y1 > (m_height - 1)) ? (m_height - 1) : y1;\n\t\tif (z_order == m_max_zorder)\n\t\t{\n\t\t\treturn fill_rect_low_level(x0, y0, x1, y1, rgb);\n\t\t}\n\t\tif (z_order == m_top_zorder)\n\t\t{\n\t\t\tint width = m_layers[z_order].rect.width();\n\t\t\tc_rect layer_rect = m_layers[z_order].rect;\n\t\t\tunsigned int rgb_16 = GL_RGB_32_to_16(rgb);\n\t\t\tfor (int y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tfor (int x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\tif (layer_rect.pt_in_rect(x, y))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (m_color_bytes == 2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t((unsigned short*)m_layers[z_order].fb)[(y - layer_rect.m_top) * width + (x - layer_rect.m_left)] = rgb_16;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t((unsigned int*)m_layers[z_order].fb)[(y - layer_rect.m_top) * width + (x - layer_rect.m_left)] = rgb;\t\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn fill_rect_low_level(x0, y0, x1, y1, rgb);\n\t\t}\n\t\tfor (; y0 <= y1; y0++)\n\t\t{\n\t\t\tdraw_hline(x0, x1, y0, rgb, z_order);\n\t\t}\n\t}\n\tvoid draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tfor (; x0 <= x1; x0++)\n\t\t{\n\t\t\tdraw_pixel(x0, y, rgb, z_order);\n\t\t}\n\t}\n\tvoid draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tfor (; y0 <= y1; y0++)\n\t\t{\n\t\t\tdraw_pixel(x, y0, rgb, z_order);\n\t\t}\n\t}\n\tvoid draw_line(int x1, int y1, int x2, int y2, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tint dx, dy, x, y, e;\n\t\t(x1 > x2) ? (dx = x1 - x2) : (dx = x2 - x1);\n\t\t(y1 > y2) ? (dy = y1 - y2) : (dy = y2 - y1);\n\t\tif (((dx > dy) && (x1 > x2)) || ((dx <= dy) && (y1 > y2)))\n\t\t{\n\t\t\tx = x2; y = y2;\n\t\t\tx2 = x1; y2 = y1;\n\t\t\tx1 = x; y1 = y;\n\t\t}\n\t\tx = x1; y = y1;\n\t\tif (dx > dy)\n\t\t{\n\t\t\te = dy - dx / 2;\n\t\t\tfor (; x1 <= x2; ++x1, e += dy)\n\t\t\t{\n\t\t\t\tdraw_pixel(x1, y1, rgb, z_order);\n\t\t\t\tif (e > 0) { e -= dx; (y > y2) ? --y1 : ++y1; }\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\te = dx - dy / 2;\n\t\t\tfor (; y1 <= y2; ++y1, e += dx)\n\t\t\t{\n\t\t\t\tdraw_pixel(x1, y1, rgb, z_order);\n\t\t\t\tif (e > 0) { e -= dy; (x > x2) ? --x1 : ++x1; }\n\t\t\t}\n\t\t}\n\t}\n\tvoid draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size = 1)\n\t{\n\t\tfor (unsigned int offset = 0; offset < size; offset++)\n\t\t{\n\t\t\tdraw_hline(x0 + offset, x1 - offset, y0 + offset, rgb, z_order);\n\t\t\tdraw_hline(x0 + offset, x1 - offset, y1 - offset, rgb, z_order);\n\t\t\tdraw_vline(x0 + offset, y0 + offset, y1 - offset, rgb, z_order);\n\t\t\tdraw_vline(x1 - offset, y0 + offset, y1 - offset, rgb, z_order);\n\t\t}\n\t}\n\tvoid draw_rect(c_rect rect, unsigned int rgb, unsigned int size, unsigned int z_order)\n\t{\n\t\tdraw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order, size);\n\t}\n\tvoid fill_rect(c_rect rect, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tfill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order);\n\t}\n\tint flush_screen(int left, int top, int right, int bottom)\n\t{\n\t\tif (!m_is_active)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tif (left < 0 || left >= m_width || right < 0 || right >= m_width ||\n\t\t\ttop < 0 || top >= m_height || bottom < 0 || bottom >= m_height)\n\t\t{\n\t\t\tASSERT(false);\n\t\t}\n\t\tm_display->flush_screen(left, top, right, bottom, m_fb, m_width);\n\t\t*m_phy_write_index = *m_phy_write_index + 1;\n\t\treturn 0;\n\t}\n\tbool is_active() { return m_is_active; }\n\tc_display* get_display() { return m_display; }\n\tvoid activate_layer(c_rect active_rect, unsigned int active_z_order)//empty active rect means inactivating the layer\n\t{\n\t\tASSERT(active_z_order > Z_ORDER_LEVEL_0 && active_z_order <= Z_ORDER_LEVEL_MAX);\n\t\t\n\t\t//Show the layers below the current active rect.\n\t\tc_rect current_active_rect = m_layers[active_z_order].active_rect;\n\t\tfor(int low_z_order = Z_ORDER_LEVEL_0; low_z_order < active_z_order; low_z_order++)\n\t\t{\n\t\t\tc_rect low_layer_rect = m_layers[low_z_order].rect;\n\t\t\tc_rect low_active_rect = m_layers[low_z_order].active_rect;\n\t\t\tvoid* fb = m_layers[low_z_order].fb;\n\t\t\tint width = low_layer_rect.width();\n\t\t\tfor (int y = current_active_rect.m_top; y <= current_active_rect.m_bottom; y++)\n\t\t\t{\n\t\t\t\tfor (int x = current_active_rect.m_left; x <= current_active_rect.m_right; x++)\n\t\t\t\t{\n\t\t\t\t\tif (low_active_rect.pt_in_rect(x, y) && low_layer_rect.pt_in_rect(x, y))//active rect maybe is bigger than layer rect\n\t\t\t\t\t{\n\t\t\t\t\t\tunsigned int rgb = (m_color_bytes == 2) ? GL_RGB_16_to_32(((unsigned short*)fb)[(x - low_layer_rect.m_left) + (y - low_layer_rect.m_top) * width]) : ((unsigned int*)fb)[(x - low_layer_rect.m_left) + (y - low_layer_rect.m_top) * width];\n\t\t\t\t\t\tdraw_pixel_low_level(x, y, rgb);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tm_layers[active_z_order].active_rect = active_rect;//set the new acitve rect.\n\t}\n\tvoid set_active(bool flag) { m_is_active = flag; }\nprotected:\n\tvirtual void fill_rect_low_level(int x0, int y0, int x1, int y1, unsigned int rgb)\n\t{//fill rect on framebuffer of surface\n\t\tint x, y;\n\t\tif (m_color_bytes == 2)\n\t\t{\n\t\t\tunsigned short* fb;\n\t\t\tunsigned int rgb_16 = GL_RGB_32_to_16(rgb);\n\t\t\tfor (y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tfb = m_fb ? &((unsigned short*)m_fb)[y * m_width + x0] : 0;\n\t\t\t\tif (!fb) { break; }\n\t\t\t\tfor (x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\t*fb++ = rgb_16;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tunsigned int* fb;\n\t\t\tfor (y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tfb = m_fb ? &((unsigned int*)m_fb)[y * m_width + x0] : 0;\n\t\t\t\tif (!fb) { break; }\n\t\t\t\tfor (x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\t*fb++ = rgb;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!m_is_active) { return; }\n\t\tm_display->fill_rect(x0, y0, x1, y1, rgb);\n\t\t*m_phy_write_index = *m_phy_write_index + 1;\n\t}\n\tvirtual void draw_pixel_low_level(int x, int y, unsigned int rgb)\n\t{\n\t\tif (m_fb)\n\t\t{//draw pixel on framebuffer of surface\n\t\t\t(m_color_bytes == 2) ? ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb): ((unsigned int*)m_fb)[y * m_width + x] = rgb;\n\t\t}\n\t\tif (!m_is_active) { return; }\n\t\tm_display->draw_pixel(x, y, rgb);\n\t\t*m_phy_write_index = *m_phy_write_index + 1;\n\t}\n\tvoid attach_display(c_display* display)\n\t{\n\t\tASSERT(display);\n\t\tm_display = display;\n\t\tm_phy_write_index = &display->m_phy_write_index;\n\t}\n\tvoid set_surface(Z_ORDER_LEVEL max_z_order, c_rect layer_rect)\n\t{\n\t\tm_max_zorder = max_z_order;\n\t\tif (m_display && (m_display->m_surface_cnt > 1))\n\t\t{\n\t\t\tm_fb = calloc(m_width * m_height, m_color_bytes);\n\t\t}\n\t\tfor (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++)\n\t\t{//Top layber fb always be 0\n\t\t\tASSERT(m_layers[i].fb = calloc(layer_rect.width() * layer_rect.height(), m_color_bytes));\n\t\t\tm_layers[i].rect = layer_rect;\n\t\t}\n\t\tm_layers[Z_ORDER_LEVEL_0].active_rect = layer_rect;\n\t}\n\tint\t\t\t\tm_width;\t\t//in pixels\n\tint\t\t\t\tm_height;\t\t//in pixels\n\tint\t\t\t\tm_color_bytes;\t//16 bits, 32 bits for default\n\tvoid*\t\t\tm_fb;\t\t\t//frame buffer you could see\n\tc_layer \t\tm_layers[Z_ORDER_LEVEL_MAX];//all graphic layers\n\tbool\t\t\tm_is_active;\t//active flag\n\tZ_ORDER_LEVEL\tm_max_zorder;\t//the highest graphic layer the surface will have\n\tZ_ORDER_LEVEL\tm_top_zorder;\t//the current highest graphic layer the surface have\n\tint*\t\t\tm_phy_write_index;\n\tc_display*\t\tm_display;\n};\ninline c_display::c_display(void* phy_fb, int display_width, int display_height, c_surface* surface, DISPLAY_DRIVER* driver) : m_phy_fb(phy_fb), m_width(display_width), m_height(display_height), m_driver(driver), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(1), m_surface_index(0)\n{\n\tm_color_bytes = surface->m_color_bytes;\n\tsurface->m_is_active = true;\n\t(m_surface_group[0] = surface)->attach_display(this);\n}\ninline c_display::c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, DISPLAY_DRIVER* driver) : m_phy_fb(phy_fb), m_width(display_width), m_height(display_height), m_color_bytes(color_bytes), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(surface_cnt), m_driver(driver), m_surface_index(0)\n{\n\tASSERT(color_bytes == 2 || color_bytes == 4);\n\tASSERT(m_surface_cnt <= SURFACE_CNT_MAX);\n\tmemset(m_surface_group, 0, sizeof(m_surface_group));\n\t\n\tfor (int i = 0; i < m_surface_cnt; i++)\n\t{\n\t\tm_surface_group[i] = new c_surface(surface_width, surface_height, color_bytes);\n\t\tm_surface_group[i]->attach_display(this);\n\t}\n}\ninline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect layer_rect)\n{\n\tASSERT(max_zorder < Z_ORDER_LEVEL_MAX && m_surface_index < m_surface_cnt);\n\t(layer_rect == c_rect()) ? m_surface_group[m_surface_index]->set_surface(max_zorder, c_rect(0, 0, m_width, m_height)) : m_surface_group[m_surface_index]->set_surface(max_zorder, layer_rect);\n\treturn m_surface_group[m_surface_index++];\n}\ninline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset)\n{\n\tint surface_width = s0->m_width;\n\tint surface_height = s0->m_height;\n\tif (offset < 0 || offset > surface_width || y0 < 0 || y0 >= surface_height ||\n\t\ty1 < 0 || y1 >= surface_height || x0 < 0 || x0 >= surface_width || x1 < 0 || x1 >= surface_width)\n\t{\n\t\tASSERT(false);\n\t\treturn -1;\n\t}\n\tint width = (x1 - x0 + 1);\n\tif (width < 0 || width > surface_width || width < offset)\n\t{\n\t\tASSERT(false);\n\t\treturn -1;\n\t}\n\tx0 = (x0 >= m_width) ? (m_width - 1) : x0;\n\tx1 = (x1 >= m_width) ? (m_width - 1) : x1;\n\ty0 = (y0 >= m_height) ? (m_height - 1) : y0;\n\ty1 = (y1 >= m_height) ? (m_height - 1) : y1;\n\tif (m_phy_fb)\n\t{\n\t\tfor (int y = y0; y <= y1; y++)\n\t\t{\n\t\t\t//Left surface\n\t\t\tchar* addr_s = ((char*)(s0->m_fb) + (y * surface_width + x0 + offset) * m_color_bytes);\n\t\t\tchar* addr_d = ((char*)(m_phy_fb)+(y * m_width + x0) * m_color_bytes);\n\t\t\tmemcpy(addr_d, addr_s, (width - offset) * m_color_bytes);\n\t\t\t//Right surface\n\t\t\taddr_s = ((char*)(s1->m_fb) + (y * surface_width + x0) * m_color_bytes);\n\t\t\taddr_d = ((char*)(m_phy_fb)+(y * m_width + x0 + (width - offset)) * m_color_bytes);\n\t\t\tmemcpy(addr_d, addr_s, offset * m_color_bytes);\n\t\t}\n\t}\n\telse if (m_color_bytes == 2)\n\t{\n\t\tvoid(*draw_pixel)(int x, int y, unsigned int rgb) = m_driver->draw_pixel;\n\t\tfor (int y = y0; y <= y1; y++)\n\t\t{\n\t\t\t//Left surface\n\t\t\tfor (int x = x0; x <= (x1 - offset); x++)\n\t\t\t{\n\t\t\t\tdraw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s0->m_fb)[y * m_width + x + offset]));\n\t\t\t}\n\t\t\t//Right surface\n\t\t\tfor (int x = x1 - offset; x <= x1; x++)\n\t\t\t{\n\t\t\t\tdraw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s1->m_fb)[y * m_width + x + offset - x1 + x0]));\n\t\t\t}\n\t\t}\n\t}\n\telse //m_color_bytes == 3/4...\n\t{\n\t\tvoid(*draw_pixel)(int x, int y, unsigned int rgb) = m_driver->draw_pixel;\n\t\tfor (int y = y0; y <= y1; y++)\n\t\t{\n\t\t\t//Left surface\n\t\t\tfor (int x = x0; x <= (x1 - offset); x++)\n\t\t\t{\n\t\t\t\tdraw_pixel(x, y, ((unsigned int*)s0->m_fb)[y * m_width + x + offset]);\n\t\t\t}\n\t\t\t//Right surface\n\t\t\tfor (int x = x1 - offset; x <= x1; x++)\n\t\t\t{\n\t\t\t\tdraw_pixel(x, y, ((unsigned int*)s1->m_fb)[y * m_width + x + offset - x1 + x0]);\n\t\t\t}\n\t\t}\n\t}\n\tm_phy_write_index++;\n\treturn 0;\n}\n#include <string.h>\n#include <stdio.h>\n#define VALUE_STR_LEN\t16\nclass c_surface;\nclass c_font_operator\n{\npublic:\n\tvirtual void draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color) = 0;\n\tvirtual void draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT) = 0;\n\tvirtual void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color) = 0;\n\tvirtual void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT) = 0;\n\tvirtual int get_str_size(const void* string, const void* font, int& width, int& height) = 0;\n\tvoid get_string_pos(const void* string, const void* font, c_rect rect, unsigned int align_type, int& x, int& y)\n\t{\n\t\tint x_size, y_size;\n\t\tget_str_size(string, font, x_size, y_size);\n\t\tint height = rect.m_bottom - rect.m_top + 1;\n\t\tint width = rect.m_right - rect.m_left + 1;\n\t\tx = y = 0;\n\t\tswitch (align_type & ALIGN_HMASK)\n\t\t{\n\t\tcase ALIGN_HCENTER:\n\t\t\t//m_text_org_x=0\n\t\t\tif (width > x_size)\n\t\t\t{\n\t\t\t\tx = (width - x_size) / 2;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase ALIGN_LEFT:\n\t\t\tx = 0;\n\t\t\tbreak;\n\t\tcase ALIGN_RIGHT:\n\t\t\t//m_text_org_x=0\n\t\t\tif (width > x_size)\n\t\t\t{\n\t\t\t\tx = width - x_size;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(0);\n\t\t\tbreak;\n\t\t}\n\t\tswitch (align_type & ALIGN_VMASK)\n\t\t{\n\t\tcase ALIGN_VCENTER:\n\t\t\t//m_text_org_y=0\n\t\t\tif (height > y_size)\n\t\t\t{\n\t\t\t\ty = (height - y_size) / 2;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase ALIGN_TOP:\n\t\t\ty = 0;\n\t\t\tbreak;\n\t\tcase ALIGN_BOTTOM:\n\t\t\t//m_text_org_y=0\n\t\t\tif (height > y_size)\n\t\t\t{\n\t\t\t\ty = height - y_size;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(0);\n\t\t\tbreak;\n\t\t}\n\t}\n};\nclass c_lattice_font_op : public c_font_operator\n{\npublic:\n\tvoid draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)\n\t{\n\t\tconst char* s = (const char*)string;\n\t\tif (0 == s)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tint offset = 0;\n\t\tunsigned int utf8_code;\n\t\twhile (*s)\n\t\t{\n\t\t\ts += get_utf8_code(s, utf8_code);\n\t\t\toffset += draw_single_char(surface, z_order, utf8_code, (x + offset), y, (const LATTICE_FONT_INFO*)font, font_color, bg_color);\n\t\t}\n\t}\n\tvoid draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)\n\t{\n\t\tconst char* s = (const char*)string;\n\t\tif (0 == s)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tint x, y;\n\t\tget_string_pos(s, (const LATTICE_FONT_INFO*)font, rect, align_type, x, y);\n\t\tdraw_string(surface, z_order, string, rect.m_left + x, rect.m_top + y, font, font_color, bg_color);\n\t}\n\tvoid draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)\n\t{\n\t\tchar buf[VALUE_STR_LEN];\n\t\tvalue_2_string(value, dot_position, buf, VALUE_STR_LEN);\n\t\tdraw_string(surface, z_order, buf, x, y, (const LATTICE_FONT_INFO*)font, font_color, bg_color);\n\t}\n\tvoid draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)\n\t{\n\t\tchar buf[VALUE_STR_LEN];\n\t\tvalue_2_string(value, dot_position, buf, VALUE_STR_LEN);\n\t\tdraw_string_in_rect(surface, z_order, buf, rect, (const LATTICE_FONT_INFO*)font, font_color, bg_color, align_type);\n\t}\n\tint get_str_size(const void *string, const void* font, int& width, int& height)\n\t{\n\t\tconst char* s = (const char*)string;\n\t\tif (0 == s || 0 == font)\n\t\t{\n\t\t\twidth = height = 0;\n\t\t\treturn -1;\n\t\t}\n\t\tint lattice_width = 0;\n\t\tunsigned int utf8_code;\n\t\tint utf8_bytes;\n\t\twhile (*s)\n\t\t{\n\t\t\tutf8_bytes = get_utf8_code(s, utf8_code);\n\t\t\tconst LATTICE* p_lattice = get_lattice((const LATTICE_FONT_INFO*)font, utf8_code);\n\t\t\tlattice_width += p_lattice ? p_lattice->width : ((const LATTICE_FONT_INFO*)font)->height;\n\t\t\ts += utf8_bytes;\n\t\t}\n\t\twidth = lattice_width;\n\t\theight = ((const LATTICE_FONT_INFO*)font)->height;\n\t\treturn 0;\n\t}\nprivate:\n\tvoid value_2_string(int value, int dot_position, char* buf, int len)\n\t{\n\t\tmemset(buf, 0, len);\n\t\tswitch (dot_position)\n\t\t{\n\t\tcase 0:\n\t\t\tsprintf(buf, \"%d\", value);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsprintf(buf, \"%.1f\", value * 1.0 / 10);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsprintf(buf, \"%.2f\", value * 1.0 / 100);\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsprintf(buf, \"%.3f\", value * 1.0 / 1000);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t}\n\tint draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const LATTICE_FONT_INFO* font, unsigned int font_color, unsigned int bg_color)\n\t{\n\t\tunsigned int error_color = 0xFFFFFFFF;\n\t\tif (font)\n\t\t{\n\t\t\tconst LATTICE* p_lattice = get_lattice(font, utf8_code);\n\t\t\tif (p_lattice)\n\t\t\t{\n\t\t\t\tdraw_lattice(surface, z_order, x, y, p_lattice->width, font->height, p_lattice->pixel_buffer, font_color, bg_color);\n\t\t\t\treturn p_lattice->width;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\terror_color = GL_RGB(255, 0, 0);\n\t\t}\n\t\t//lattice/font not found, draw \"X\"\n\t\tint len = 16;\n\t\tfor (int y_ = 0; y_ < len; y_++)\n\t\t{\n\t\t\tfor (int x_ = 0; x_ < len; x_++)\n\t\t\t{\n\t\t\t\tint diff = (x_ - y_);\n\t\t\t\tint sum = (x_ + y_);\n\t\t\t\t(diff == 0 || diff == -1 || diff == 1 || sum == len || sum == (len - 1) || sum == (len + 1)) ?\n\t\t\t\t\tsurface->draw_pixel((x + x_), (y + y_), error_color, z_order) : surface->draw_pixel((x + x_), (y + y_), 0, z_order);\n\t\t\t}\n\t\t}\n\t\treturn len;\n\t}\n\tvoid 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)\n\t{\n\t\tunsigned int r, g, b, rgb;\n\t\tunsigned char blk_value = *p_data++;\n\t\tunsigned char blk_cnt = *p_data++;\n\t\tb = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8;\n\t\tg = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8;\n\t\tr = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8;\n\t\trgb = GL_RGB(r, g, b);\n\t\tfor (int y_ = 0; y_ < height; y_++)\n\t\t{\n\t\t\tfor (int x_ = 0; x_ < width; x_++)\n\t\t\t{\n\t\t\t\tASSERT(blk_cnt);\n\t\t\t\tif (0x00 == blk_value)\n\t\t\t\t{\n\t\t\t\t\tif (GL_ARGB_A(bg_color))\n\t\t\t\t\t{\n\t\t\t\t\t\tsurface->draw_pixel(x + x_, y + y_, bg_color, z_order);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsurface->draw_pixel((x + x_), (y + y_), rgb, z_order);\n\t\t\t\t}\n\t\t\t\tif (--blk_cnt == 0)\n\t\t\t\t{//reload new block\n\t\t\t\t\tblk_value = *p_data++;\n\t\t\t\t\tblk_cnt = *p_data++;\n\t\t\t\t\tb = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8;\n\t\t\t\t\tg = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8;\n\t\t\t\t\tr = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8;\n\t\t\t\t\trgb = GL_RGB(r, g, b);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tconst LATTICE* get_lattice(const LATTICE_FONT_INFO* font, unsigned int utf8_code)\n\t{\n\t\tint first = 0;\n\t\tint last = font->count - 1;\n\t\tint middle = (first + last) / 2;\n\t\twhile (first <= last)\n\t\t{\n\t\t\tif (font->lattice_array[middle].utf8_code < utf8_code)\n\t\t\t\tfirst = middle + 1;\n\t\t\telse if (font->lattice_array[middle].utf8_code == utf8_code)\n\t\t\t{\n\t\t\t\treturn &font->lattice_array[middle];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlast = middle - 1;\n\t\t\t}\n\t\t\tmiddle = (first + last) / 2;\n\t\t}\n\t\treturn 0;\n\t}\n\t\n\tstatic int get_utf8_code(const char* s, unsigned int& output_utf8_code)\n\t{\n\t\tstatic unsigned char s_utf8_length_table[256] =\n\t\t{\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t\t\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t\t\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t\t\t4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1\n\t\t};\n\t\tunsigned char* us = (unsigned char*)s;\n\t\tint utf8_bytes = s_utf8_length_table[*us];\n\t\tswitch (utf8_bytes)\n\t\t{\n\t\tcase 1:\n\t\t\toutput_utf8_code = *us;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\toutput_utf8_code = (*us << 8) | (*(us + 1));\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\toutput_utf8_code = (*us << 16) | ((*(us + 1)) << 8) | *(us + 2);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\toutput_utf8_code = (*us << 24) | ((*(us + 1)) << 16) | (*(us + 2) << 8) | *(us + 3);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t\treturn utf8_bytes;\n\t}\n};\nclass c_word\n{\npublic:\n\tstatic void draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)//string: char or wchar_t\n\t{\n\t\tfontOperator->draw_string(surface, z_order, string, x, y, font, font_color, bg_color);\n\t}\n\tstatic void draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)//string: char or wchar_t\n\t{\n\t\tfontOperator->draw_string_in_rect(surface, z_order, string, rect, font, font_color, bg_color, align_type);\n\t}\n\tstatic void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)\n\t{\n\t\tfontOperator->draw_value_in_rect(surface, z_order, value, dot_position, rect, font, font_color, bg_color, align_type);\n\t}\n\tstatic void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)\n\t{\n\t\tfontOperator->draw_value(surface, z_order, value, dot_position, x, y, font, font_color, bg_color);\n\t}\n\t\n\tstatic int get_str_size(const void* string, const void* font, int& width, int& height)\n\t{\n\t\treturn fontOperator->get_str_size(string, font, width, height);\n\t}\n\tstatic c_font_operator* fontOperator;\n};\n#define\tDEFAULT_MASK_COLOR 0xFF080408\nclass c_surface;\nclass c_image_operator\n{\npublic:\n\tvirtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR) = 0;\n\tvirtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR) = 0;\n};\nclass c_bitmap_operator : public c_image_operator\n{\npublic:\n\tvirtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR)\n\t{\n\t\tASSERT(image_info);\n\t\tBITMAP_INFO* pBitmap = (BITMAP_INFO*)image_info;\n\t\tunsigned short* lower_fb_16 = 0;\n\t\tunsigned int* lower_fb_32 = 0;\n\t\tint lower_fb_width = 0;\n\t\tc_rect lower_fb_rect;\n\t\tif (z_order >= Z_ORDER_LEVEL_1)\n\t\t{\n\t\t\tlower_fb_16 = (unsigned short*)surface->m_layers[z_order - 1].fb;\n\t\t\tlower_fb_32 = (unsigned int*)surface->m_layers[z_order - 1].fb;\n\t\t\tlower_fb_rect = surface->m_layers[z_order - 1].rect;\n\t\t\tlower_fb_width = lower_fb_rect.width();\n\t\t}\n\t\tunsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb);\n\t\tint xsize = pBitmap->width;\n\t\tint ysize = pBitmap->height;\n\t\tconst unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array;\n\t\tint color_bytes = surface->m_color_bytes;\n\t\tfor (int y_ = y; y_ < y + ysize; y_++)\n\t\t{\n\t\t\tfor (int x_ = x; x_ < x + xsize; x_++)\n\t\t\t{\n\t\t\t\tunsigned int rgb = *pData++;\n\t\t\t\tif (mask_rgb_16 == rgb)\n\t\t\t\t{\n\t\t\t\t\tif (lower_fb_rect.pt_in_rect(x_, y_))\n\t\t\t\t\t{//show lower layer\n\t\t\t\t\t\tsurface->draw_pixel(x_, y_, (color_bytes == 4) ? lower_fb_32[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)] : GL_RGB_16_to_32(lower_fb_16[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)]), z_order);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsurface->draw_pixel(x_, y_, GL_RGB_16_to_32(rgb), z_order);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvirtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR)\n\t{\n\t\tASSERT(image_info);\n\t\tBITMAP_INFO* pBitmap = (BITMAP_INFO*)image_info;\n\t\tif (0 == pBitmap || (src_x + width > pBitmap->width) || (src_y + height > pBitmap->height))\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tunsigned short* lower_fb_16 = 0;\n\t\tunsigned int* lower_fb_32 = 0;\n\t\tint lower_fb_width = 0;\n\t\tc_rect lower_fb_rect;\n\t\tif (z_order >= Z_ORDER_LEVEL_1)\n\t\t{\n\t\t\tlower_fb_16 = (unsigned short*)surface->m_layers[z_order - 1].fb;\n\t\t\tlower_fb_32 = (unsigned int*)surface->m_layers[z_order - 1].fb;\n\t\t\tlower_fb_rect = surface->m_layers[z_order - 1].rect;\n\t\t\tlower_fb_width = lower_fb_rect.width();\n\t\t}\n\t\tunsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb);\n\t\tconst unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array;\n\t\tint color_bytes = surface->m_color_bytes;\n\t\tfor (int y_ = 0; y_ < height; y_++)\n\t\t{\n\t\t\tconst unsigned short* p = &pData[src_x + (src_y + y_) * pBitmap->width];\n\t\t\tfor (int x_ = 0; x_ < width; x_++)\n\t\t\t{\n\t\t\t\tunsigned int rgb = *p++;\n\t\t\t\tif (mask_rgb_16 == rgb)\n\t\t\t\t{\n\t\t\t\t\tif (lower_fb_rect.pt_in_rect(x + x_, y + y_))\n\t\t\t\t\t{//show lower layer\n\t\t\t\t\t\tsurface->draw_pixel(x + x_, y + y_, (color_bytes == 4) ? lower_fb_32[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left] : GL_RGB_16_to_32(lower_fb_16[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left]), z_order);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsurface->draw_pixel(x + x_, y + y_, GL_RGB_16_to_32(rgb), z_order);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\nclass c_image\n{\npublic:\n\tstatic void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR)\n\t{\n\t\timage_operator->draw_image(surface, z_order, image_info, x, y, mask_rgb);\n\t}\n\tstatic void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR)\n\t{\n\t\timage_operator->draw_image(surface, z_order, image_info, x, y, src_x, src_y, width, height, mask_rgb);\n\t}\n\t\n\tstatic c_image_operator* image_operator;\n};\nclass c_wnd;\nclass c_surface;\ntypedef enum\n{\n\tATTR_VISIBLE\t= 0x40000000L,\n\tATTR_FOCUS\t\t= 0x20000000L,\n\tATTR_PRIORITY\t= 0x10000000L// Handle touch action at high priority\n}WND_ATTRIBUTION;\ntypedef enum\n{\n\tSTATUS_NORMAL,\n\tSTATUS_PUSHED,\n\tSTATUS_FOCUSED,\n\tSTATUS_DISABLED\n}WND_STATUS;\ntypedef enum\n{\n\tNAV_FORWARD,\n\tNAV_BACKWARD,\n\tNAV_ENTER\n}NAVIGATION_KEY;\ntypedef enum\n{\n\tTOUCH_DOWN,\n\tTOUCH_UP\n}TOUCH_ACTION;\ntypedef struct struct_wnd_tree\n{\n\tc_wnd*\t\t\t\t\tp_wnd;//window instance\n\tunsigned int\t\t\tresource_id;//ID\n\tconst char*\t\t\t\tstr;//caption\n\tshort   \t\t\t\tx;//position x\n\tshort   \t\t\t\ty;//position y\n\tshort   \t\t\t\twidth;\n\tshort        \t\t\theight;\n\tstruct struct_wnd_tree*\tp_child_tree;//sub tree\n}WND_TREE;\ntypedef void (c_wnd::*WND_CALLBACK)(int, int);\nclass c_wnd\n{\npublic:\n\tc_wnd() : m_status(STATUS_NORMAL), m_attr((WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)), m_parent(0), m_top_child(0), m_prev_sibling(0), m_next_sibling(0),\n\t\tm_str(0), m_font_color(0), m_bg_color(0), m_id(0), m_z_order(Z_ORDER_LEVEL_0), m_focus_child(0), m_surface(0) {};\n\tvirtual ~c_wnd() {};\n\tvirtual int connect(c_wnd *parent, unsigned short resource_id, const char* str,\n\t\tshort x, short y, short width, short height, WND_TREE* p_child_tree = 0)\n\t{\n\t\tif (0 == resource_id)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\tm_id = resource_id;\n\t\tset_str(str);\n\t\tm_parent = parent;\n\t\tm_status = STATUS_NORMAL;\n\t\tif (parent)\n\t\t{\n\t\t\tm_z_order = parent->m_z_order;\n\t\t\tm_surface = parent->m_surface;\n\t\t}\n\t\tif (0 == m_surface)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -2;\n\t\t}\n\t\t/* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/\n\t\tm_wnd_rect.m_left = x;\n\t\tm_wnd_rect.m_top = y;\n\t\tm_wnd_rect.m_right = (x + width - 1);\n\t\tm_wnd_rect.m_bottom = (y + height - 1);\n\t\tpre_create_wnd();\n\t\tif (0 != parent)\n\t\t{\n\t\t\tparent->add_child_2_tail(this);\n\t\t}\n\t\tif (load_child_wnd(p_child_tree) >= 0)\n\t\t{\n\t\t\ton_init_children();\n\t\t}\n\t\treturn 0;\n\t}\n\tvoid disconnect()\n\t{\n\t\tif (0 != m_top_child)\n\t\t{\n\t\t\tc_wnd* child = m_top_child;\n\t\t\tc_wnd* next_child = 0;\n\t\t\twhile (child)\n\t\t\t{\n\t\t\t\tnext_child = child->m_next_sibling;\n\t\t\t\tchild->disconnect();\n\t\t\t\tchild = next_child;\n\t\t\t}\n\t\t}\n\t\tif (0 != m_parent)\n\t\t{\n\t\t\tm_parent->unlink_child(this);\n\t\t}\n\t\tm_focus_child = 0;\n\t\tm_attr = WND_ATTRIBUTION(0);\n\t}\n\tvirtual void on_init_children() {}\n\tvirtual void on_paint() {}\n\tvirtual void show_window()\n\t{\n\t\tif (ATTR_VISIBLE == (m_attr & ATTR_VISIBLE))\n\t\t{\n\t\t\ton_paint();\n\t\t\tc_wnd* child = m_top_child;\n\t\t\tif (0 != child)\n\t\t\t{\n\t\t\t\twhile (child)\n\t\t\t\t{\n\t\t\t\t\tchild->show_window();\n\t\t\t\t\tchild = child->m_next_sibling;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tunsigned short get_id() const { return m_id; }\n\tint get_z_order() { return m_z_order; }\n\tc_wnd* get_wnd_ptr(unsigned short id) const\n\t{\n\t\tc_wnd* child = m_top_child;\n\t\twhile (child)\n\t\t{\n\t\t\tif (child->get_id() == id)\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tchild = child->m_next_sibling;\n\t\t}\n\t\treturn child;\n\t}\n\tunsigned int get_attr() const { return m_attr; }\n\tvoid set_str(const char* str) { m_str = str; }\n\tvoid set_attr(WND_ATTRIBUTION attr) { m_attr = attr; }\n\tbool is_focus_wnd() const\n\t{\n\t\treturn ((m_attr & ATTR_VISIBLE) && (m_attr & ATTR_FOCUS)) ? true : false;\n\t}\n\tvoid set_font_color(unsigned int color) { m_font_color = color; }\n\tunsigned int get_font_color() { return m_font_color; }\n\tvoid set_bg_color(unsigned int color) { m_bg_color = color; }\n\tunsigned int get_bg_color() { return m_bg_color; }\n\tvoid set_font_type(const LATTICE_FONT_INFO *font_type) { m_font = font_type; }\n\tconst void* get_font_type() { return m_font; }\n\tvoid get_wnd_rect(c_rect &rect) const {\trect = m_wnd_rect; }\n\tvoid get_screen_rect(c_rect &rect) const\n\t{\n\t\tint l = 0;\n\t\tint t = 0;\n\t\twnd2screen(l, t);\n\t\trect.set_rect(l, t, m_wnd_rect.width(), m_wnd_rect.height());\n\t}\n\tc_wnd* set_child_focus(c_wnd *focus_child)\n\t{\n\t\tASSERT(0 != focus_child);\n\t\tASSERT(focus_child->m_parent == this);\n\t\tc_wnd* old_focus_child = m_focus_child;\n\t\tif (focus_child->is_focus_wnd())\n\t\t{\n\t\t\tif (focus_child != old_focus_child)\n\t\t\t{\n\t\t\t\tif (old_focus_child)\n\t\t\t\t{\n\t\t\t\t\told_focus_child->on_kill_focus();\n\t\t\t\t}\n\t\t\t\tm_focus_child = focus_child;\n\t\t\t\tm_focus_child->on_focus();\n\t\t\t}\n\t\t}\n\t\treturn m_focus_child;\n\t}\n\tc_wnd* get_parent() const { return m_parent; }\n\tc_wnd* get_last_child() const\n\t{\n\t\tif (0 == m_top_child)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\tc_wnd* child = m_top_child;\n\t\twhile (child->m_next_sibling)\n\t\t{\n\t\t\tchild = child->m_next_sibling;\n\t\t}\n\t\treturn child;\n\t}\n\tint\tunlink_child(c_wnd *child)\n\t{\n\t\tif ((0 == child)\n\t\t\t|| (this != child->m_parent))\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tif (0 == m_top_child)\n\t\t{\n\t\t\treturn -2;\n\t\t}\n\t\tbool find = false;\n\t\tc_wnd* tmp_child = m_top_child;\n\t\tif (tmp_child == child)\n\t\t{\n\t\t\tm_top_child = child->m_next_sibling;\n\t\t\tif (0 != child->m_next_sibling)\n\t\t\t{\n\t\t\t\tchild->m_next_sibling->m_prev_sibling = 0;\n\t\t\t}\n\t\t\tfind = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile (tmp_child->m_next_sibling)\n\t\t\t{\n\t\t\t\tif (child == tmp_child->m_next_sibling)\n\t\t\t\t{\n\t\t\t\t\ttmp_child->m_next_sibling = child->m_next_sibling;\n\t\t\t\t\tif (0 != child->m_next_sibling)\n\t\t\t\t\t{\n\t\t\t\t\t\tchild->m_next_sibling->m_prev_sibling = tmp_child;\n\t\t\t\t\t}\n\t\t\t\t\tfind = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ttmp_child = tmp_child->m_next_sibling;\n\t\t\t}\n\t\t}\n\t\tif (true == find)\n\t\t{\n\t\t\tif (m_focus_child == child)\n\t\t\t{\n\t\t\t\tm_focus_child = 0;\n\t\t\t}\n\t\t\tchild->m_next_sibling = 0;\n\t\t\tchild->m_prev_sibling = 0;\n\t\t\treturn 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t}\n\tc_wnd* get_prev_sibling() const { return m_prev_sibling; }\n\tc_wnd* get_next_sibling() const { return m_next_sibling; }\n\tc_wnd* search_priority_sibling(c_wnd* root)\n\t{\n\t\tc_wnd* priority_wnd = 0;\n\t\twhile (root)\n\t\t{\n\t\t\tif ((root->m_attr & ATTR_PRIORITY) && (root->m_attr & ATTR_VISIBLE))\n\t\t\t{\n\t\t\t\tpriority_wnd = root;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\troot = root->m_next_sibling;\n\t\t}\n\t\treturn priority_wnd;\n\t}\n\tvirtual void on_touch(int x, int y, TOUCH_ACTION action)\n\t{\n\t\tx -= m_wnd_rect.m_left;\n\t\ty -= m_wnd_rect.m_top;\n\t\tc_wnd* priority_wnd = search_priority_sibling(m_top_child);\n\t\tif (priority_wnd)\n\t\t{\n\t\t\treturn priority_wnd->on_touch(x, y, action);\n\t\t}\n\t\tc_wnd* child = m_top_child;\n\t\twhile (child)\n\t\t{\n\t\t\tif (child->is_focus_wnd())\n\t\t\t{\n\t\t\t\tc_rect rect;\n\t\t\t\tchild->get_wnd_rect(rect);\n\t\t\t\tif (true == rect.pt_in_rect(x, y))\n\t\t\t\t{\n\t\t\t\t\treturn child->on_touch(x, y, action);\n\t\t\t\t}\n\t\t\t}\n\t\t\tchild = child->m_next_sibling;\n\t\t}\n\t}\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tc_wnd* priority_wnd = search_priority_sibling(m_top_child);\n\t\tif (priority_wnd)\n\t\t{\n\t\t\treturn priority_wnd->on_navigate(key);\n\t\t}\n\t\tif (!is_focus_wnd())\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tif (key != NAV_BACKWARD && key != NAV_FORWARD)\n\t\t{\n\t\t\tif (m_focus_child)\n\t\t\t{\n\t\t\t\tm_focus_child->on_navigate(key);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Move focus\n\t\tc_wnd* old_focus_wnd = m_focus_child;\n\t\t// No current focus wnd, new one.\n\t\tif (!old_focus_wnd)\n\t\t{\n\t\t\tc_wnd* child = m_top_child;\n\t\t\tc_wnd* new_focus_wnd = 0;\n\t\t\twhile (child)\n\t\t\t{\n\t\t\t\tif (child->is_focus_wnd())\n\t\t\t\t{\n\t\t\t\t\tnew_focus_wnd = child;\n\t\t\t\t\tnew_focus_wnd->m_parent->set_child_focus(new_focus_wnd);\n\t\t\t\t\tchild = child->m_top_child;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tchild = child->m_next_sibling;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Move focus from old wnd to next wnd\n\t\tc_wnd* next_focus_wnd = (key == NAV_FORWARD) ? old_focus_wnd->m_next_sibling : old_focus_wnd->m_prev_sibling;\n\t\twhile (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))\n\t\t{// Search neighbor of old focus wnd\n\t\t\tnext_focus_wnd = (key == NAV_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;\n\t\t}\n\t\tif (!next_focus_wnd)\n\t\t{// Search whole brother wnd\n\t\t\tnext_focus_wnd = (key == NAV_FORWARD) ? old_focus_wnd->m_parent->m_top_child : old_focus_wnd->m_parent->get_last_child();\n\t\t\twhile (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))\n\t\t\t{\n\t\t\t\tnext_focus_wnd = (key == NAV_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;\n\t\t\t}\n\t\t}\n\t\tif (next_focus_wnd)\n\t\t{\n\t\t\tnext_focus_wnd->m_parent->set_child_focus(next_focus_wnd);\n\t\t}\n\t}\n\tc_surface* get_surface() { return m_surface; }\n\tvoid set_surface(c_surface* surface) { m_surface = surface; }\nprotected:\n\tvirtual void pre_create_wnd() {};\n\tvoid add_child_2_tail(c_wnd *child)\n\t{\n\t\tif (0 == child)return;\n\t\tif (child == get_wnd_ptr(child->m_id))return;\n\t\tif (0 == m_top_child)\n\t\t{\n\t\t\tm_top_child = child;\n\t\t\tchild->m_prev_sibling = 0;\n\t\t\tchild->m_next_sibling = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tc_wnd* last_child = get_last_child();\n\t\t\tif (0 == last_child)\n\t\t\t{\n\t\t\t\tASSERT(false);\n\t\t\t}\n\t\t\tlast_child->m_next_sibling = child;\n\t\t\tchild->m_prev_sibling = last_child;\n\t\t\tchild->m_next_sibling = 0;\n\t\t}\n\t}\n\tvoid wnd2screen(int &x, int &y) const\n\t{\n\t\tc_wnd* parent = m_parent;\n\t\tc_rect rect;\n\t\tx += m_wnd_rect.m_left;\n\t\ty += m_wnd_rect.m_top;\n\t\twhile (0 != parent)\n\t\t{\n\t\t\tparent->get_wnd_rect(rect);\n\t\t\tx += rect.m_left;\n\t\t\ty += rect.m_top;\n\t\t\tparent = parent->m_parent;\n\t\t}\n\t}\n\tint load_child_wnd(WND_TREE *p_child_tree)\n\t{\n\t\tif (0 == p_child_tree)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\tint sum = 0;\n\t\tWND_TREE* p_cur = p_child_tree;\n\t\twhile (p_cur->p_wnd)\n\t\t{\n\t\t\tp_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);\n\t\t\tp_cur++;\n\t\t\tsum++;\n\t\t}\n\t\treturn sum;\n\t}\n\tvoid set_active_child(c_wnd* child) { m_focus_child = child; }\n\tvirtual void on_focus() {};\n\tvirtual void on_kill_focus() {};\nprotected:\n\tunsigned short\tm_id;\n\tWND_STATUS\t\tm_status;\n\tWND_ATTRIBUTION\tm_attr;\n\tc_rect\t\t\tm_wnd_rect;\t\t//position relative to parent window.\n\tc_wnd*\t\t\tm_parent;\t\t//parent window\n\tc_wnd*\t\t\tm_top_child;\t//the first sub window would be navigated\n\tc_wnd*\t\t\tm_prev_sibling;\t//previous brother\n\tc_wnd*\t\t\tm_next_sibling;\t//next brother\n\tc_wnd*\t\t\tm_focus_child;\t//current focused window\n\tconst char*\t\tm_str;\t\t\t//caption\n\tconst void*\t\tm_font;\t\t\t//font face\n\tunsigned int\tm_font_color;\n\tunsigned int\tm_bg_color;\n\tint\t\t\t\tm_z_order;\t\t//the graphic level for rendering\n\tc_surface*\t\tm_surface;\n};\nclass c_button : public c_wnd\n{\npublic:\n\tvoid set_on_click(WND_CALLBACK on_click) { this->on_click = on_click; }\nprotected:\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tswitch (m_status)\n\t\t{\n\t\tcase STATUS_NORMAL:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\t\tif (m_str)\n\t\t\t{\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase STATUS_FOCUSED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\tif (m_str)\n\t\t\t{\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase STATUS_PUSHED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);\n\t\t\tm_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);\n\t\t\tif (m_str)\n\t\t\t{\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t}\n\tvirtual void on_focus()\n\t{\n\t\tm_status = STATUS_FOCUSED;\n\t\ton_paint();\n\t}\n\tvirtual void on_kill_focus()\n\t{\n\t\tm_status = STATUS_NORMAL;\n\t\ton_paint();\n\t}\n\tvirtual void pre_create_wnd()\n\t{\n\t\ton_click = 0;\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t}\n\tvirtual void on_touch(int x, int y, TOUCH_ACTION action)\n\t{\n\t\tif (action == TOUCH_DOWN)\n\t\t{\n\t\t\tm_parent->set_child_focus(this);\n\t\t\tm_status = STATUS_PUSHED;\n\t\t\ton_paint();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_status = STATUS_FOCUSED;\n\t\t\ton_paint();\n\t\t\tif(on_click)\n\t\t\t{\n\t\t\t\t(m_parent->*(on_click))(m_id, 0);\n\t\t\t}\n\t\t}\n\t}\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tswitch (key)\n\t\t{\n\t\tcase NAV_ENTER:\n\t\t\ton_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN);\n\t\t\ton_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP);\n\t\t\tbreak;\n\t\tcase NAV_FORWARD:\n\t\tcase NAV_BACKWARD:\n\t\t\tbreak;\n\t\t}\n\t\treturn c_wnd::on_navigate(key);\n\t}\n\tWND_CALLBACK on_click;\n};\nclass c_surface;\nclass c_dialog;\ntypedef struct\n{\n\tc_dialog* \tdialog;\n\tc_surface*\tsurface;\n} DIALOG_ARRAY;\nclass c_dialog : public c_wnd\n{\npublic:\n\tstatic int open_dialog(c_dialog* p_dlg, bool modal_mode = true)\n\t{\n\t\tif (0 == p_dlg)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\tc_dialog* cur_dlg = get_the_dialog(p_dlg->get_surface());\n\t\tif (cur_dlg == p_dlg)\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tif (cur_dlg)\n\t\t{\n\t\t\tcur_dlg->set_attr(WND_ATTRIBUTION(0));\n\t\t}\n\t\tc_rect rc;\n\t\tp_dlg->get_screen_rect(rc);\n\t\tp_dlg->get_surface()->activate_layer(rc, p_dlg->m_z_order);\n\t\tp_dlg->set_attr(modal_mode ? (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY) : (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS));\n\t\tp_dlg->show_window();\n\t\tp_dlg->set_me_the_dialog();\n\t\treturn 1;\n\t}\n\tstatic int close_dialog(c_surface* surface)\n\t{\n\t\tc_dialog* dlg = get_the_dialog(surface);\n\t\tif (0 == dlg)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\tdlg->set_attr(WND_ATTRIBUTION(0));\n\t\tsurface->activate_layer(c_rect(), dlg->m_z_order);//inactivate the layer of dialog by empty rect.\n\t\t//clear the dialog\n\t\tfor (int i = 0; i < SURFACE_CNT_MAX; i++)\n\t\t{\n\t\t\tif (ms_the_dialogs[i].surface == surface)\n\t\t\t{\n\t\t\t\tms_the_dialogs[i].dialog = 0;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tASSERT(false);\n\t\treturn -1;\n\t}\n\tstatic c_dialog* get_the_dialog(c_surface* surface)\n\t{\n\t\tfor (int i = 0; i < SURFACE_CNT_MAX; i++)\n\t\t{\n\t\t\tif (ms_the_dialogs[i].surface == surface)\n\t\t\t{\n\t\t\t\treturn ms_the_dialogs[i].dialog;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = WND_ATTRIBUTION(0);// no focus/visible\n\t\tm_z_order = Z_ORDER_LEVEL_1;\n\t\tm_bg_color = GL_RGB(33, 42, 53);\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tm_surface->fill_rect(rect, m_bg_color, m_z_order);\n\t\tif (m_str)\n\t\t{\n\t\t\tc_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));\n\t\t}\n\t}\nprivate:\n\tint set_me_the_dialog()\n\t{\n\t\tc_surface* surface = get_surface();\n\t\tfor (int i = 0; i < SURFACE_CNT_MAX; i++)\n\t\t{\n\t\t\tif (ms_the_dialogs[i].surface == surface)\n\t\t\t{\n\t\t\t\tms_the_dialogs[i].dialog = this;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\tfor (int i = 0; i < SURFACE_CNT_MAX; i++)\n\t\t{\n\t\t\tif (ms_the_dialogs[i].surface == 0)\n\t\t\t{\n\t\t\t\tms_the_dialogs[i].dialog = this;\n\t\t\t\tms_the_dialogs[i].surface = surface;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tASSERT(false);\n\t\treturn -2;\n\t}\n\tstatic DIALOG_ARRAY ms_the_dialogs[SURFACE_CNT_MAX];\n};\n#include <string.h>\n//Changing key width/height will change the width/height of keyboard\n#define KEY_WIDTH          65\n#define KEY_HEIGHT         38\n#define KEYBOARD_WIDTH\t\t((KEY_WIDTH + 2) * 10)\n#define KEYBOARD_HEIGHT\t\t((KEY_HEIGHT + 2) * 4)\n#define NUM_BOARD_WIDTH\t\t((KEY_WIDTH + 2) * 4)\n#define NUM_BOARD_HEIGHT\t((KEY_HEIGHT + 2) * 4)\n#define CAPS_WIDTH\t\t\t(KEY_WIDTH * 3 / 2)\n#define DEL_WIDTH\t\t\t(KEY_WIDTH * 3 / 2 + 1)\n#define ESC_WIDTH\t\t\t(KEY_WIDTH * 2 + 2)\n#define SWITCH_WIDTH\t\t(KEY_WIDTH * 3 / 2 )\n#define SPACE_WIDTH\t\t\t(KEY_WIDTH * 3 + 2 * 2)\n#define DOT_WIDTH\t\t\t(KEY_WIDTH * 3 / 2 + 3)\n#define ENTER_WIDTH\t\t\t(KEY_WIDTH * 2 + 2)\n#define POS_X(c)\t\t\t((KEY_WIDTH * c) + (c + 1) * 2)\n#define POS_Y(r)\t\t\t((KEY_HEIGHT * r) + (r + 1) * 2)\n#define KEYBOARD_CLICK\t\t\t0x5014\n#define ON_KEYBORAD_UPDATE(func)  \\\n{MSG_TYPE_WND, KEYBOARD_CLICK, 0,  msgCallback(&func)},\ntypedef enum\n{\n\tSTATUS_UPPERCASE,\n\tSTATUS_LOWERCASE\n}KEYBOARD_STATUS;\ntypedef enum\n{\n\tSTYLE_ALL_BOARD,\n\tSTYLE_NUM_BOARD\n}KEYBOARD_STYLE;\ntypedef enum\n{\n\tCLICK_CHAR,\n\tCLICK_ENTER,\n\tCLICK_ESC\n}CLICK_STATUS;\nextern WND_TREE g_key_board_children[];\nextern WND_TREE g_number_board_children[];\nclass c_keyboard: public c_wnd\n{\npublic:\n\tc_keyboard() { m_attr = WND_ATTRIBUTION(0); }\n\tint open_keyboard(c_wnd *user, unsigned short resource_id, KEYBOARD_STYLE style, WND_CALLBACK on_click)\n\t{\n\t\tc_rect user_rect;\n\t\tuser->get_wnd_rect(user_rect);\n\t\tif ((style != STYLE_ALL_BOARD) && (style != STYLE_NUM_BOARD))\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\tif (style == STYLE_ALL_BOARD)\n\t\t{//Place keyboard at the bottom of user's parent window.\n\t\t\tc_rect user_parent_rect;\n\t\t\tuser->get_parent()->get_wnd_rect(user_parent_rect);\n\t\t\tc_wnd::connect(user, resource_id, 0, (0 - user_rect.m_left), (user_parent_rect.height() - user_rect.m_top - KEYBOARD_HEIGHT - 1), KEYBOARD_WIDTH, KEYBOARD_HEIGHT, g_key_board_children);\n\t\t}\n\t\telse if (style == STYLE_NUM_BOARD)\n\t\t{//Place keyboard below the user window.\n\t\t\tc_wnd::connect(user, resource_id, 0, 0, user_rect.height(), NUM_BOARD_WIDTH, NUM_BOARD_HEIGHT, g_number_board_children);\n\t\t}\n\t\tm_on_click = on_click;\n\t\tc_rect rc;\n\t\tget_screen_rect(rc);\n\t\tm_surface->activate_layer(rc, m_z_order);\n\t\tshow_window();\n\t\treturn 0;\n\t}\n\tvoid close_keyboard()\n\t{\n\t\tc_wnd::disconnect();\n\t\tm_surface->activate_layer(c_rect(), m_z_order);//inactivate the layer of keyboard by empty rect.\n\t}\n\t\n\tvirtual void on_init_children()\n\t{\n\t\tc_wnd* child = m_top_child;\n\t\tif (0 != child)\n\t\t{\n\t\t\twhile (child)\n\t\t\t{\n\t\t\t\t((c_button*)child)->set_on_click(WND_CALLBACK(&c_keyboard::on_key_clicked));\n\t\t\t\tchild = child->get_next_sibling();\n\t\t\t}\n\t\t}\n\t}\n\tKEYBOARD_STATUS get_cap_status(){return m_cap_status;}\n\tchar* get_str() { return m_str; }\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY);\n\t\tm_cap_status = STATUS_UPPERCASE;\n\t\tm_z_order = m_surface->get_max_z_order();\n\t\tmemset(m_str, 0, sizeof(m_str));\n\t\tm_str_len = 0;\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tm_surface->fill_rect(rect, GL_RGB(0, 0, 0), m_z_order);\n\t}\n\tvoid on_key_clicked(int id, int param)\n\t{\n\t\tswitch (id)\n\t\t{\n\t\tcase 0x14:\n\t\t\ton_caps_clicked(id, param);\n\t\t\tbreak;\n\t\tcase '\\n':\n\t\t\ton_enter_clicked(id, param);\n\t\t\tbreak;\n\t\tcase 0x1B:\n\t\t\ton_esc_clicked(id, param);\n\t\t\tbreak;\n\t\tcase 0x7F:\n\t\t\ton_del_clicked(id, param);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ton_char_clicked(id, param);\n\t\t\tbreak;\n\t\t}\n\t}\n\tvoid on_char_clicked(int id, int param)\n\t{//id = char ascii code.\n\t\tif (m_str_len >= sizeof(m_str))\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tif ((id >= '0' && id <= '9') || id == ' ' || id == '.')\n\t\t{\n\t\t\tgoto InputChar;\n\t\t}\n\t\tif (id >= 'A' && id <= 'Z')\n\t\t{\n\t\t\tif (STATUS_LOWERCASE == m_cap_status)\n\t\t\t{\n\t\t\t\tid += 0x20;\n\t\t\t}\n\t\t\tgoto InputChar;\n\t\t}\n\t\tif (id == 0x90) return;//TBD\n\t\tASSERT(false);\n\tInputChar:\n\t\tm_str[m_str_len++] = id;\n\t\t(m_parent->*(m_on_click))(m_id, CLICK_CHAR);\n\t}\n\tvoid on_del_clicked(int id, int param)\n\t{\n\t\tif (m_str_len <= 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tm_str[--m_str_len] = 0;\n\t\t(m_parent->*(m_on_click))(m_id, CLICK_CHAR);\n\t}\n\tvoid on_caps_clicked(int id, int param)\n\t{\n\t\tm_cap_status = (m_cap_status == STATUS_LOWERCASE) ? STATUS_UPPERCASE : STATUS_LOWERCASE;\n\t\tshow_window();\n\t}\n\tvoid on_enter_clicked(int id, int param)\n\t{\n\t\tmemset(m_str, 0, sizeof(m_str));\n\t\t(m_parent->*(m_on_click))(m_id, CLICK_ENTER);\n\t}\n\tvoid on_esc_clicked(int id, int param)\n\t{\n\t\tmemset(m_str, 0, sizeof(m_str));\n\t\t(m_parent->*(m_on_click))(m_id, CLICK_ESC);\n\t}\nprivate:\n\tchar m_str[32];\n\tint\t m_str_len;\n\tKEYBOARD_STATUS m_cap_status;\n\tWND_CALLBACK m_on_click;\n};\nclass c_keyboard_button : public c_button\n{\nprotected:\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tswitch (m_status)\n\t\t{\n\t\tcase STATUS_NORMAL:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\t\tbreak;\n\t\tcase STATUS_FOCUSED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\tbreak;\n\t\tcase STATUS_PUSHED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);\n\t\t\tm_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t\tif (m_id == 0x14)\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Caps\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == 0x1B)\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Esc\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == ' ')\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Space\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == '\\n')\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Enter\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == '.')\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \".\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == 0x7F)\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Back\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == 0x90)\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"?123\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\tchar letter[] = { 0, 0 };\n\t\tif (m_id >= 'A' && m_id <= 'Z')\n\t\t{\n\t\t\tletter[0] = (((c_keyboard*)m_parent)->get_cap_status() == STATUS_UPPERCASE) ? m_id : (m_id + 0x20);\n\t\t}\n\t\telse if (m_id >= '0' && m_id <= '9')\n\t\t{\n\t\t\tletter[0] = (char)m_id;\n\t\t}\n\t\tc_word::draw_string_in_rect(m_surface, m_z_order, letter, rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t}\n};\n#include <string.h>\n#define MAX_EDIT_STRLEN\t\t32\n#define IDD_KEY_BOARD\t\t0x1\nclass c_edit : public c_wnd\n{\n\tfriend class c_keyboard;\npublic:\n\tconst char* get_text(){return m_str;}\n\tvoid set_text(const char* str)\n\t{\n\t\tif (str != 0 && strlen(str) < sizeof(m_str))\n\t\t{\n\t\t\tstrcpy(m_str, str);\n\t\t}\n\t}\n\tvoid set_keyboard_style(KEYBOARD_STYLE kb_sytle) { m_kb_style = kb_sytle; }\n\t\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\tm_kb_style = STYLE_ALL_BOARD;\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t\tmemset(m_str_input, 0, sizeof(m_str_input));\n\t\tmemset(m_str, 0, sizeof(m_str));\n\t\tset_text(c_wnd::m_str);\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect, kb_rect;\n\t\tget_screen_rect(rect);\n\t\ts_keyboard.get_screen_rect(kb_rect);\n\t\tswitch (m_status)\n\t\t{\n\t\tcase STATUS_NORMAL:\n\t\t\tif ((s_keyboard.get_attr()&ATTR_VISIBLE) == ATTR_VISIBLE)\n\t\t\t{\n\t\t\t\ts_keyboard.close_keyboard();\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\t\t}\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tcase STATUS_FOCUSED:\n\t\t\tif ((s_keyboard.get_attr()&ATTR_VISIBLE) == ATTR_VISIBLE)\n\t\t\t{\n\t\t\t\ts_keyboard.close_keyboard();\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\t\t}\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tcase STATUS_PUSHED:\n\t\t\tif ((s_keyboard.get_attr()&ATTR_VISIBLE) != ATTR_VISIBLE)\n\t\t\t{\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY);\n\t\t\t\ts_keyboard.open_keyboard(this, IDD_KEY_BOARD, m_kb_style, WND_CALLBACK(&c_edit::on_key_board_click));\n\t\t\t}\n\t\t\tm_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());\n\t\t\tm_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);\n\t\t\tstrlen(m_str_input) ? c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str_input, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER) :\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t}\n\t}\n\tvirtual void on_focus()\n\t{\n\t\tm_status = STATUS_FOCUSED;\n\t\ton_paint();\n\t}\n\tvirtual void on_kill_focus()\n\t{\n\t\tm_status = STATUS_NORMAL;\n\t\ton_paint();\n\t}\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tswitch (key)\n\t\t{\n\t\tcase NAV_ENTER:\n\t\t\t(m_status == STATUS_PUSHED) ? s_keyboard.on_navigate(key) : (on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN), on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP));\n\t\t\treturn;\n\t\tcase NAV_BACKWARD:\n\t\tcase NAV_FORWARD:\n\t\t\treturn (m_status == STATUS_PUSHED) ? s_keyboard.on_navigate(key) : c_wnd::on_navigate(key);\n\t\t}\n\t}\n\tvirtual void on_touch(int x, int y, TOUCH_ACTION action)\n\t{\n\t\t(action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y);\n\t}\t\n\tvoid on_key_board_click(int id, int param)\n\t{\n\t\tswitch (param)\n\t\t{\n\t\tcase CLICK_CHAR:\n\t\t\tstrcpy(m_str_input, s_keyboard.get_str());\n\t\t\ton_paint();\n\t\t\tbreak;\n\t\tcase CLICK_ENTER:\n\t\t\tif (strlen(m_str_input))\n\t\t\t{\n\t\t\t\tmemcpy(m_str, m_str_input, sizeof(m_str_input));\n\t\t\t}\n\t\t\tm_status = STATUS_FOCUSED;\n\t\t\ton_paint();\n\t\t\tbreak;\n\t\tcase CLICK_ESC:\n\t\t\tmemset(m_str_input, 0, sizeof(m_str_input));\n\t\t\tm_status = STATUS_FOCUSED;\n\t\t\ton_paint();\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t}\nprivate:\n\tvoid on_touch_down(int x, int y)\n\t{\n\t\tc_rect kb_rect_relate_2_edit_parent;\n\t\ts_keyboard.get_wnd_rect(kb_rect_relate_2_edit_parent);\n\t\tkb_rect_relate_2_edit_parent.m_left += m_wnd_rect.m_left;\n\t\tkb_rect_relate_2_edit_parent.m_right += m_wnd_rect.m_left;\n\t\tkb_rect_relate_2_edit_parent.m_top += m_wnd_rect.m_top;\n\t\tkb_rect_relate_2_edit_parent.m_bottom += m_wnd_rect.m_top;\n\t\tif (m_wnd_rect.pt_in_rect(x, y))\n\t\t{//click edit box\n\t\t\tif (STATUS_NORMAL == m_status)\n\t\t\t{\n\t\t\t\tm_parent->set_child_focus(this);\n\t\t\t}\n\t\t}\n\t\telse if (kb_rect_relate_2_edit_parent.pt_in_rect(x, y))\n\t\t{//click key board\n\t\t\tc_wnd::on_touch(x, y, TOUCH_DOWN);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (STATUS_PUSHED == m_status)\n\t\t\t{\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\ton_paint();\n\t\t\t}\n\t\t}\n\t}\n\tvoid on_touch_up(int x, int y)\n\t{\n\t\tif (STATUS_FOCUSED == m_status)\n\t\t{\n\t\t\tm_status = STATUS_PUSHED;\n\t\t\ton_paint();\n\t\t}\n\t\telse if (STATUS_PUSHED == m_status)\n\t\t{\n\t\t\tif (m_wnd_rect.pt_in_rect(x, y))\n\t\t\t{//click edit box\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\ton_paint();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tc_wnd::on_touch(x, y, TOUCH_UP);\n\t\t\t}\n\t\t}\n\t}\n\tstatic c_keyboard  s_keyboard;\n\tKEYBOARD_STYLE m_kb_style;\n\tchar m_str_input[MAX_EDIT_STRLEN];\n\tchar m_str[MAX_EDIT_STRLEN];\n};\nclass c_label : public c_wnd\n{\npublic:\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tunsigned int bg_color = m_bg_color ? m_bg_color : m_parent->get_bg_color();\n\t\tget_screen_rect(rect);\n\t\tif (m_str)\n\t\t{\n\t\t\tm_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, bg_color, m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, bg_color, ALIGN_LEFT | ALIGN_VCENTER);\n\t\t}\n\t}\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = ATTR_VISIBLE;\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t}\n};\n#include <string.h>\n#define MAX_ITEM_NUM\t\t\t4\n#define ITEM_HEIGHT\t\t\t\t45\nclass c_list_box : public c_wnd\n{\npublic:\n\tvoid set_on_change(WND_CALLBACK on_change) { this->on_change = on_change; }\n\tshort get_item_count() { return m_item_total; }\n\tint add_item(char* str)\n\t{\n\t\tif (m_item_total >= MAX_ITEM_NUM)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\tm_item_array[m_item_total++] = str;\n\t\tupdate_list_size();\n\t\treturn 0;\n\t}\n\tvoid clear_item()\n\t{\n\t\tm_selected_item = m_item_total = 0;\n\t\tmemset(m_item_array, 0, sizeof(m_item_array));\n\t\tupdate_list_size();\n\t}\n\tvoid  select_item(short index)\n\t{\n\t\tif (index < 0 || index >= m_item_total)\n\t\t{\n\t\t\tASSERT(false);\n\t\t}\n\t\tm_selected_item = index;\n\t}\n\t\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\tmemset(m_item_array, 0, sizeof(m_item_array));\n\t\tm_item_total = 0;\n\t\tm_selected_item = 0;\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tswitch (m_status)\n\t\t{\n\t\tcase STATUS_NORMAL:\n\t\t\tif (m_z_order > m_parent->get_z_order())\n\t\t\t{\n\t\t\t\tm_surface->activate_layer(c_rect(), m_z_order);//inactivate the layer of list by empty rect.\n\t\t\t\tm_z_order = m_parent->get_z_order();\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\t\t}\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tcase STATUS_FOCUSED:\n\t\t\tif (m_z_order > m_parent->get_z_order())\n\t\t\t{\n\t\t\t\tm_surface->activate_layer(c_rect(), m_z_order);//inactivate the layer of list by empty rect.\n\t\t\t\tm_z_order = m_parent->get_z_order();\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\t\t}\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tcase STATUS_PUSHED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);\n\t\t\tm_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, GL_RGB(2, 124, 165), GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t//draw list\n\t\t\tif (m_item_total > 0)\n\t\t\t{\n\t\t\t\tif (m_z_order == m_parent->get_z_order())\n\t\t\t\t{\n\t\t\t\t\tm_z_order++;\n\t\t\t\t\tm_surface->activate_layer(m_list_screen_rect, m_z_order);\n\t\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY);\n\t\t\t\t}\n\t\t\t\tshow_list();\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t}\n\t}\n\tvirtual void on_focus()\n\t{\n\t\tm_status = STATUS_FOCUSED;\n\t\ton_paint();\n\t}\n\tvirtual void on_kill_focus()\n\t{\n\t\tm_status = STATUS_NORMAL;\n\t\ton_paint();\n\t}\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tswitch (key)\n\t\t{\n\t\tcase NAV_ENTER:\n\t\t\tif (STATUS_PUSHED == m_status)\n\t\t\t{\n\t\t\t\tif(on_change)\n\t\t\t\t{\n\t\t\t\t\t(m_parent->*(on_change))(m_id, m_selected_item);\n\t\t\t\t}\n\t\t\t}\n\t\t\ton_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN);\n\t\t\ton_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP);\n\t\t\treturn;\n\t\tcase NAV_BACKWARD:\n\t\t\tif (m_status != STATUS_PUSHED)\n\t\t\t{\n\t\t\t\treturn c_wnd::on_navigate(key);\n\t\t\t}\n\t\t\tm_selected_item = (m_selected_item > 0) ? (m_selected_item - 1) : m_selected_item;\n\t\t\treturn show_list();\n\t\tcase NAV_FORWARD:\n\t\t\tif (m_status != STATUS_PUSHED)\n\t\t\t{\n\t\t\t\treturn c_wnd::on_navigate(key);\n\t\t\t}\n\t\t\tm_selected_item = (m_selected_item < (m_item_total - 1)) ? (m_selected_item + 1) : m_selected_item;\n\t\t\treturn show_list();\n\t\t}\n\t}\n\tvirtual void on_touch(int x, int y, TOUCH_ACTION action)\n\t{\n\t\t(action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y);\n\t}\n\t\nprivate:\n\tvoid update_list_size()\n\t{\n\t\tm_list_wnd_rect = m_wnd_rect;\n\t\tm_list_wnd_rect.m_top = m_wnd_rect.m_bottom + 1;\n\t\tm_list_wnd_rect.m_bottom = m_list_wnd_rect.m_top + m_item_total * ITEM_HEIGHT;\n\t\tget_screen_rect(m_list_screen_rect);\n\t\tm_list_screen_rect.m_top = m_list_screen_rect.m_bottom + 1;\n\t\tm_list_screen_rect.m_bottom = m_list_screen_rect.m_top + m_item_total * ITEM_HEIGHT;\n\t}\n\tvoid show_list()\n\t{\n\t\t//draw all items\n\t\tc_rect tmp_rect;\n\t\tfor (int i = 0; i < m_item_total; i++)\n\t\t{\n\t\t\ttmp_rect.m_left = m_list_screen_rect.m_left;\n\t\t\ttmp_rect.m_right = m_list_screen_rect.m_right;\n\t\t\ttmp_rect.m_top = m_list_screen_rect.m_top + i * ITEM_HEIGHT;\n\t\t\ttmp_rect.m_bottom = tmp_rect.m_top + ITEM_HEIGHT;\n\t\t\tif (m_selected_item == i)\n\t\t\t{\n\t\t\t\tm_surface->fill_rect(tmp_rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_surface->fill_rect(tmp_rect, GL_RGB(17, 17, 17), m_z_order);\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font, m_font_color, GL_RGB(17, 17, 17), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t}\n\t}\n\tvoid on_touch_down(int x, int y)\n\t{\n\t\tif (m_wnd_rect.pt_in_rect(x, y))\n\t\t{//click base\n\t\t\tif (STATUS_NORMAL == m_status)\n\t\t\t{\n\t\t\t\tm_parent->set_child_focus(this);\n\t\t\t}\n\t\t}\n\t\telse if (m_list_wnd_rect.pt_in_rect(x, y))\n\t\t{//click extend list\n\t\t\tc_wnd::on_touch(x, y, TOUCH_DOWN);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (STATUS_PUSHED == m_status)\n\t\t\t{\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\ton_paint();\n\t\t\t\tif(on_change)\n\t\t\t\t{\n\t\t\t\t\t(m_parent->*(on_change))(m_id, m_selected_item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvoid on_touch_up(int x, int y)\n\t{\n\t\tif (STATUS_FOCUSED == m_status)\n\t\t{\n\t\t\tm_status = STATUS_PUSHED;\n\t\t\ton_paint();\n\t\t}\n\t\telse if (STATUS_PUSHED == m_status)\n\t\t{\n\t\t\tif (m_wnd_rect.pt_in_rect(x, y))\n\t\t\t{//click base\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\ton_paint();\n\t\t\t}\n\t\t\telse if (m_list_wnd_rect.pt_in_rect(x, y))\n\t\t\t{//click extend list\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\tselect_item((y - m_list_wnd_rect.m_top) / ITEM_HEIGHT);\n\t\t\t\ton_paint();\n\t\t\t\tif(on_change)\n\t\t\t\t{\n\t\t\t\t\t(m_parent->*(on_change))(m_id, m_selected_item);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tc_wnd::on_touch(x, y, TOUCH_UP);\n\t\t\t}\n\t\t}\n\t}\n\tshort\t\t\tm_selected_item;\n\tshort\t\t\tm_item_total;\n\tchar*\t\t\tm_item_array[MAX_ITEM_NUM];\n\tc_rect\t\t\tm_list_wnd_rect;\t//rect relative to parent wnd.\n\tc_rect\t\t\tm_list_screen_rect;\t//rect relative to physical screen(frame buffer)\n\tWND_CALLBACK \ton_change;\n};\n#include <stdlib.h>\n#define MAX_PAGES\t5\nclass c_gesture;\nclass c_slide_group : public c_wnd {\npublic:\n\tinline c_slide_group();\n\tint set_active_slide(int index, bool is_redraw = true)\n\t{\n\t\tif (index >= MAX_PAGES || index < 0)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tif (0 == m_slides[index])\n\t\t{\n\t\t\treturn -2;\n\t\t}\n\t\tm_active_slide_index = index;\n\t\tfor (int i = 0; i < MAX_PAGES; i++)\n\t\t{\n\t\t\tif (m_slides[i] == 0)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (i == index)\n\t\t\t{\n\t\t\t\tm_slides[i]->get_surface()->set_active(true);\n\t\t\t\tadd_child_2_tail(m_slides[i]);\n\t\t\t\tif (is_redraw)\n\t\t\t\t{\n\t\t\t\t\tc_rect rc;\n\t\t\t\t\tget_screen_rect(rc);\n\t\t\t\t\tm_slides[i]->get_surface()->flush_screen(rc.m_left, rc.m_top, rc.m_right, rc.m_bottom);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_slides[i]->get_surface()->set_active(false);\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tc_wnd* get_slide(int index){return m_slides[index];}\n\tc_wnd* get_active_slide(){return m_slides[m_active_slide_index];}\n\tint get_active_slide_index(){return m_active_slide_index;}\n\tint 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)\n\t{\n\t\tif (0 == slide)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tc_surface* old_surface = get_surface();\n\t\tc_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder);\n\t\tnew_surface->set_active(false);\n\t\tset_surface(new_surface);\n\t\tslide->connect(this, resource_id, 0, x, y, width, height, p_child_tree);\n\t\tset_surface(old_surface);\n\t\tint i = 0;\n\t\twhile (i < MAX_PAGES)\n\t\t{\n\t\t\tif (m_slides[i] == slide)\n\t\t\t{//slide has lived\n\t\t\t\tASSERT(false);\n\t\t\t\treturn -2;\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\t\t//new slide\n\t\ti = 0;\n\t\twhile (i < MAX_PAGES)\n\t\t{\n\t\t\tif (m_slides[i] == 0)\n\t\t\t{\n\t\t\t\tm_slides[i] = slide;\n\t\t\t\tslide->show_window();\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\t\t//no more slide can be add\n\t\tASSERT(false);\n\t\treturn -3;\n\t}\n\tvoid disabel_all_slide()\n\t{\n\t\tfor (int i = 0; i < MAX_PAGES; i++)\n\t\t{\n\t\t\tif (m_slides[i])\n\t\t\t{\n\t\t\t\tm_slides[i]->get_surface()->set_active(false);\n\t\t\t}\n\t\t}\n\t}\n\tinline virtual void on_touch(int x, int y, TOUCH_ACTION action);\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tif (m_slides[m_active_slide_index])\n\t\t{\n\t\t\tm_slides[m_active_slide_index]->on_navigate(key);\n\t\t}\n\t}\nprotected:\n\tc_wnd* m_slides[MAX_PAGES];\n\tint m_active_slide_index;\n\tc_gesture* m_gesture;\n};\n//#define SWIPE_STEP\t\t\t300//for arm\n#define SWIPE_STEP\t\t\t10//for PC & ANDROID\n#define MOVE_THRESHOLD\t\t10\ntypedef enum {\n\tTOUCH_MOVE,\n\tTOUCH_IDLE\n}TOUCH_STATE;\nclass c_slide_group;\nclass c_gesture {\npublic:\n\tc_gesture(c_slide_group* group)\n\t{\n\t\tm_slide_group = group;\n\t\tm_state = TOUCH_IDLE;\n\t\tm_down_x = m_down_y = m_move_x = m_move_y = 0;\n\t}\n\tbool handle_swipe(int x, int y, TOUCH_ACTION action)\n\t{\n\t\tif (action == TOUCH_DOWN)//MOUSE_LBUTTONDOWN\n\t\t{\n\t\t\tif (m_state == TOUCH_IDLE)\n\t\t\t{\n\t\t\t\tm_state = TOUCH_MOVE;\n\t\t\t\tm_move_x = m_down_x = x;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse//TOUCH_MOVE\n\t\t\t{\n\t\t\t\treturn on_move(x);\n\t\t\t}\n\t\t}\n\t\telse if (action == TOUCH_UP)//MOUSE_LBUTTONUP\n\t\t{\n\t\t\tif (m_state == TOUCH_MOVE)\n\t\t\t{\n\t\t\t\tm_state = TOUCH_IDLE;\n\t\t\t\treturn on_swipe(x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t\t//ASSERT(false);\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\nprivate:\n\tbool on_move(int x)\n\t{\n\t\tif (m_slide_group == 0)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif (abs(x - m_move_x) < MOVE_THRESHOLD)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\tm_slide_group->disabel_all_slide();\n\t\tm_move_x = x;\n\t\tif ((m_move_x - m_down_x) > 0)\n\t\t{\n\t\t\tmove_right();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmove_left();\n\t\t}\n\t\treturn false;\n\t}\n\tbool on_swipe(int x)\n\t{\n\t\tif (m_slide_group == 0)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif ((m_down_x == m_move_x) && (abs(x - m_down_x) < MOVE_THRESHOLD))\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tm_slide_group->disabel_all_slide();\n\t\tint page = -1;\n\t\tm_move_x = x;\n\t\tif ((m_move_x - m_down_x) > 0)\n\t\t{\n\t\t\tpage = swipe_right();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tpage = swipe_left();\n\t\t}\n\t\tif (page >= 0)\n\t\t{\n\t\t\tm_slide_group->set_active_slide(page);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_slide_group->set_active_slide(m_slide_group->get_active_slide_index(), false);\n\t\t}\n\t\treturn false;\n\t}\n\tint swipe_left()\n\t{\n\t\tif (m_slide_group == 0)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tint index = m_slide_group->get_active_slide_index();\n\t\tif ((index + 1) >= MAX_PAGES ||\n\t\t\tm_slide_group->get_slide(index + 1) == 0 ||\n\t\t\tm_slide_group->get_slide(index) == 0)\n\t\t{\n\t\t\treturn -2;\n\t\t}\n\t\tc_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface();\n\t\tc_surface * s2 = m_slide_group->get_slide(index)->get_surface();\n\t\tif (s1->get_display() != s2->get_display())\n\t\t{\n\t\t\treturn -3;\n\t\t}\n\t\tint step = m_down_x - m_move_x;\n\t\tc_rect rc;\n\t\tm_slide_group->get_screen_rect(rc);\n\t\twhile (step < rc.width())\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step);\n\t\t\tstep += SWIPE_STEP;\n\t\t}\n\t\tif (step != rc.width())\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, rc.width());\n\t\t}\n\t\treturn (index + 1);\n\t}\n\tint swipe_right()\n\t{\n\t\tif (m_slide_group == 0)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tint index = m_slide_group->get_active_slide_index();\n\t\tif (index <= 0 ||\n\t\t\tm_slide_group->get_slide(index - 1) == 0 ||\n\t\t\tm_slide_group->get_slide(index) == 0)\n\t\t{\n\t\t\treturn -2;\n\t\t}\n\t\tc_surface* s1 = m_slide_group->get_slide(index - 1)->get_surface();\n\t\tc_surface * s2 = m_slide_group->get_slide(index)->get_surface();\n\t\tif (s1->get_display() != s2->get_display())\n\t\t{\n\t\t\treturn -3;\n\t\t}\n\t\tc_rect rc;\n\t\tm_slide_group->get_screen_rect(rc);\n\t\tint step = rc.width() - (m_move_x - m_down_x);\n\t\twhile (step > 0)\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step);\n\t\t\tstep -= SWIPE_STEP;\n\t\t}\n\t\tif (step != 0)\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, 0);\n\t\t}\n\t\treturn (index - 1);\n\t}\n\tvoid move_left()\n\t{\n\t\tint index = m_slide_group->get_active_slide_index();\n\t\tif ((index + 1) >= MAX_PAGES ||\n\t\t\tm_slide_group->get_slide(index + 1) == 0 ||\n\t\t\tm_slide_group->get_slide(index) == 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tc_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface();\n\t\tc_surface * s2 = m_slide_group->get_slide(index)->get_surface();\n\t\tc_rect rc;\n\t\tm_slide_group->get_screen_rect(rc);\n\t\tif (s1->get_display() == s2->get_display())\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (m_down_x - m_move_x));\n\t\t}\n\t}\n\tvoid move_right()\n\t{\n\t\tint index = m_slide_group->get_active_slide_index();\n\t\tif (index <= 0 ||\n\t\t\tm_slide_group->get_slide(index - 1) == 0 ||\n\t\t\tm_slide_group->get_slide(index) == 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tc_surface* s1 = m_slide_group->get_slide(index - 1)->get_surface();\n\t\tc_surface * s2 = m_slide_group->get_slide(index)->get_surface();\n\t\tc_rect rc;\n\t\tm_slide_group->get_screen_rect(rc);\n\t\tif (s1->get_display() == s2->get_display())\n\t\t{\n\t\t\ts1->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)));\n\t\t}\n\t}\n\tint m_down_x;\n\tint m_down_y;\n\tint m_move_x;\n\tint m_move_y;\n\tTOUCH_STATE m_state;\n\tc_slide_group* m_slide_group;\n};\ninline c_slide_group::c_slide_group()\n{\n\tm_gesture = new c_gesture(this);\n\tfor (int i = 0; i < MAX_PAGES; i++)\n\t{\n\t\tm_slides[i] = 0;\n\t}\n\tm_active_slide_index = 0;\n}\ninline void c_slide_group::on_touch(int x, int y, TOUCH_ACTION action)\n{\n\tx -= m_wnd_rect.m_left;\n\ty -= m_wnd_rect.m_top;\n\tif (m_gesture->handle_swipe(x, y, action))\n\t{\n\t\tif (m_slides[m_active_slide_index])\n\t\t{\n\t\t\tm_slides[m_active_slide_index]->on_touch(x, y, action);\n\t\t}\n\t}\n}\n#define ID_BT_ARROW_UP      \t0x1111\n#define ID_BT_ARROW_DOWN    \t0x2222\nclass c_spin_box;\nclass c_spin_button : public c_button\n{\n\tfriend class c_spin_box;\n\tinline virtual void on_touch(int x, int y, TOUCH_ACTION action);\n\tc_spin_box* m_spin_box;\n};\nclass c_spin_box : public c_wnd\n{\n\tfriend class c_spin_button;\npublic:\n\tshort get_value() { return m_value; }\n\tvoid set_value(unsigned short value) { m_value = m_cur_value = value; }\n\tvoid set_max_min(short max, short min) { m_max = max; m_min = min; }\n\tvoid set_step(short step) { m_step = step; }\n\tshort get_min() { return m_min; }\n\tshort get_max() { return m_max; }\n\tshort get_step() { return m_step; }\n\tvoid set_value_digit(short digit) { m_digit = digit; }\n\tshort get_value_digit() { return m_digit; }\n\tvoid set_on_change(WND_CALLBACK on_change) { this->on_change = on_change; }\nprotected:\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\trect.m_right = rect.m_left + (rect.width() * 2 / 3);\n\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\tc_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);\n\t}\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE);\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t\tm_max = 6;\n\t\tm_min = 1;\n\t\tm_digit = 0;\n\t\tm_step = 1;\n\t\t//link arrow button position.\n\t\tc_rect rect;\n\t\tget_wnd_rect(rect);\n\t\tm_bt_down.m_spin_box = m_bt_up.m_spin_box = this;\n\t\tm_bt_up.connect(m_parent, ID_BT_ARROW_UP, \"+\", (rect.m_left + rect.width() * 2 / 3), rect.m_top, (rect.width() / 3), (rect.height() / 2));\n\t\tm_bt_down.connect(m_parent, ID_BT_ARROW_DOWN, \"-\", (rect.m_left + rect.width() * 2 / 3), (rect.m_top + rect.height() / 2), (rect.width() / 3), (rect.height() / 2));\n\t}\n\tvoid on_arrow_up_bt_click()\n\t{\n\t\tif (m_cur_value + m_step > m_max)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tm_cur_value += m_step;\n\t\tif(on_change)\n\t\t{\n\t\t\t(m_parent->*(on_change))(m_id, m_cur_value);\n\t\t}\n\t\ton_paint();\n\t}\n\tvoid on_arrow_down_bt_click()\n\t{\n\t\tif (m_cur_value - m_step < m_min)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tm_cur_value -= m_step;\n\t\tif(on_change)\n\t\t{\n\t\t\t(m_parent->*(on_change))(m_id, m_cur_value);\n\t\t}\n\t\ton_paint();\n\t}\n\tshort\t\t\tm_cur_value;\n\tshort\t\t\tm_value;\n\tshort\t\t\tm_step;\n\tshort\t\t\tm_max;\n\tshort\t\t\tm_min;\n\tshort\t\t\tm_digit;\n\tc_spin_button  \tm_bt_up;\n\tc_spin_button  \tm_bt_down;\n\tWND_CALLBACK \ton_change;\n};\ninline void c_spin_button::on_touch(int x, int y, TOUCH_ACTION action)\n{\n\tif (action == TOUCH_UP)\n\t{\n\t\t(m_id == ID_BT_ARROW_UP) ? m_spin_box->on_arrow_up_bt_click() : m_spin_box->on_arrow_down_bt_click();\n\t}\n\tc_button::on_touch(x, y, action);\n}\n#define  MAX_COL_NUM  30\n#define  MAX_ROW_NUM  30\nclass c_table: public c_wnd\n{\npublic:\n\tvoid set_sheet_align(unsigned int align_type){ m_align_type = align_type;}\n\tvoid set_row_num(unsigned int row_num){ m_row_num = row_num;}\n\tvoid set_col_num(unsigned int col_num){ m_col_num = col_num;}\n\tvoid set_row_height(unsigned int height)\n\t{\n\t\tfor (unsigned int i = 0; i < m_row_num; i++)\n\t\t{\n\t\t\tm_row_height[i] = height;\n\t\t}\n\t}\n\tvoid set_col_width(unsigned int width)\n\t{\n\t\tfor (unsigned int i = 0; i < m_col_num; i++)\n\t\t{\n\t\t\tm_col_width[i] = width;\n\t\t}\n\t}\n\tint set_row_height(unsigned int index, unsigned int height)\n\t{\n\t\tif (m_row_num > index)\n\t\t{\n\t\t\tm_row_height[index] = height;\n\t\t\treturn index;\n\t\t}\n\t\treturn -1;\n\t}\n\tint set_col_width(unsigned int index, unsigned int width)\n\t{\n\t\tif (m_col_num > index)\n\t\t{\n\t\t\tm_col_width[index] = width;\n\t\t\treturn index;\n\t\t}\n\t\treturn -1;\n\t}\n\tvoid set_item(int row, int col, char* str, unsigned int color)\n\t{\n\t\tdraw_item(row, col, str, color);\n\t}\n\tunsigned int get_row_num(){ return m_row_num;}\n\tunsigned int get_col_num(){ return m_col_num;}\n\tc_rect get_item_rect(int row, int col)\n\t{\n\t\tstatic c_rect rect;\n\t\tif (row >= MAX_ROW_NUM || col >= MAX_COL_NUM)\n\t\t{\n\t\t\treturn rect;\n\t\t}\n\t\tunsigned int width = 0;\n\t\tunsigned int height = 0;\n\t\tfor (int i = 0; i < col; i++)\n\t\t{\n\t\t\twidth += m_col_width[i];\n\t\t}\n\t\tfor (int j = 0; j < row; j++)\n\t\t{\n\t\t\theight += m_row_height[j];\n\t\t}\n\t\tc_rect wRect;\n\t\tget_screen_rect(wRect);\n\t\trect.m_left = wRect.m_left + width;\n\t\trect.m_right = rect.m_left + m_col_width[col];\n\t\tif (rect.m_right > wRect.m_right)\n\t\t{\n\t\t\trect.m_right = wRect.m_right;\n\t\t}\n\t\trect.m_top = wRect.m_top + height;\n\t\trect.m_bottom = rect.m_top + m_row_height[row];\n\t\tif (rect.m_bottom > wRect.m_bottom)\n\t\t{\n\t\t\trect.m_bottom = wRect.m_bottom;\n\t\t}\n\t\treturn rect;\n\t}\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE);\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t}\n\tvoid draw_item(int row, int col, const char* str, unsigned int color)\n\t{\n\t\tc_rect rect = get_item_rect(row, col);\n\t\tm_surface->fill_rect(rect.m_left + 1, rect.m_top + 1, rect.m_right - 1, rect.m_bottom - 1, color, m_z_order);\n\t\tc_word::draw_string_in_rect(m_surface, m_z_order, str, rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_align_type);\n\t}\n\tunsigned int m_align_type;\t\n\tunsigned int m_row_num;\n\tunsigned int m_col_num;\n\tunsigned int m_row_height[MAX_ROW_NUM];\n\tunsigned int m_col_width[MAX_COL_NUM];\n};\n#include <string.h>\n#include <stdio.h>\n#define WAVE_BUFFER_LEN\t1024\n#define WAVE_READ_CACHE_LEN\t8\n#define BUFFER_EMPTY\t-1111\n#define BUFFER_FULL\t\t-2222;\nclass c_wave_buffer\n{\npublic:\n\tc_wave_buffer()\n\t{\n\t\tm_head = m_tail = m_min_old = m_max_old =\n\t\t\tm_min_older = m_max_older = m_last_data = m_read_cache_sum = m_refresh_sequence = 0;\n\t\tmemset(m_wave_buf, 0, sizeof(m_wave_buf));\n\t\tmemset(m_read_cache_min, 0, sizeof(m_read_cache_min));\n\t\tmemset(m_read_cache_mid, 0, sizeof(m_read_cache_mid));\n\t\tmemset(m_read_cache_max, 0, sizeof(m_read_cache_max));\n\t}\n\tint write_wave_data(short data)\n\t{\n\t\tif ((m_tail + 1) % WAVE_BUFFER_LEN == m_head)\n\t\t{//full\n\t\t\t//log_out(\"wave buf full\\n\");\n\t\t\treturn BUFFER_FULL;\n\t\t}\n\t\tm_wave_buf[m_tail] = data;\n\t\tm_tail = (m_tail + 1) % WAVE_BUFFER_LEN;\n\t\treturn 1;\n\t}\n\tint read_wave_data_by_frame(short &max, short &min, short frame_len, unsigned int sequence, short offset)\n\t{\n\t\tif (m_refresh_sequence != sequence)\n\t\t{\n\t\t\tm_refresh_sequence = sequence;\n\t\t\tm_read_cache_sum = 0;\n\t\t}\n\t\telse if (offset < m_read_cache_sum)//(m_refresh_sequence == sequence && offset < m_fb_sum)\n\t\t{\n\t\t\tmax = m_read_cache_max[offset];\n\t\t\tmin = m_read_cache_min[offset];\n\t\t\treturn m_read_cache_mid[offset];\n\t\t}\n\t\tm_read_cache_sum++;\n\t\tASSERT(m_read_cache_sum <= WAVE_READ_CACHE_LEN);\n\t\tint i, data;\n\t\tint tmp_min = m_last_data;\n\t\tint tmp_max = m_last_data;\n\t\tint mid = (m_min_old + m_max_old) >> 1;\n\t\ti = 0;\n\t\twhile (i++ < frame_len)\n\t\t{\n\t\t\tdata = read_data();\n\t\t\tif (BUFFER_EMPTY == data)\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tm_last_data = data;\n\t\t\tif (data < tmp_min) { tmp_min = data; }\n\t\t\tif (data > tmp_max) { tmp_max = data; }\n\t\t}\n\t\tmin = m_read_cache_min[offset] = MIN(m_min_old, MIN(tmp_min, m_min_older));\n\t\tmax = m_read_cache_max[offset] = MAX(m_max_old, MAX(tmp_max, m_max_older));\n\t\tm_min_older = m_min_old;\n\t\tm_max_older = m_max_old;\n\t\tm_min_old = tmp_min;\n\t\tm_max_old = tmp_max;\n\t\treturn (m_read_cache_mid[offset] = mid);\n\t}\n\tvoid reset()\n\t{\n\t\tm_head = m_tail;\n\t}\n\tvoid clear_data()\n\t{\n\t\tm_head = m_tail = 0;\n\t\tmemset(m_wave_buf, 0, sizeof(m_wave_buf));\n\t}\n\tshort get_cnt()\n\t{\n\t\treturn (m_tail >= m_head) ? (m_tail - m_head) : (m_tail - m_head + WAVE_BUFFER_LEN);\n\t}\nprivate:\n\tint read_data()\n\t{\n\t\tif (m_head == m_tail)\n\t\t{//empty\n\t\t\t//log_out(\"wave buf empty\\n\");\n\t\t\treturn BUFFER_EMPTY;\n\t\t}\n\t\tint ret = m_wave_buf[m_head];\n\t\tm_head = (m_head + 1) % WAVE_BUFFER_LEN;\n\t\treturn ret;\n\t}\n\tshort m_wave_buf[WAVE_BUFFER_LEN];\n\tshort m_head;\n\tshort m_tail;\n\tint m_min_old;\n\tint m_max_old;\n\tint m_min_older;\n\tint m_max_older;\n\tint m_last_data;\n\tshort \tm_read_cache_min[WAVE_READ_CACHE_LEN];\n\tshort \tm_read_cache_mid[WAVE_READ_CACHE_LEN];\n\tshort \tm_read_cache_max[WAVE_READ_CACHE_LEN];\n\tshort\tm_read_cache_sum;\n\tunsigned int m_refresh_sequence;\n};\n#include <stdlib.h>\n#include <string.h>\n#define CORRECT(x, high_limit, low_limit)\t{\\\n\tx = (x > high_limit) ? high_limit : x;\\\n\tx = (x < low_limit) ? low_limit : x;\\\n}while(0)\n#define WAVE_CURSOR_WIDTH\t\t8\n#define\tWAVE_LINE_WIDTH\t\t\t1\n#define\tWAVE_MARGIN\t\t\t\t5\ntypedef enum\n{\n\tFILL_MODE,\n\tSCAN_MODE\n}E_WAVE_DRAW_MODE;\nclass c_wave_buffer;\nclass c_wave_ctrl : public c_wnd\n{\npublic:\n\tc_wave_ctrl()\n\t{\n\t\tm_wave = 0;\n\t\tm_bg_fb = 0;\n\t\tm_wave_name_font = m_wave_unit_font = 0;\n\t\tm_wave_name = m_wave_unit = 0;\n\t\tm_max_data = 500;\n\t\tm_min_data = 0;\n\t\tm_wave_speed = 1;\n\t\tm_wave_data_rate = 0;\n\t\tm_wave_refresh_rate = 1000;\n\t\tm_frame_len_map_index = 0;\n\t\tm_wave_name_color = m_wave_unit_color = m_wave_color = GL_RGB(255, 0, 0);\n\t\tm_back_color = GL_RGB(0, 0, 0);\n\t}\n\tvirtual void on_init_children()//should be pre_create\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tm_wave_left = rect.m_left + WAVE_MARGIN;\n\t\tm_wave_right = rect.m_right - WAVE_MARGIN;\n\t\tm_wave_top = rect.m_top + WAVE_MARGIN;\n\t\tm_wave_bottom = rect.m_bottom - WAVE_MARGIN;\n\t\tm_wave_cursor = m_wave_left;\n\t\tm_bg_fb = (unsigned int*)calloc(rect.width() * rect.height(), 4);\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tm_surface->fill_rect(rect, m_back_color, m_z_order);\n\t\t//show name\n\t\tc_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));\n\t\t//show unit\n\t\tc_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));\n\t\tsave_background();\n\t}\n\tvoid set_wave_name(char* wave_name){ m_wave_name = wave_name;}\n\tvoid set_wave_unit(char* wave_unit){ m_wave_unit = wave_unit;}\n\tvoid set_wave_name_font(const LATTICE_FONT_INFO* wave_name_font_type){ m_wave_name_font = wave_name_font_type;}\n\tvoid set_wave_unit_font(const LATTICE_FONT_INFO* wave_unit_font_type){ m_wave_unit_font = wave_unit_font_type;}\n\tvoid set_wave_name_color(unsigned int wave_name_color){ m_wave_name_color = wave_name_color;}\n\tvoid set_wave_unit_color(unsigned int wave_unit_color){ m_wave_unit_color = wave_unit_color;}\n\tvoid set_wave_color(unsigned int color){ m_wave_color = color;}\n\tvoid set_wave_in_out_rate(unsigned int data_rate, unsigned int refresh_rate)\n\t{\n\t\tm_wave_data_rate = data_rate;\n\t\tm_wave_refresh_rate = refresh_rate;\n\t\tint read_times_per_second = m_wave_speed * 1000 / m_wave_refresh_rate;\n\t\tmemset(m_frame_len_map, 0, sizeof(m_frame_len_map));\n\t\tfor (unsigned int i = 1; i < sizeof(m_frame_len_map) + 1; i++)\n\t\t{\n\t\t\tm_frame_len_map[i - 1] = data_rate * i / read_times_per_second - data_rate * (i - 1) / read_times_per_second;\n\t\t}\n\t\tm_frame_len_map_index = 0;\n\t}\n\tvoid set_wave_speed(unsigned int speed)\n\t{\n\t\tm_wave_speed = speed;\n\t\tset_wave_in_out_rate(m_wave_data_rate, m_wave_refresh_rate);\n\t}\n\tvoid set_max_min(short max_data, short min_data)\n\t{\n\t\tm_max_data = max_data;\n\t\tm_min_data = min_data;\n\t}\n\tvoid set_wave(c_wave_buffer* wave){m_wave = wave;}\n\tc_wave_buffer* get_wave(){return m_wave;}\n\tvoid clear_data()\n\t{\n\t\tif (m_wave == 0)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn;\n\t\t}\n\t\tm_wave->clear_data();\n\t}\n\tbool is_data_enough()\n\t{\n\t\tif (m_wave == 0)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn false;\n\t\t}\n\t\treturn (m_wave->get_cnt() - m_frame_len_map[m_frame_len_map_index] * m_wave_speed);\n\t}\n\tvoid refresh_wave(unsigned char frame)\n\t{\n\t\tif (m_wave == 0)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn;\n\t\t}\n\t\tshort max, min, mid;\n\t\tfor (short offset = 0; offset < m_wave_speed; offset++)\n\t\t{\n\t\t\t//get wave value\n\t\t\tmid = m_wave->read_wave_data_by_frame(max, min,\n\t\t\t\tm_frame_len_map[m_frame_len_map_index++],\n\t\t\t\tframe, offset);\n\t\t\tm_frame_len_map_index %= sizeof(m_frame_len_map);\n\t\t\t//map to wave ctrl\n\t\t\tint y_min, y_max;\n\t\t\tif (m_max_data == m_min_data)\n\t\t\t{\n\t\t\t\tASSERT(false);\n\t\t\t}\n\t\t\ty_max = m_wave_bottom + WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top) * (min - m_min_data) / (m_max_data - m_min_data);\n\t\t\ty_min = m_wave_bottom - WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top) * (max - m_min_data) / (m_max_data - m_min_data);\n\t\t\tmid = m_wave_bottom - (m_wave_bottom - m_wave_top) * (mid - m_min_data) / (m_max_data - m_min_data);\n\t\t\tCORRECT(y_min, m_wave_bottom, m_wave_top);\n\t\t\tCORRECT(y_max, m_wave_bottom, m_wave_top);\n\t\t\tCORRECT(mid, m_wave_bottom, m_wave_top);\n\t\t\tif (m_wave_cursor > m_wave_right)\n\t\t\t{\n\t\t\t\tm_wave_cursor = m_wave_left;\n\t\t\t}\n\t\t\tdraw_smooth_vline(y_min, y_max, mid, m_wave_color);\n\t\t\trestore_background();\n\t\t\tm_wave_cursor++;\n\t\t}\n\t}\n\tvoid clear_wave()\n\t{\n\t\tm_surface->fill_rect(m_wave_left, m_wave_top, m_wave_right, m_wave_bottom, m_back_color, m_z_order);\n\t\tm_wave_cursor = m_wave_left;\n\t}\t\nprotected:\n\tvoid draw_smooth_vline(int y_min, int y_max, int mid, unsigned int rgb)\n\t{\n\t\tint dy = y_max - y_min;\n\t\tshort r = GL_RGB_R(rgb);\n\t\tshort g = GL_RGB_G(rgb);\n\t\tshort b = GL_RGB_B(rgb);\n\t\tint  index = (dy >> 1) + 2;\n\t\tint  y;\n\t\tm_surface->draw_pixel(m_wave_cursor, mid, rgb, m_z_order);\n\t\tif (dy < 1)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tunsigned char cur_r, cur_g, cur_b;\n\t\tunsigned int cur_rgb;\n\t\tfor (int i = 1; i <= (dy >> 1) + 1; ++i)\n\t\t{\n\t\t\tif ((mid + i) <= y_max)\n\t\t\t{\n\t\t\t\ty = mid + i;\n\t\t\t\tcur_r = r * (index - i) / index;\n\t\t\t\tcur_g = g * (index - i) / index;\n\t\t\t\tcur_b = b * (index - i) / index;\n\t\t\t\tcur_rgb = GL_RGB(cur_r, cur_g, cur_b);\n\t\t\t\tm_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order);\n\t\t\t}\n\t\t\tif ((mid - i) >= y_min)\n\t\t\t{\n\t\t\t\ty = mid - i;\n\t\t\t\tcur_r = r * (index - i) / index;\n\t\t\t\tcur_g = g * (index - i) / index;\n\t\t\t\tcur_b = b * (index - i) / index;\n\t\t\t\tcur_rgb = GL_RGB(cur_r, cur_g, cur_b);\n\t\t\t\tm_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order);\n\t\t\t}\n\t\t}\n\t}\n\tvoid restore_background()\n\t{\n\t\tint  x = m_wave_cursor + WAVE_CURSOR_WIDTH;\n\t\tif (x > m_wave_right)\n\t\t{\n\t\t\tx -= (m_wave_right - m_wave_left + 1);\n\t\t}\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tint width = rect.width();\n\t\tint top = rect.m_top;\n\t\tint left = rect.m_left;\n\t\tfor (int y_pos = (m_wave_top - 1); y_pos <= (m_wave_bottom + 1); y_pos++)\n\t\t{\n\t\t\t(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);\n\t\t}\n\t}\n\tvoid save_background()\n\t{\n\t\tif (!m_bg_fb)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tunsigned int* p_des = m_bg_fb;\n\t\tfor (int y = rect.m_top; y <= rect.m_bottom; y++)\n\t\t{\n\t\t\tfor (int x = rect.m_left; x <= rect.m_right; x++)\n\t\t\t{\n\t\t\t\t*p_des++ = m_surface->get_pixel(x, y, m_z_order);\n\t\t\t}\n\t\t}\n\t}\n\tchar* m_wave_name;\n\tchar* m_wave_unit;\n\tconst LATTICE_FONT_INFO* m_wave_name_font;\n\tconst LATTICE_FONT_INFO* m_wave_unit_font;\n\tunsigned int m_wave_name_color;\n\tunsigned int m_wave_unit_color;\n\tunsigned int m_wave_color;\n\tunsigned int m_back_color;\n\tint m_wave_left;\n\tint m_wave_right;\n\tint m_wave_top;\n\tint m_wave_bottom;\n\tshort m_max_data;\n\tshort m_min_data;\n\t\nprivate:\n\tc_wave_buffer*\tm_wave;\n\tunsigned int*\tm_bg_fb;\t\t\t//background frame buffer, could be used to draw scale line.\n\tint \t\t\tm_wave_cursor;\n\tint \t\t\tm_wave_speed;\t\t//pixels per refresh\n\tunsigned int\tm_wave_data_rate;\t//data sample rate\n\tunsigned int\tm_wave_refresh_rate;//refresh cycle in millisecond\n\tunsigned char \tm_frame_len_map[64];\n\tunsigned char \tm_frame_len_map_index;\n};\n#ifdef GUILITE_ON\nc_bitmap_operator the_bitmap_op = c_bitmap_operator();\nc_image_operator* c_image::image_operator = &the_bitmap_op;\nconst void* c_theme::s_font_map[FONT_MAX];\nconst void* c_theme::s_image_map[IMAGE_MAX];\nunsigned int c_theme::s_color_map[COLOR_MAX];\nc_lattice_font_op the_lattice_font_op = c_lattice_font_op();\nc_font_operator* c_word::fontOperator = &the_lattice_font_op;\n#endif\n#ifdef GUILITE_ON\n#if ((defined __linux__) && (!defined __none_os__)) || (defined __APPLE__)\n#include <unistd.h>\n#include <pthread.h>\n#include <string.h>\n#include <time.h>\n#include <sys/time.h>\n#include <signal.h>\n#include <sys/times.h>\n#include <fcntl.h>\n#include <termios.h>\n#include <sys/stat.h>\n#include <semaphore.h>\n#include <errno.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#define MAX_TIMER_CNT 10\n#define TIMER_UNIT 50//ms\nstatic void(*do_assert)(const char* file, int line);\nstatic void(*do_log_out)(const char* log);\nvoid register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))\n{\n\tdo_assert = my_assert;\n\tdo_log_out = my_log_out;\n}\nvoid _assert(const char* file, int line)\n{\n\tif(do_assert)\n\t{\n\t\tdo_assert(file, line);\n\t}\n\telse\n\t{\n\t\tprintf(\"assert@ file:%s, line:%d, error no: %d\\n\", file, line, errno);\n\t} \n}\nvoid log_out(const char* log)\n{\n\tif (do_log_out)\n\t{\n\t\tdo_log_out(log);\n\t}\n\telse\n\t{\n\t\tprintf(\"%s\", log);\n\t\tfflush(stdout);\n\t}\n}\ntypedef struct _timer_manage\n{\n    struct  _timer_info\n    {\n        int state; /* on or off */\n        int interval;\n        int elapse; /* 0~interval */\n        void (* timer_proc) (void* param);\n\t\tvoid* param;\n    }timer_info[MAX_TIMER_CNT];\n    void (* old_sigfunc)(int);\n    void (* new_sigfunc)(int);\n}_timer_manage_t;\nstatic struct _timer_manage timer_manage;\nstatic void* timer_routine(void*)\n{\n    int i;\n    while(true)\n    {\n    \tfor(i = 0; i < MAX_TIMER_CNT; i++)\n\t\t{\n\t\t\tif(timer_manage.timer_info[i].state == 0)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttimer_manage.timer_info[i].elapse++;\n\t\t\tif(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)\n\t\t\t{\n\t\t\t\ttimer_manage.timer_info[i].elapse = 0;\n\t\t\t\ttimer_manage.timer_info[i].timer_proc(timer_manage.timer_info[i].param);\n\t\t\t}\n\t\t}\n    \tusleep(1000 * TIMER_UNIT);\n    }\n    return NULL;\n}\nstatic int init_mul_timer()\n{\n\tstatic bool s_is_init = false;\n\tif(s_is_init == true)\n\t{\n\t\treturn 0;\n\t}\n    memset(&timer_manage, 0, sizeof(struct _timer_manage));\n    pthread_t pid;\n    pthread_create(&pid, NULL, timer_routine, NULL);\n    s_is_init = true;\n    return 1;\n}\nstatic int set_a_timer(int interval, void (* timer_proc)(void* param), void* param)\n{\n\tinit_mul_timer();\n\tint i;\n    if(timer_proc == NULL || interval <= 0)\n    {\n        return (-1);\n    }\n    for(i = 0; i < MAX_TIMER_CNT; i++)\n    {\n        if(timer_manage.timer_info[i].state == 1)\n        {\n            continue;\n        }\n        memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));\n        timer_manage.timer_info[i].timer_proc = timer_proc;\n\t\ttimer_manage.timer_info[i].param = param;\n        timer_manage.timer_info[i].interval = interval;\n        timer_manage.timer_info[i].elapse = 0;\n        timer_manage.timer_info[i].state = 1;\n        break;\n    }\n    if(i >= MAX_TIMER_CNT)\n    {\n    \tASSERT(false);\n        return (-1);\n    }\n    return (i);\n}\ntypedef void (*EXPIRE_ROUTINE)(void* arg);\nEXPIRE_ROUTINE s_expire_function;\nstatic c_fifo s_real_timer_fifo;\nstatic void* real_timer_routine(void*)\n{\n\tchar dummy;\n\twhile(1)\n\t{\n\t\tif(s_real_timer_fifo.read(&dummy, 1) > 0)\n\t\t{\n\t\t\tif(s_expire_function)s_expire_function(0);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tASSERT(false);\n\t\t}\n\t}\n\treturn 0;\n}\nstatic void expire_real_timer(int sigo)\n{\n\tchar dummy = 0x33;\n\tif(s_real_timer_fifo.write(&dummy, 1) <= 0)\n\t{\n\t\tASSERT(false);\n\t}\n}\nvoid start_real_timer(void (*func)(void* arg))\n{\n\tif(NULL == func)\n\t{\n\t\treturn;\n\t}\n\ts_expire_function = func;\n\tsignal(SIGALRM, expire_real_timer);\n\tstruct itimerval value, ovalue;\n\tvalue.it_value.tv_sec = 0;\n\tvalue.it_value.tv_usec = REAL_TIME_TASK_CYCLE_MS * 1000;\n\tvalue.it_interval.tv_sec = 0;\n\tvalue.it_interval.tv_usec = REAL_TIME_TASK_CYCLE_MS * 1000;\n\tsetitimer(ITIMER_REAL, &value, &ovalue);\n\tstatic pthread_t s_pid;\n\tif(s_pid == 0)\n\t{\n\t\tpthread_create(&s_pid, NULL, real_timer_routine, NULL);\n\t}\n}\nunsigned int get_cur_thread_id()\n{\n\treturn (unsigned long)pthread_self();\n}\nvoid register_timer(int milli_second,void func(void* param), void* param)\n{\n\tset_a_timer(milli_second/TIMER_UNIT,func, param);\n}\nlong get_time_in_second()\n{\n\treturn time(NULL);         /* + 8*60*60*/\n}\nT_TIME get_time()\n{\n\tT_TIME ret = {0};\n\tstruct tm *fmt;\n\ttime_t timer;\n\ttimer = get_time_in_second();\n\tfmt = localtime(&timer);\n\tret.year   = fmt->tm_year + 1900;\n\tret.month  = fmt->tm_mon + 1;\n\tret.day    = fmt->tm_mday;\n\tret.hour   = fmt->tm_hour;\n\tret.minute = fmt->tm_min;\n\tret.second = fmt->tm_sec;\n\treturn ret;\n}\nT_TIME second_to_day(long second)\n{\n\tT_TIME ret = {0};\n\tstruct tm *fmt;\n\tfmt = localtime(&second);\n\tret.year   = fmt->tm_year + 1900;\n\tret.month  = fmt->tm_mon + 1;\n\tret.day    = fmt->tm_mday;\n\tret.hour   = fmt->tm_hour;\n\tret.minute = fmt->tm_min;\n\tret.second = fmt->tm_sec;\n\treturn ret;\n}\nvoid create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)\n{\n    pthread_create((pthread_t*)thread_id, (pthread_attr_t const*)attr, start_routine, arg);\n}\nvoid thread_sleep(unsigned int milli_seconds)\n{\n\tusleep(milli_seconds * 1000);\n}\ntypedef struct {\n\tunsigned short\tbfType;\n\tunsigned int   \tbfSize;\n\tunsigned short  bfReserved1;\n\tunsigned short  bfReserved2;\n\tunsigned int   \tbfOffBits;\n}__attribute__((packed))FileHead;\ntypedef struct{\n\tunsigned int  \tbiSize;\n\tint \t\t\tbiWidth;\n\tint       \t\tbiHeight;\n\tunsigned short\tbiPlanes;\n\tunsigned short  biBitCount;\n\tunsigned int    biCompress;\n\tunsigned int    biSizeImage;\n\tint       \t\tbiXPelsPerMeter;\n\tint       \t\tbiYPelsPerMeter;\n\tunsigned int \tbiClrUsed;\n\tunsigned int    biClrImportant;\n\tunsigned int \tbiRedMask;\n\tunsigned int \tbiGreenMask;\n\tunsigned int \tbiBlueMask;\n}__attribute__((packed))Infohead;\nint build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)\n{\n\tFileHead bmp_head;\n\tInfohead bmp_info;\n\tint size = width * height * 2;\n\t//initialize bmp head.\n\tbmp_head.bfType = 0x4d42;\n\tbmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead);\n\tbmp_head.bfReserved1 = bmp_head.bfReserved2 = 0;\n\tbmp_head.bfOffBits = bmp_head.bfSize - size;\n\t//initialize bmp info.\n\tbmp_info.biSize = 40;\n\tbmp_info.biWidth = width;\n\tbmp_info.biHeight = height;\n\tbmp_info.biPlanes = 1;\n\tbmp_info.biBitCount = 16;\n\tbmp_info.biCompress = 3;\n\tbmp_info.biSizeImage = size;\n\tbmp_info.biXPelsPerMeter = 0;\n\tbmp_info.biYPelsPerMeter = 0;\n\tbmp_info.biClrUsed = 0;\n\tbmp_info.biClrImportant = 0;\n\t//RGB565\n\tbmp_info.biRedMask = 0xF800;\n\tbmp_info.biGreenMask = 0x07E0;\n\tbmp_info.biBlueMask = 0x001F;\n\t//copy the data\n\tFILE *fp;\n\tif(!(fp=fopen(filename,\"wb\")))\n\t{\n\t\treturn -1;\n\t}\n\tfwrite(&bmp_head, 1, sizeof(FileHead),fp);\n\tfwrite(&bmp_info, 1, sizeof(Infohead),fp);\n\t//fwrite(data, 1, size, fp);//top <-> bottom\n\tfor (int i = (height - 1); i >= 0; --i)\n\t{\n\t\tfwrite(&data[i * width * 2], 1, width * 2, fp);\n\t}\n\t\n\tfclose(fp);\n\treturn 0;\n}\nc_fifo::c_fifo()\n{\n\tm_head = m_tail = 0;\n\tm_read_sem = malloc(sizeof(sem_t));\n\tm_write_mutex = malloc(sizeof(pthread_mutex_t));\n\t\n\tsem_init((sem_t*)m_read_sem, 0, 0);\n\tpthread_mutex_init((pthread_mutex_t*)m_write_mutex, 0);\n}\nint c_fifo::read(void* buf, int len)\n{\n\tunsigned char* pbuf = (unsigned char*)buf;\n\tint i = 0;\n\twhile(i < len)\n\t{\n\t\tif (m_tail == m_head)\n\t\t{//empty\n\t\t\tsem_wait((sem_t*)m_read_sem);\n\t\t\tcontinue;\n\t\t}\n\t\t*pbuf++ = m_buf[m_head];\n\t\tm_head = (m_head + 1) % FIFO_BUFFER_LEN;\n\t\ti++;\n\t}\n\tif(i != len)\n\t{\n\t\tASSERT(false);\n\t}\n\treturn i;\n}\nint c_fifo::write(void* buf, int len)\n{\n\tunsigned char* pbuf = (unsigned char*)buf;\n\tint i = 0;\n\tint tail = m_tail;\n\tpthread_mutex_lock((pthread_mutex_t*)m_write_mutex);\n\twhile(i < len)\n\t{\n\t\tif ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)\n\t\t{//full, clear data has been written;\n\t\t\tm_tail = tail;\n\t\t\tlog_out(\"Warning: fifo full\\n\");\n\t\t\tpthread_mutex_unlock((pthread_mutex_t*)m_write_mutex);\n\t\t\treturn 0;\n\t\t}\n\t\tm_buf[m_tail] = *pbuf++;\n\t\tm_tail = (m_tail + 1) % FIFO_BUFFER_LEN;\n\t\ti++;\n\t}\n\tpthread_mutex_unlock((pthread_mutex_t*)m_write_mutex);\n\tif(i != len)\n\t{\n\t\tASSERT(false);\n\t}\n\telse\n\t{\n\t\tsem_post((sem_t*)m_read_sem);\n\t}\n\treturn i;\n}\n#endif\n#endif\n#ifdef GUILITE_ON\r\n#if (defined __none_os__) || ((!defined _WIN32) && (!defined WIN32) && (!defined _WIN64) && (!defined WIN64) && (!defined __linux__) && (!defined __APPLE__))\r\n\r\n#include <stdio.h>\r\n\r\nstatic void(*do_assert)(const char* file, int line);\r\nstatic void(*do_log_out)(const char* log);\r\nvoid register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))\r\n{\r\n\tdo_assert = my_assert;\r\n\tdo_log_out = my_log_out;\r\n}\r\n\r\nvoid _assert(const char* file, int line)\r\n{\r\n\tif(do_assert)\r\n\t{\r\n\t\tdo_assert(file, line);\r\n\t}\r\n\twhile(1);\r\n}\r\n\r\nvoid log_out(const char* log)\r\n{\r\n\tif (do_log_out)\r\n\t{\r\n\t\tdo_log_out(log);\r\n\t}\r\n}\r\n\r\nlong get_time_in_second()\r\n{\r\n    return 0;\r\n}\r\n\r\nT_TIME second_to_day(long second)\r\n{\r\n    T_TIME ret = {0};\r\n    return ret;\r\n}\r\n\r\nT_TIME get_time()\r\n{\r\n    T_TIME ret = {0};\r\n    return ret;\r\n}\r\n\r\nvoid start_real_timer(void (*func)(void* arg))\r\n{\r\n    log_out(\"Not support now\");\r\n}\r\n\r\nvoid register_timer(int milli_second, void func(void* ptmr, void* parg))\r\n{\r\n    log_out(\"Not support now\");\r\n}\r\n\r\nunsigned int get_cur_thread_id()\r\n{\r\n    log_out(\"Not support now\");\r\n    return 0;\r\n}\r\n\r\nvoid create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)\r\n{\r\n    log_out(\"Not support now\");\r\n}\r\n\r\nextern \"C\" void delay_ms(unsigned short nms);\r\nvoid thread_sleep(unsigned int milli_seconds)\r\n{//MCU alway implemnet driver code in APP.\r\n\t\tdelay_ms(milli_seconds);\r\n}\r\n\r\nint build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)\r\n{\r\n    log_out(\"Not support now\");\r\n    return 0;\r\n}\r\n\r\nc_fifo::c_fifo()\r\n{\r\n\tm_head = m_tail = 0;\r\n\tm_read_sem = m_write_mutex = 0;\r\n}\r\n\r\nint c_fifo::read(void* buf, int len)\r\n{\r\n\tunsigned char* pbuf = (unsigned char*)buf;\r\n\tint i = 0;\r\n\twhile(i < len)\r\n\t{\r\n\t\tif (m_tail == m_head)\r\n\t\t{//empty\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\t*pbuf++ = m_buf[m_head];\r\n\t\tm_head = (m_head + 1) % FIFO_BUFFER_LEN;\r\n\t\ti++;\r\n\t}\r\n\tif(i != len)\r\n\t{\r\n\t\tASSERT(false);\r\n\t}\r\n\treturn i;\r\n}\r\n\r\nint c_fifo::write(void* buf, int len)\r\n{\r\n\tunsigned char* pbuf = (unsigned char*)buf;\r\n\tint i = 0;\r\n\tint tail = m_tail;\r\n\r\n\twhile(i < len)\r\n\t{\r\n\t\tif ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)\r\n\t\t{//full, clear data has been written;\r\n\t\t\tm_tail = tail;\r\n\t\t\tlog_out(\"Warning: fifo full\\n\");\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\tm_buf[m_tail] = *pbuf++;\r\n\t\tm_tail = (m_tail + 1) % FIFO_BUFFER_LEN;\r\n\t\ti++;\r\n\t}\r\n\r\n\tif(i != len)\r\n\t{\r\n\t\tASSERT(false);\r\n\t}\r\n\treturn i;\r\n}\r\n\r\n#endif\r\n#endif\r\n#ifdef GUILITE_ON\n#if (defined _WIN32) || (defined WIN32) || (defined _WIN64) || (defined WIN64)\n#include <string.h>\n#include <stdio.h>\n#include <time.h>\n#include <conio.h>\n#include <windows.h>\n#include <assert.h>\n#define MAX_TIMER_CNT 10\n#define TIMER_UNIT 50//ms\nstatic void(*do_assert)(const char* file, int line);\nstatic void(*do_log_out)(const char* log);\nvoid register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))\n{\n\tdo_assert = my_assert;\n\tdo_log_out = my_log_out;\n}\nvoid _assert(const char* file, int line)\n{\n\tstatic char s_buf[192];\n\tif (do_assert) \n\t{\n\t\tdo_assert(file, line);\n\t}\n\telse\n\t{\n\t\tmemset(s_buf, 0, sizeof(s_buf));\n\t\tsprintf_s(s_buf, sizeof(s_buf), \"vvvvvvvvvvvvvvvvvvvvvvvvvvvv\\n\\nAssert@ file = %s, line = %d\\n\\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n\", file, line);\n\t\tOutputDebugStringA(s_buf);\n\t\tprintf(\"%s\", s_buf);\n\t\tfflush(stdout);\n\t\tassert(false);\n\t}\n}\nvoid log_out(const char* log)\n{\n\tif (do_log_out)\n\t{\n\t\tdo_log_out(log);\n\t}\n\telse\n\t{\n\t\tprintf(\"%s\", log);\n\t\tfflush(stdout);\n\t\tOutputDebugStringA(log);\n\t}\n}\ntypedef struct _timer_manage\n{\n    struct  _timer_info\n    {\n        int state; /* on or off */\n        int interval;\n        int elapse; /* 0~interval */\n        void (* timer_proc) (void* param);\n\t\tvoid* param;\n    }timer_info[MAX_TIMER_CNT];\n    void (* old_sigfunc)(int);\n    void (* new_sigfunc)(int);\n}_timer_manage_t;\nstatic struct _timer_manage timer_manage;\nDWORD WINAPI timer_routine(LPVOID lpParam)\n{\n    int i;\n    while(true)\n    {\n    \tfor(i = 0; i < MAX_TIMER_CNT; i++)\n\t\t{\n\t\t\tif(timer_manage.timer_info[i].state == 0)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttimer_manage.timer_info[i].elapse++;\n\t\t\tif(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)\n\t\t\t{\n\t\t\t\ttimer_manage.timer_info[i].elapse = 0;\n\t\t\t\ttimer_manage.timer_info[i].timer_proc(timer_manage.timer_info[i].param);\n\t\t\t}\n\t\t}\n\t\tSleep(TIMER_UNIT);\n    }\n    return 0;\n}\nstatic int init_mul_timer()\n{\n\tstatic bool s_is_init = false;\n\tif(s_is_init == true)\n\t{\n\t\treturn 0;\n\t}\n    memset(&timer_manage, 0, sizeof(struct _timer_manage));\n    DWORD pid;\n\tCreateThread(0, 0, timer_routine, 0, 0, &pid);\n    s_is_init = true;\n    return 1;\n}\nstatic int set_a_timer(int interval, void (* timer_proc) (void* param), void* param)\n{\n\tinit_mul_timer();\n\tint i;\n    if(timer_proc == 0 || interval <= 0)\n    {\n        return (-1);\n    }\n    for(i = 0; i < MAX_TIMER_CNT; i++)\n    {\n        if(timer_manage.timer_info[i].state == 1)\n        {\n            continue;\n        }\n        memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));\n        timer_manage.timer_info[i].timer_proc = timer_proc;\n\t\ttimer_manage.timer_info[i].param = param;\n        timer_manage.timer_info[i].interval = interval;\n        timer_manage.timer_info[i].elapse = 0;\n        timer_manage.timer_info[i].state = 1;\n        break;\n    }\n    if(i >= MAX_TIMER_CNT)\n    {\n\t\tASSERT(false);\n        return (-1);\n    }\n    return (i);\n}\ntypedef void (*EXPIRE_ROUTINE)(void* arg);\nEXPIRE_ROUTINE s_expire_function;\nstatic c_fifo s_real_timer_fifo;\nstatic DWORD WINAPI fire_real_timer(LPVOID lpParam)\n{\n\tchar dummy;\n\twhile(1)\n\t{\n\t\tif(s_real_timer_fifo.read(&dummy, 1) > 0)\n\t\t{\n\t\t\tif(s_expire_function)s_expire_function(0);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tASSERT(false);\n\t\t}\n\t}\n\treturn 0;\n}\n/*Win32 desktop only\nstatic void CALLBACK trigger_real_timer(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR)\n{\n\tchar dummy = 0x33;\n\ts_real_timer_fifo.write(&dummy, 1);\n}\n*/\nstatic DWORD WINAPI trigger_real_timer(LPVOID lpParam)\n{\n\tchar dummy = 0x33;\n\twhile (1)\n\t{\n\t\ts_real_timer_fifo.write(&dummy, 1);\n\t\tSleep(REAL_TIME_TASK_CYCLE_MS);\n\t}\n\treturn 0;\n}\nvoid start_real_timer(void (*func)(void* arg))\n{\n\tif(0 == func)\n\t{\n\t\treturn;\n\t}\n\ts_expire_function = func;\n\t//timeSetEvent(REAL_TIME_TASK_CYCLE_MS, 0, trigger_real_timer, 0, TIME_PERIODIC);//Win32 desktop only\n\tstatic DWORD s_pid;\n\tif(s_pid == 0)\n\t{\n\t\tCreateThread(0, 0, trigger_real_timer, 0, 0, &s_pid);\n\t\tCreateThread(0, 0, fire_real_timer, 0, 0, &s_pid);\n\t}\n}\nunsigned int get_cur_thread_id()\n{\n\treturn GetCurrentThreadId();\n}\nvoid register_timer(int milli_second,void func(void* param), void* param)\n{\n\tset_a_timer(milli_second/TIMER_UNIT,func, param);\n}\nlong get_time_in_second()\n{\n\treturn (long)time(0);\n}\nT_TIME get_time()\n{\n\tT_TIME ret = {0};\n\t\n\tSYSTEMTIME time;\n\tGetLocalTime(&time);\n\tret.year = time.wYear;\n\tret.month = time.wMonth;\n\tret.day = time.wDay;\n\tret.hour = time.wHour;\n\tret.minute = time.wMinute;\n\tret.second = time.wSecond;\n\treturn ret;\n}\nT_TIME second_to_day(long second)\n{\n\tT_TIME ret;\n\tret.year = 1999;\n\tret.month = 10;\n\tret.date = 1;\n\tret.second = second % 60;\n\tsecond /= 60;\n\tret.minute = second % 60;\n\tsecond /= 60;\n\tret.hour = (second + 8) % 24;//China time zone.\n\treturn ret;\n}\nvoid create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)\n{\n\tDWORD pid = 0;\n\tCreateThread(0, 0, LPTHREAD_START_ROUTINE(start_routine), arg, 0, &pid);\n\t*thread_id = pid;\n}\nvoid thread_sleep(unsigned int milli_seconds)\n{\n\tSleep(milli_seconds);\n}\n#pragma pack(push,1)\ntypedef struct {\n\tunsigned short\tbfType;\n\tunsigned int   \tbfSize;\n\tunsigned short  bfReserved1;\n\tunsigned short  bfReserved2;\n\tunsigned int   \tbfOffBits;\n}FileHead;\ntypedef struct {\n\tunsigned int  \tbiSize;\n\tint \t\t\tbiWidth;\n\tint       \t\tbiHeight;\n\tunsigned short\tbiPlanes;\n\tunsigned short  biBitCount;\n\tunsigned int    biCompress;\n\tunsigned int    biSizeImage;\n\tint       \t\tbiXPelsPerMeter;\n\tint       \t\tbiYPelsPerMeter;\n\tunsigned int \tbiClrUsed;\n\tunsigned int    biClrImportant;\n\tunsigned int \tbiRedMask;\n\tunsigned int \tbiGreenMask;\n\tunsigned int \tbiBlueMask;\n}Infohead;\n#pragma pack(pop)\nint build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)\n{\n\tFileHead bmp_head;\n\tInfohead bmp_info;\n\tint size = width * height * 2;\n\t//initialize bmp head.\n\tbmp_head.bfType = 0x4d42;\n\tbmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead);\n\tbmp_head.bfReserved1 = bmp_head.bfReserved2 = 0;\n\tbmp_head.bfOffBits = bmp_head.bfSize - size;\n\t//initialize bmp info.\n\tbmp_info.biSize = 40;\n\tbmp_info.biWidth = width;\n\tbmp_info.biHeight = height;\n\tbmp_info.biPlanes = 1;\n\tbmp_info.biBitCount = 16;\n\tbmp_info.biCompress = 3;\n\tbmp_info.biSizeImage = size;\n\tbmp_info.biXPelsPerMeter = 0;\n\tbmp_info.biYPelsPerMeter = 0;\n\tbmp_info.biClrUsed = 0;\n\tbmp_info.biClrImportant = 0;\n\t//RGB565\n\tbmp_info.biRedMask = 0xF800;\n\tbmp_info.biGreenMask = 0x07E0;\n\tbmp_info.biBlueMask = 0x001F;\n\t//copy the data\n\tFILE *fp;\n\tif (!(fp = fopen(filename, \"wb\")))\n\t{\n\t\treturn -1;\n\t}\n\tfwrite(&bmp_head, 1, sizeof(FileHead), fp);\n\tfwrite(&bmp_info, 1, sizeof(Infohead), fp);\n\t//fwrite(data, 1, size, fp);//top <-> bottom\n\tfor (int i = (height - 1); i >= 0; --i)\n\t{\n\t\tfwrite(&data[i * width * 2], 1, width * 2, fp);\n\t}\n\tfclose(fp);\n\treturn 0;\n}\nc_fifo::c_fifo()\n{\n\tm_head = m_tail = 0;\n\tm_read_sem = CreateSemaphore(0,\t// default security attributes\n\t\t0,\t\t// initial count\n\t\t1,\t\t// maximum count\n\t\t0);\t// unnamed semaphore\n\tm_write_mutex = CreateMutex(0, false, 0);\n}\nint c_fifo::read(void* buf, int len)\n{\n\tunsigned char* pbuf = (unsigned char*)buf;\n\tint i = 0;\n\twhile (i < len)\n\t{\n\t\tif (m_tail == m_head)\n\t\t{//empty\n\t\t\tWaitForSingleObject(m_read_sem, INFINITE);\n\t\t\tcontinue;\n\t\t}\n\t\t*pbuf++ = m_buf[m_head];\n\t\tm_head = (m_head + 1) % FIFO_BUFFER_LEN;\n\t\ti++;\n\t}\n\tif (i != len)\n\t{\n\t\tASSERT(false);\n\t}\n\treturn i;\n}\nint c_fifo::write(void* buf, int len)\n{\n\tunsigned char* pbuf = (unsigned char*)buf;\n\tint i = 0;\n\tint tail = m_tail;\n\tWaitForSingleObject(m_write_mutex, INFINITE);\n\twhile (i < len)\n\t{\n\t\tif ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)\n\t\t{//full, clear data has been written;\n\t\t\tm_tail = tail;\n\t\t\tlog_out(\"Warning: fifo full\\n\");\n\t\t\tReleaseMutex(m_write_mutex);\n\t\t\treturn 0;\n\t\t}\n\t\tm_buf[m_tail] = *pbuf++;\n\t\tm_tail = (m_tail + 1) % FIFO_BUFFER_LEN;\n\t\ti++;\n\t}\n\tReleaseMutex(m_write_mutex);\n\tif (i != len)\n\t{\n\t\tASSERT(false);\n\t}\n\telse\n\t{\n\t\tReleaseSemaphore(m_read_sem, 1, 0);\n\t}\n\treturn i;\n}\n#endif\n#endif\n#ifdef GUILITE_ON\nDIALOG_ARRAY c_dialog::ms_the_dialogs[SURFACE_CNT_MAX];\nc_keyboard  c_edit::s_keyboard;\nstatic c_keyboard_button s_key_0, s_key_1, s_key_2, s_key_3, s_key_4, s_key_5, s_key_6, s_key_7, s_key_8, s_key_9;\nstatic c_keyboard_button s_key_A, s_key_B, s_key_C, s_key_D, s_key_E, s_key_F, s_key_G, s_key_H, s_key_I, s_key_J;\nstatic c_keyboard_button s_key_K, s_key_L, s_key_M, s_key_N, s_key_O, s_key_P, s_key_Q, s_key_R, s_key_S, s_key_T;\nstatic c_keyboard_button s_key_U, s_key_V, s_key_W, s_key_X, s_key_Y, s_key_Z;\nstatic c_keyboard_button s_key_dot, s_key_caps, s_key_space, s_key_enter, s_key_del, s_key_esc, s_key_num_switch;\nWND_TREE g_key_board_children[] =\n{\n\t//Row 1\n\t{&s_key_Q, 'Q', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_W, 'W', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_E, 'E', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_R, 'R', 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_T, 'T', 0, POS_X(4), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_Y, 'Y', 0, POS_X(5), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_U, 'U', 0, POS_X(6), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_I, 'I', 0, POS_X(7), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_O, 'O', 0, POS_X(8), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_P, 'P', 0, POS_X(9), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t//Row 2 \n\t{&s_key_A, 'A', 0, ((KEY_WIDTH / 2) + POS_X(0)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_S, 'S', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_D, 'D', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_F, 'F', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_G, 'G', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_H, 'H', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_J, 'J', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_K, 'K', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_L, 'L', 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t//Row 3\n\t{&s_key_caps, 0x14,\t0, POS_X(0),\t\t\t\t\t\tPOS_Y(2), CAPS_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_Z,\t'Z',\t0, ((KEY_WIDTH / 2) + POS_X(1)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_X,\t'X',\t0, ((KEY_WIDTH / 2) + POS_X(2)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_C,\t'C',\t0, ((KEY_WIDTH / 2) + POS_X(3)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_V,\t'V',\t0, ((KEY_WIDTH / 2) + POS_X(4)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_B,\t'B',\t0, ((KEY_WIDTH / 2) + POS_X(5)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_N,\t'N',\t0, ((KEY_WIDTH / 2) + POS_X(6)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_M,\t'M',\t0, ((KEY_WIDTH / 2) + POS_X(7)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_del,0x7F,\t0, ((KEY_WIDTH / 2) + POS_X(8)),\tPOS_Y(2), DEL_WIDTH,\tKEY_HEIGHT},\n\t//Row 4\n\t{&s_key_esc,\t\t0x1B,\t0, POS_X(0),\t\t\t\t\t\tPOS_Y(3), ESC_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_num_switch,\t0x90,\t0, POS_X(2),\t\t\t\t\t\tPOS_Y(3), SWITCH_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_space,\t\t' ',\t0, ((KEY_WIDTH / 2) + POS_X(3)),\tPOS_Y(3), SPACE_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_dot,\t\t'.',\t0, ((KEY_WIDTH / 2) + POS_X(6)),\tPOS_Y(3), DOT_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_enter,\t\t'\\n',\t0, POS_X(8),\t\t\t\t\t\tPOS_Y(3), ENTER_WIDTH,\tKEY_HEIGHT},\n\t{0,0,0,0,0,0,0}\n};\nWND_TREE g_number_board_children[] =\n{\n\t{&s_key_1,\t'1',\t0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_2,\t'2',\t0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_3,\t'3',\t0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_4,\t'4',\t0, POS_X(0), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_5,\t'5',\t0, POS_X(1), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_6,\t'6',\t0, POS_X(2), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_7,\t'7',\t0, POS_X(0), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_8,\t'8',\t0, POS_X(1), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_9,\t'9',\t0, POS_X(2), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_esc,0x1B,\t0, POS_X(0), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_0,\t'0',\t0, POS_X(1), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_dot,'.',\t0, POS_X(2), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_del, 0x7F,\t0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT * 2 + 2},\n\t{&s_key_enter,'\\n',\t0, POS_X(3), POS_Y(2), KEY_WIDTH, KEY_HEIGHT * 2 + 2},\n\t{0,0,0,0,0,0,0}\n};\n#endif"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# Welcome to GUI-lite\n<p align=\"center\">\n    <img src=\"documents/logo.png\" alt=\"Logo\"/>\n</p>\n<p align=\"center\">\n  <img src=\"https://img.shields.io/badge/build-passing-brightgreen.svg\">\n  <img src=\"https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS%20%7C%20iOS%20%7C%20Android%20%7C%20MCU-brightgreen.svg\">\n  <img src=\"https://img.shields.io/badge/architecture-amd64%20%7C%20arm%20%7C%20arm64-blue.svg\">\n  <img src=\"https://img.shields.io/badge/license-Apache%202-blue.svg\">\n</p>\n<p align=\"center\">The smallest header-only GUI library (4 KLOC) for all platforms.</p>\n<p align=\"center\">\n    <img src=\"documents/WhyGuiLite.png\" alt=\"Why GuiLite\"/>\n</p>\n\n- [中文](README_zh.md)\n\n## Lightweight\n- ✂️Small: 4,000+ lines of C++ code, zero dependency, header-only(GuiLite.h)\n- ⚡Fast: High Rendering performance, even work on MCU\n- 👫🏻Compatible: Work smoothly with 3rd party frameworks(Qt/MFC/Winform/Cocoa/Web)\n- ⚙️️Hardware Minimum Requirements:\n\n    | Processor | Disk/ROM space | Memory |\n    | --- | --- | --- |\n    | 24 MHZ | 29 KB | 9 KB |\n\n## Cross platform\n- Supported OSes: iOS/macOS/WatchOS, Android, Linux, Windows, RTOS... or **MCU without OS**\n- Supported languages: C/C++, Swift, Java, Javascript, C#, Golang...\n- Supported 3rd party libraries: Qt, MFC, Winforms, CoCoa...\n\n## Hero features\n- ☁️Cloud + IoT Solution: master your IoT business all over the world\n- 🔣Multi-language, supports UTF-8;📀Playback Video\n- 🔨[Toolkit](https://github.com/idea4good/GuiLiteToolkit) for building font/image resources\n- 📐[Layout GUI WYSIWYG](https://github.com/idea4good/GuiLitePreviewer)\n- 📊Code Telemetry and Analysis in real time\n- 📦Supports 3D and [Web](https://github.com/idea4good/GuiLiteWeb)\n- 🐋Run in docker with a single command: `sudo docker run -it --privileged -v /dev:/dev-share idea4good/gui-lite:latest bash /run.sh`\n\n## Easy to learn and support\nEven a C beginner could master GUI-lite quickly. The source code only uses basic C++ features (class, virtual function). We chose C++ as it could make the code size significantly smaller and easier to read.\n- 📚Documentation\n    - [How to use GUI-lite?](documents/HowToUse.md)\n    - [Design specification](documents/HowToWork.md)\n    - [How to Layout widgets?](documents/HowLayoutWork.md)\n    - [How to build unicode font/bitmap resource?](https://github.com/idea4good/GuiLiteToolkit)\n    - [How to switch theme?](https://github.com/idea4good/GuiLiteSamples/blob/master/HostMonitor/UIcode/source/resource/resource.cpp)\n    - [How to dispatch messages?](documents/HowMessageWork.md)\n    - [UML chart of GUI-lite core](documents/UML.md)\n- 📈Learning steps\n    1. Build GUI-lite library\n    2. Build/Debug HelloXXX demos\n    3. Read/Modify `HelloXXX/UIcode/UIcode.cpp` code\n    4. Read/Modify `widgets` code\n    5. Read/Modify `core` code\n    6. Build your GUI framework\n- 📞[Reach out us](#community-channel) if you have any questions you are welcomed to our developer family.\n- 🀄️[Mirror repository in China](https://gitee.com/idea4good/GuiLite)\n\n## Demo wall\n- Zero dependency, 100% build pass & runnable\n- Click the demo you like, and run it on your hardware\n- Most of the demos have about 100 lines of UI code, the code repository is [GuiLiteSamples](https://github.com/idea4good/GuiLiteSamples)\n---\n### MCU platform\n---\n<table>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3D\"><img src=\"documents/Hello3D.gif\" width=\"200px;\"/><br /><sub><b>3D on STM32</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloWave\"><img src=\"documents/HelloWave.gif\" width=\"200px;\"/><br /><sub><b>Wave on STM32</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloParticle\"><img src=\"documents/HelloParticle.gif\" width=\"200px;\"/><br /><sub><b>Particle on STM32</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloStar\"><img src=\"documents/HelloStar.gif\" width=\"200px;\"/><br /><sub><b>Star on STM32</b></sub></a>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3Dwave\"><img src=\"documents/Hello3Dwave.gif\" width=\"200px;\"/><br /><sub><b>3D wave on STM32</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloNoTouch\"><img src=\"documents/HelloNoTouch.gif\" width=\"200px;\"/><br /><sub><b>Keyboard on STM32</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloMario\"><img src=\"documents/HelloMario.gif\" width=\"200px;\"/><br /><sub><b>Mario on STM32</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloCircle\"><img src=\"documents/HelloCircle.gif\" width=\"200px;\"/><br /><sub><b>3D circle on STM32</b></sub></a>\n  </tr>\n  <tr>\n  <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3Ddonut\"><img src=\"documents/Hello3Ddonut.gif\" width=\"200px;\"/><br /><sub><b>3D donut on STM32</b></sub></a>\n  <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloTimer\"><img src=\"documents/HelloTimer.gif\" width=\"200px;\"/><br /><sub><b>Timer</b></sub></a>\n  <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloMolecule\"><img src=\"documents/HelloMolecule.gif\" width=\"200px;\"/><br /><sub><b>Molecule move</b></sub></a>\n  <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloPendulum\"><img src=\"documents/HelloPendulum.gif\" width=\"200px;\"/><br /><sub><b>Pendulum effect</b></sub></a>\n  </tr>\n</table>\n\n---\n### IoT feature\n---\n<table>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/data_on_cloud.png\" width=\"600px;\"/><br /><sub><b>Monitor IoT device on cloud</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/BuildInfo.png\" width=\"600px;\"/><br /><sub><b>Code Telemetry & Analysis in real time</b></sub></a>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloAzureIoT\"><img src=\"documents/HelloAzureIoT.jpg\" width=\"600px;\"/><br /><sub><b>Track IoT device over the world</b></sub></a>\n  </tr>\n</table>\n\n---\n### Multi-language, Design tool and video\n---\n<table>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloFont\"><img src=\"documents/HelloFont.gif\" width=\"600px;\"/><br /><sub><b>Lattice Font</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloFreetype\"><img src=\"documents/HelloFreetype.gif\" width=\"600px;\"/><br /><sub><b>Freetype Font</b></sub></a>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLitePreviewer\"><img src=\"documents/Previewer.gif\" width=\"600px;\"/><br /><sub><b>Layout GUI</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloJPG\"><img src=\"documents/HelloJPG.gif\" width=\"600px;\"/><br /><sub><b>Render JPG file quickly</b></sub></a>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloFFmpeg\"><img src=\"documents/HelloFFmpeg.jpg\" width=\"600px;\"/><br /><sub><b>Play video with FFmpeg</b></sub></a>\n  </tr>\n</table>\n\n---\n### Widgets & Controller\n---\n<table>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloGuiLite\"><img src=\"documents/HelloGuiLite.gif\" width=\"600px;\"/><br /><sub><b>Emulate  Windows UI</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloScroll\"><img src=\"documents/HelloScroll.gif\" width=\"600px;\"/><br /><sub><b>Scroll widget</b></sub></a>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloWidgets\"><img src=\"documents/HelloWidgets.gif\" width=\"600px;\"/><br /><sub><b>How to use widgets</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloNets\"><img src=\"documents/HelloNets-pc.gif\" width=\"600px;\"/><br /><sub><b>3D Nets on Windows/Linux</b></sub></a>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloTransparent\"><img src=\"documents/HelloTransparent.gif\" width=\"600px;\"/><br /><sub><b>Transparent dialog</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloSlide\"><img src=\"documents/HelloSlide.gif\" width=\"600px;\"/><br /><sub><b>Swipe view</b></sub></a>\n  </tr>\n</table>\n\n---\n### Cross platform\n---\n<table>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/HostMonitor.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Windows</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/Mac.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Mac</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/Android.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Android</b></sub></a>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/WinMR.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Windows Mixed Reality</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/Linux.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Linux</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteWeb\"><img src=\"documents/GuiLite3D.gif\" width=\"300px;\"/><br /><sub><b>3D on Web</b></sub></a>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteWeb\"><img src=\"documents/GuiLiteCube.gif\" width=\"300px;\"/><br /><sub><b>3D on Web</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/iOS.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on iPhone</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteWeb\"><img src=\"documents/GuiLiteGraphic.gif\" width=\"300px;\"/><br /><sub><b>How display work</b></sub></a>\n  </tr>\n</table>\n\n---\n### Apple platform\n---\n<table>\n  <tr>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3D\"><img src=\"documents/iWatch.hello3D.gif\" width=\"300px;\"/><br /><sub><b>3D on Apple Watch</b></sub></a>\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloWave\"><img src=\"documents/iWatch.helloWave.gif\" width=\"300px;\"/><br /><sub><b>Wave on Apple Watch</b></sub></a>    \n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloParticle\"><img src=\"documents/iOS.particle.gif\" width=\"300px;\"/><br /><sub><b>Particle on iPhone</b></sub></a>\n  </tr>\n</table>\n\n## 📞Community Channel\nThanks for the help from the community, you all make GUI-lite better! And welcome to any new friend to join us.\n- [**@Twitter**](https://twitter.com/idea4good)\n- QQ group:\n<table>\n  <tr>\n    <td align=\"center\"><img src=\"documents/qq.group-7.png\" width=\"240px;\"/><br /><sub><b>開發群🔑：875721211</b></sub></a>\n  </tr>\n"
  },
  {
    "path": "README_zh.md",
    "content": "# 歡迎蒞臨 GUI-lite\r\n<p align=\"center\">\r\n    <img src=\"documents/logo.png\" alt=\"Logo\"/>\r\n</p>\r\n<p align=\"center\">\r\n  <img src=\"https://img.shields.io/badge/build-passing-brightgreen.svg\">\r\n  <img src=\"https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS%20%7C%20iOS%20%7C%20Android%20%7C%20MCU-brightgreen.svg\">\r\n  <img src=\"https://img.shields.io/badge/architecture-amd64%20%7C%20arm%20%7C%20arm64-blue.svg\">\r\n  <img src=\"https://img.shields.io/badge/license-Apache%202-blue.svg\">\r\n</p>\r\n<p align=\"center\"> 大道至簡 - 4千行/仅头文件/全平台GUI库 </p>\r\n<p align=\"center\">\r\n    <img src=\"documents/WhyGuiLite-cn.png\" alt=\"Why GuiLite\"/>\r\n</p>\r\n\r\n## 輕-快-容\r\n- ✂️轻量: 4千行C++代码，0依赖，单一头文件库（GuiLite.h）\r\n- ⚡超快: 高效渲染，单片机上也能流畅运行\r\n- 👫🏻兼容: 完美兼容第3方GUI框架(Qt/MFC/Winform/Cocoa/Web)，现有Qt/MFC代码可以继续使用\r\n- ⚙️️最低硬件要求:\r\n\r\n  | Processor | Disk/ROM space | Memory |\r\n  | --- | --- | --- |\r\n  | 24 MHZ | 29 KB | 9 KB |\r\n\r\n## 跨平臺\r\n- 支持的操作系统：iOS/macOS/WatchOS，Android，Linux（ARM/x86-64），Windows（包含VR），RTOS... 甚至**无操作系统的单片机**\r\n- 支持的开发语言： C/C++, Swift, Java, Javascript, C#, Golang...\r\n- 支持的第3方库：Qt, MFC, Winforms, CoCoa...\r\n\r\n## 實用的功能\r\n- ☁️完美的“云” + “物联网”解决方案：让你轻松驾驭全球IoT业务\r\n- 🔣支持多语言,采用 UTF-8 编码；📀支持视频播放\r\n- 🔨[资源制作工具](https://github.com/idea4good/GuiLiteToolkit)为你定制自己的字体/图片资源\r\n- 📐[所见即所得的GUI布局工具](https://github.com/idea4good/GuiLitePreviewer)\r\n- 📊编译活跃度统计，及实时分析\r\n- 📦支持3D & [Web](https://github.com/idea4good/GuiLiteWeb)\r\n- 🐋支持Docker，一条命令启动Docker: `sudo docker run -it --privileged -v /dev:/dev-share idea4good/gui-lite:latest bash /run.sh`\r\n\r\n## 易學習和全面的技術支持\r\n即使是C语言的初学者，也可以很快掌握GUI-lite；代码只使用C++的基本特性（类和虚函数），选择C++语言，能让代码体积更小，更易阅读。\r\n- 📚开发文档\r\n    - [如何使用GUI-lite?](documents/HowToUse.md)\r\n    - [软件设计说明](documents/HowToWork-cn.md)\r\n    - [如何布局UI?](documents/HowLayoutWork.md)\r\n    - [如何制作多种文字/位图资源?](https://github.com/idea4good/GuiLiteToolkit)\r\n    - [如何“换肤”？](https://github.com/idea4good/GuiLiteSamples/blob/master/HostMonitor/UIcode/source/resource/resource.cpp)\r\n    - [如何传递消息?](documents/HowMessageWork.md)\r\n    - [核心UML示意图](documents/UML.md)\r\n- 📈学习方法\r\n    1. 编译GUI-lite库\r\n    2. 编译、调试：HelloXXX实例程序\r\n    3. 研读、修改100+行的`HelloXXX/UIcode/UIcode.cpp`源代码\r\n    4. 研读`widgets`目录下的代码\r\n    5. 研读`core`目录下的代码\r\n    6. 扩展/开发自己的GUI库\r\n- 📞遇到任何问题，都可以[联系我们](#社区交流)，也欢迎加入我们的开发者大家庭\r\n- 🌐[码云Gitee快速链接](https://gitee.com/idea4good/GuiLite)\r\n\r\n## Demo展示墻\r\n- 0依赖，100%编译通过，可直接运行\r\n- 点击你喜欢的实例，并运行在你的硬件上面\r\n- 大部分demo的UI代码只有100行左右，代碼庫在[GuiLiteSamples](https://github.com/idea4good/GuiLiteSamples)\r\n---\r\n### 單片機平臺\r\n---\r\n<table>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3D\"><img src=\"documents/Hello3D.gif\" width=\"200px;\"/><br /><sub><b>3D on STM32</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloWave\"><img src=\"documents/HelloWave.gif\" width=\"200px;\"/><br /><sub><b>Wave on STM32</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloParticle\"><img src=\"documents/HelloParticle.gif\" width=\"200px;\"/><br /><sub><b>Particle on STM32</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloStar\"><img src=\"documents/HelloStar.gif\" width=\"200px;\"/><br /><sub><b>Star on STM32</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3Dwave\"><img src=\"documents/Hello3Dwave.gif\" width=\"200px;\"/><br /><sub><b>3D wave on STM32</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloNoTouch\"><img src=\"documents/HelloNoTouch.gif\" width=\"200px;\"/><br /><sub><b>Keyboard on STM32</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloMario\"><img src=\"documents/HelloMario.gif\" width=\"200px;\"/><br /><sub><b>Mario on STM32</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloCircle\"><img src=\"documents/HelloCircle.gif\" width=\"200px;\"/><br /><sub><b>3D circle on STM32</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n  <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3Ddonut\"><img src=\"documents/Hello3Ddonut.gif\" width=\"200px;\"/><br /><sub><b>3D donut on STM32</b></sub></a>\r\n  <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloTimer\"><img src=\"documents/HelloTimer.gif\" width=\"200px;\"/><br /><sub><b>Timer</b></sub></a>\r\n  <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloMolecule\"><img src=\"documents/HelloMolecule.gif\" width=\"200px;\"/><br /><sub><b>Molecule move</b></sub></a>\r\n  <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloPendulum\"><img src=\"documents/HelloPendulum.gif\" width=\"200px;\"/><br /><sub><b>Pendulum effect</b></sub></a>\r\n  </tr>\r\n</table>\r\n\r\n---\r\n### IoT 功能\r\n---\r\n<table>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/data_on_cloud.png\" width=\"600px;\"/><br /><sub><b>Monitor IoT device on cloud</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/BuildInfo.png\" width=\"600px;\"/><br /><sub><b>Code Telemetry & Analysis in real time</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloAzureIoT\"><img src=\"documents/HelloAzureIoT.jpg\" width=\"600px;\"/><br /><sub><b>Track IoT device over the world</b></sub></a>\r\n  </tr>\r\n</table>\r\n\r\n---\r\n### 多語言，設計工具及視頻\r\n---\r\n<table>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloFont\"><img src=\"documents/HelloFont.gif\" width=\"600px;\"/><br /><sub><b>Lattice Font</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloFreetype\"><img src=\"documents/HelloFreetype.gif\" width=\"600px;\"/><br /><sub><b>Freetype Font</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLitePreviewer\"><img src=\"documents/Previewer.gif\" width=\"600px;\"/><br /><sub><b>Layout GUI</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloJPG\"><img src=\"documents/HelloJPG.gif\" width=\"600px;\"/><br /><sub><b>Render JPG file quickly</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloFFmpeg\"><img src=\"documents/HelloFFmpeg.jpg\" width=\"600px;\"/><br /><sub><b>Play video with FFmpeg</b></sub></a>\r\n  </tr>\r\n</table>\r\n\r\n---\r\n### UI 控件實作\r\n---\r\n<table>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloGuiLite\"><img src=\"documents/HelloGuiLite.gif\" width=\"600px;\"/><br /><sub><b>Emulate  Windows UI</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloScroll\"><img src=\"documents/HelloScroll.gif\" width=\"600px;\"/><br /><sub><b>Scroll widget</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloWidgets\"><img src=\"documents/HelloWidgets.gif\" width=\"600px;\"/><br /><sub><b>How to use widgets</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloNets\"><img src=\"documents/HelloNets-pc.gif\" width=\"600px;\"/><br /><sub><b>3D Nets on Windows/Linux</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloTransparent\"><img src=\"documents/HelloTransparent.gif\" width=\"600px;\"/><br /><sub><b>Transparent dialog</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloSlide\"><img src=\"documents/HelloSlide.gif\" width=\"600px;\"/><br /><sub><b>Swipe view</b></sub></a>\r\n  </tr>\r\n</table>\r\n\r\n---\r\n### 跨平臺實作\r\n---\r\n<table>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/HostMonitor.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Windows</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/Mac.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Mac</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/Android.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Android</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/WinMR.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Windows Mixed Reality</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/Linux.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on Linux</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteWeb\"><img src=\"documents/GuiLite3D.gif\" width=\"300px;\"/><br /><sub><b>3D on Web</b></sub></a>\r\n  </tr>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteWeb\"><img src=\"documents/GuiLiteCube.gif\" width=\"300px;\"/><br /><sub><b>3D on Web</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HostMonitor\"><img src=\"documents/iOS.gif\" width=\"300px;\"/><br /><sub><b>HostMonitor on iPhone</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteWeb\"><img src=\"documents/GuiLiteGraphic.gif\" width=\"300px;\"/><br /><sub><b>How display work</b></sub></a>\r\n  </tr>\r\n</table>\r\n\r\n---\r\n### 蘋果平臺\r\n---\r\n<table>\r\n  <tr>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/Hello3D\"><img src=\"documents/iWatch.hello3D.gif\" width=\"300px;\"/><br /><sub><b>3D on Apple Watch</b></sub></a>\r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloWave\"><img src=\"documents/iWatch.helloWave.gif\" width=\"300px;\"/><br /><sub><b>Wave on Apple Watch</b></sub></a>    \r\n    <td align=\"center\"><a href=\"https://github.com/idea4good/GuiLiteSamples/tree/master/HelloParticle\"><img src=\"documents/iOS.particle.gif\" width=\"300px;\"/><br /><sub><b>Particle on iPhone</b></sub></a>\r\n  </tr>\r\n</table>\r\n\r\n## 📞社區交流\r\n- 感谢开发者群的所有同学，是你们塑造了今天的GUI-lite！也欢迎新的大神/小白加入我们。\r\n- 开发者QQ\r\n<table>\r\n  <tr>\r\n    <td align=\"center\"><img src=\"documents/qq.group-7.png\" width=\"240px;\"/><br /><sub><b>開發群🔑：875721211</b></sub></a>\r\n  </tr>\r\n  "
  },
  {
    "path": "documents/HowLayoutWork.md",
    "content": "# How to layout widgets for GuiLiteSamples::HostMonitor?\n\nAll widgets were described by struct WND_TREE and ?.xml.cpp files\n\n## How to layout slide group?\n![Layout slides group](layout_slide_group.png)\n## How to layout single slide?\n![Layout single slide](layout_single_slide.png)\n## How to layout dialog?\n![Layout dialog](layout_dialog.png)"
  },
  {
    "path": "documents/HowMessageWork.md",
    "content": "# How messages work for GuiLiteSamples::HostMonitor?\n\n## How real time message(draw waves) work?\n![Callstack for drawing waves](draw_wav.png)\n\n## How click button message work?\n![Callstack for clicking button](click_button.png)\n\n## How left/right flip message work?\n![Callstack for fliping slides](flip.png)"
  },
  {
    "path": "documents/HowToUse.md",
    "content": "# How to use GuiLite?\n- For GuiLite user: You could copy GuiLite.h in your application\n- For GuiLite developer: You could get well-organized source code, and develop it on any platform(Windows/Linux/Apple)\n\n# For GuiLite user\nGuiLite is a header-only library, so it should be straightforward to integrate into your application.\n\nUIcode.cpp:\n```c++\n#define GUILITE_ON\t// Do not define this macro upon GuiLite.h once more\n#include \"GuiLite.h\"\n\n// your code here:\n```\n# For GuiLite developer\n## Build GuiLite library for Windows?\nPrerequisite: Windows & Visul Studio 2013/2015/2017/2019\n- Open \"GuiLite.sln\" by Visual Studio\n- Click `Build Solution`\n- Output here: GuiLite\\workspace\\Debug(Release)\\GuiLite.lib\n\nFAQ: Error when open GuiLite project with Visual Studio, reconfigure the project to match your computer like this:\n\n![vs-configure](vs-configure.jpg)\n\n## Build GuiLite library for iOS/Mac and Linux(amd64) & raspberry pi?\n```bash\ncd GuiLite/workspace\ncmake .\nmake\n\n# Output here: GuiLite/workspace/libGuiLite.a\n```\n\n## Build GuiLite library for ARM Linux?\n### Prerequisite: Install cross compiler:\n```bash\n# For ARM32:\nsudo apt-get install g++-arm-linux-gnueabi gcc-arm-linux-gnueabi\n# For ARM64:\nsudo apt-get install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu\n```\n### Build\n```bash\ncd GuiLite/workspace\n# For ARM32:\ncmake -D CMAKE_C_COMPILER=\"/usr/bin/arm-linux-gnueabi-gcc\" -D CMAKE_CXX_COMPILER=\"/usr/bin/arm-linux-gnueabi-g++\" .\n# For ARM64:\ncmake -D CMAKE_C_COMPILER=\"/usr/bin/aarch64-linux-gnu-gcc\" -D CMAKE_CXX_COMPILER=\"/usr/bin/aarch64-linux-gnu-g++\" .\nmake\n```\nOutput here: GuiLite/workspace/libGuiLite.a\n\n## How to build GuiLite library for any MCU?\n### Prerequisite: Install Keil uvsion 5.6 or above.\n### Build\n- Open `GuiLite/workspace/GuiLite.uvprojx` with Keil uvsion.\n- Implement function(e.g, thread_sleep) in `core\\src\\adapter\\api_unknow.cpp` to meet your need.\n- Choose your Device type(Default: STM32F103ZE) from option for target.\n- Build GuiLite.\n- Output here: GuiLite/workspace/Objects/GuiLite.lib\n\n## Build header-only GuiLite.h?\n```bash\ncd GuiLite/src\n./GenerateGuiLite.h.sh\n```\n"
  },
  {
    "path": "documents/HowToWork-cn.md",
    "content": "# GuiLite设计原理及代码注释\n- [基本原理](#基本原理)\n- [扩展方法](#扩展方法)\n- [代码目录结构](#代码目录结构)\n- [界面元素管理](#界面元素管理)\n- [图形绘制](#图形绘制)\n- [文件注释](#文件注释)\n- [函数注释](#函数注释)\n- [速成路线图](#速成路线图)\n***\n## 基本原理\nGuiLite只做两个工作：界面元素管理和图形绘制。\n\n界面管理包括：\n- 添加/删除界面元素（例如：按钮，标签，对话框等控件），设置对应的文字及位置信息\n- 用户输入消息传递：根据用户输入寻找受影响的界面元素，并回调响应的处理的处理函数\n- 用户自定义消息传递：用户可以自定义消息响应函数，并自主产生消息；当消息产生时，对应的响应函数会被调用\n\n图形绘制包括：\n- 基本的点线绘制，例如：画点，矩形，横线，竖线等\n- 设置绘制图层，如果需要多个图层，在基本点线绘制时，需要给出图层的索引值\n- 图层处理，在图层界面发生变化的时候(例如：打开/关闭对话框)，GuiLite将决定各个图层上的像素点，哪个会被最终显示在屏幕上\n\n👉注意：图形绘制不依赖界面管理，可以独立的存在，例如，在资源有限的单片机环境，有时候不需要界面元素管理，而直接进行图形，文字的绘制。\n\n## 扩展方法\nGuiLite只给出了基本控件（例如：按钮，标签，键盘，选择框）的实现方法，旨在说明控件的实现方法。对于扩展控件，可以选择下面的方式：\n- 如果开发者需要调整基本控件的细节，可以直接在源代码中修改\n- 如果开发者需要构建全新的控件，可以参考基本控件的实现方法，重新实现\n\n对于扩展绘制，例如：画圆，画曲线，可以直接在surface.cpp文件中添加响应的函数接口。\n\n## 代码目录结构\ncore: \n- 实现了底层绘制，图层管理和消息传递\n- adapter实现了各个平台（例如：Windows, Linux，Android，iOS，macOS,未知OS或无OS）的封装。\n\nwidgets: \n- 实现了各种常规控件（例如：按钮，标签，键盘，波形）及容器（例如：视窗，对话框，滑动页面），开发者可以根据自己的需要，直接在相应的代码上进行修改或重绘，开发出有自己风格，特色的界面\n- 实现了用户的手势识别（例如：手指滑动，鼠标按下/释放）的消息传递，将用户的输入信息传递到整个GUI体系树中，并调用相应的响应回调函数；开发者可以根据自己的需要添加/修改响应回调函数。\n\n## 界面元素管理\n界面元素管理包括：对所有控件（button，spinbox, lable, keyboard），容器（dialog, view）管理；具体的管理方法是在用户调用connect函数时，会把所有的界面元素连接起来，从而实现对所有界面元素的遍历/添加/删除等操作。这些链接看起来像一棵树，对界面元素的遍历，就是对这棵树的遍历\n\n比如：当你按下一个dialog的button时，手指的位置信息（x，y）会被传入树的根部（root），然后从root开始寻找，哪个dialog被点中，dialog的哪个button被点中，并调用buton被点中的回调函数，用于作相应处理（一般会进行button的状态修改及重绘工作）\n\n### 界面元素如何创建\n所有界面元素都继承自c_wnd类的对象，对象被实例化时，也就完成了界面元素的创建；但此时的界面元素是孤独的，与其他界面元素没有形成联系（没有父母，没有兄弟姐妹）\n\n### 界面元素如何被管理\n新创建的界面元素纳入管理的过程，就是为其添加父母，兄弟姐妹的过程。使用的函数接口为connect();从此该界面元素会跟其他界面元素一样，纳入一棵树中，并随之响应用户可能的点击操作。\n\n当需要删掉该界面元素时，使用disconnect()；从此该界面元素会断绝所有的父子关系，从树上摘下来，不再响应用户的触控操作；但对象本身不会被销毁。典型应用场景：软键盘的创建/退出。\n\n## 图形绘制\n图形绘制包括： 绘制方法和图层管理。\n- 点绘制是线/面/位图绘制的基础，若干个点的绘制，形成点面及位图\n- 图层管理，则是管理多个界面元素的遮挡关系，系统默认支持3层遮挡关系，这3个层次可以为：视图背景层，对话框层，keyboard/spinbox控件层。\n\n### 绘制方法\n请参看文件bitmap.cpp和surface.cpp中的draw_xxx()函数。\n为了发挥GPU的加速功能，也可以通过改写draw_xxx/fill_xxx函数，使用GPU特性，来提升绘制效率。\n\n### 图层管理\n![Graphic layer](GraphicLayer.png)![GuiLiteGraphic](GuiLiteGraphic.gif)\n- display层：该层对应了物理显存，display层决定了一个显示终端的最终显示效果；通常系统中至少有一个display层。\n- surface层：该层属于display层的一个部分；它为左右滑动而存在，每一张滑动页面均对应了一个surface层；surface层决定了一个滑动页面的最终显示效果；通常1个display层会对应多个surface层。\n- frame层：该层属于surface层的一个部分；它现实叠加界面元素而存在。\n\n## 文件注释\n| core 重要程度/文件名称 | 代码简介 | 推荐学习时间 |\n| --- | --- | --- |\n| ★★★ wnd.h | UI元素的基本类，定义所有的UI元素信息、绘制及管理办法 | 1.5小时 |\n| ★★ display.h | 生成显示设备，设定surface的数目，一个surface对应一个滑动页面 | 0.5小时 |\n| word.h | 显示文字 | < 1小时 |\n| image.h | 绘制位图，支持16 bits和32 bits | < 0.5小时 |\n| rect.h | UI元素的位置信息 | < 0.5小时 |\n| api_linux.cpp | Linux适配层 | < 0.5小时 |\n| api_win.cpp | Window适配层 | < 0.5小时 |\n| api_unknow.cpp | 无OS或其他OS适配层 | < 0.5小时 |\n***\n| widgets 难度/文件名称 | 代码简介 | 推荐学习时间 |\n| --- | --- | --- |\n| label.h | 标签控件的绘制 | < 0.5小时 |\n| button.h | 按钮控件的绘制及用户点击响应函数 | < 0.5小时 |\n| table.h | Table控件的绘制 | < 0.5小时 |\n| dialog.h | 对话框的绘制及管理方法 | < 0.5小时 |\n| ★ keyboard.h | 键盘控件的绘制及用户点击响应函数 | 0.5小时 |\n| ★★ list_box.h | List控件的绘制及用户点击响应函数 | 1.5小时 |\n| ★★ spinbox.h | Spinbox控件的绘制及用户点击响应函数 | 1.5小时 |\n| ★★ edit.h | Edit控件的绘制及用户点击响应函数 | 1.5小时 |\n| ★ slide_group.h | 多屏GUI的实现，以及用来切换屏幕的划屏操作 | 1.5小时 |\n| ★★★ wave_buffer.h | 波形数据的缓冲管理 | 1.5小时 |\n| ★★★ wave_ctrl.h | 它通过波形数据，绘制实时的波形控件 | 1.5小时 |\n\n## 函数注释\n| 函数名称 | display.h::c_display 函数接口注释 |\n| --- | --- |\n| c_display | c_display构造函数。phy_fb：物理framebuffer指针；display_width：物理显示器宽度；display_height：物理显示器高度；surface_width：surface宽度；surface_height：surface高度；color_bytes：颜色深度；surface_cnt：surface个数/滑动页面的个数；gfx_op：外部绘制接口，用以适配非framebuffer的渲染方式，如果该值不为空，surface在作底层渲染的时候，会调用该接口 |\n| alloc_surface | 分配surface/滑动页面。usr： 用户ID；max_zorder：该surface所拥有的图层数量|\n| merge_surface | 横向组合两个surface，多用于滑动surface。s0：源surface 0；s1：源surface 1，x0：源surface 0的起始点x坐标；x1：源surface 1的起始点x坐标；y0：源surface 0的起始点y坐标；y1：源surface 1的起始点y坐标；offset：横向组合的偏移距离 |\n| get_updated_fb | 获取该display的framebuffer指针，常用来将GUI显示在任意需要的地方。widght：用来获取framebuffer的宽度；height：用来获取framebuffer的高度；force_update：是否需要强制更新framebuffer的内容，如果不需要强制更新，且framebuffer没法发生变化，将返回NULL |\n| snap_shot | 生成当前显示的快照，并输出到bitmap文件。file_name：快照文件的名称 |\n***\n| 函数名称 | display.h::c_surface 函数接口注释 |\n| --- | --- |\n| c_surface | c_surface构造函数。 display：surface所属于的display；width：surface的宽度；height：surface的高度；color_bytes：颜色深度|\n| set_surface | 设置surface。wnd_root：使用者者ID，通常为root window，其子窗口自动获得该surface的使用权。 max_z_order：该surface拥有的图层数量 |\n| draw_pixel | 渲染一个像素点。x：像素点坐标x；y：像素点坐标y；rgb：像素颜色；z_order：像素所在的图层 |\n| draw_pixel_on_fb | 渲染一个像素点 - 底层渲染。x：像素点坐标x；y：像素点坐标y；rgb：像素颜色 |\n| fill_rect | 填充一个矩形。 x0：矩形左上角的坐标x；y0：矩形左上角的坐标y；x1：矩形右下角的坐标x；y1：矩形右下角的坐标y；rgb：矩形的颜色；z_order：矩形所在的图层|\n| fill_rect_on_fb | 填充一个矩形 - 底层渲染。 x0：矩形左上角的坐标x；y0：矩形左上角的坐标y；x1：矩形右下角的坐标x；y1：矩形右下角的坐标y；rgb：矩形的颜色 |\n| get_pixel | 获取指定位置的像素点的颜色值。x：位置坐标x；y：位置坐标y；z_order：位置坐标z（图层坐标） |\n| draw_hline | 渲染一条横线。x0：横线的左边起始坐标x；x1：横线的右边结尾坐标x；y：横线的纵向坐标y |\n| draw_vline | 渲染一条竖线。x：竖线的横向坐标：x；y0：竖线的上起始坐标y；y1：竖线的下结尾坐标y |\n| draw_line | 渲染普通直线。x1：直线左端点的坐标x；y1：直线左端点的坐标y；x2：直线右端点坐标x；y2：直线右端点坐标y |\n| draw_rect | 渲染矩形。x0：矩形左上角的坐标x；y0：矩形左上角的坐标y；x1：矩形右下角的坐标x；y1：矩形右下角的坐标y |\n| set_overlap_zone | 设置指定图层的可视区域（矩形），可视区域会根据图层优先级，自动进行上下叠加。rect：可视矩形的位置信息；z_order：图层的z坐标（图层坐标） |\n| flush_screen | 将当前surface的指定矩形区域一次性刷在显示屏上。left：surface指定区域的左边界坐标；top：surface指定区域的上边界坐标；right：surface指定区域的右边界坐标；bottom：surface指定区域的下边界坐标 |\n| is_valid | 判断给定位置的矩形，是否合理（是否在surface的范围内）。rect：矩形区域的坐标信息 |\n***\n| 函数名称 | wnd.cpp 函数接口注释 |\n| --- | --- |\n| c_wnd | c_wnd构造函数，进行基本初始化 |\n| connect | 把自己（this）、自己的子窗口系列及父窗口连接起来，形成完整的UI窗口链条；连接完成后，自己就可以响应用户输入及各种UI消息。parent：父窗口；resour_id：窗口ID；str：自己的窗口标题字符串；x：自己相对父窗口的坐标x；y：自己相对父窗口的坐标y；width：窗口宽度；height：窗口高度；p_child_tree：子窗口系列 |\n| load_child_wnd | 把一系列子窗口连接起来，形成完整的UI窗口链条；连接完成后，所有子窗口都可以响应用户输入及各种UI消息。p_child_tree：子窗口系列 |\n| disconnect | 把自己（this）跟父窗口、子窗口脱离连接，切断自己与UI的联系，不在响应用户输入及各种UI消息。 |\n| get_wnd_ptr | 获得指定窗口ID的窗口指针。id：窗口ID |\n| set_attr | 设置窗口属性，包括：普通、失效、可见。attr：属性值 |\n| is_focus_wnd | 判断自己（this）是否可以获得焦点 |\n| set_wnd_pos | 设置自己（this）相对于父窗口的窗口位置。x：窗口左上角坐标x；y：窗口左上角坐标y；width：窗口宽度；height：窗口高度 |\n| get_wnd_rect | 获取自己（this）相对于父窗口的位置信息。rect：用于输出位置信息 |\n| get_screen_rect | 获取自己（this）相对于UI系统的绝对位置信息。rect：用于输出位置信息 |\n| set_child_focus | 将自己（this）的一个子窗口设置为获得讲点状态。 focus_child：获得焦点的子窗口|\n| add_child_2_tail | 把一个子窗口添加到自己（this）的子窗口链表的尾部。child：被添加的子窗口 |\n| get_last_child | 获得自己（this）子窗口链表尾部的子窗口指针。 |\n| unlink_child | 将自己（this）的子窗口从子窗口链表中脱离出来。child：被脱链的子窗口 |\n| show_window | 渲染自己（this）及自己的子窗口 |\n| on_touch | 响应用户的触控消息。x：用户触控点的坐标x；y：用户触控点的坐标y；action：用户的触控类型，包括：按下，释放 |\n| on_key | 响应用户的按键消息。key：用户点击的按键键值。 |\n| notify_parent | 传递UI消息给自己（this）的父窗口，并调用父窗口对应的响应函数。msg_id：消息ID；ctrl_id：自己的资源ID，param：消息的参数 |\n\n## 速成路线图\n1. 精读源文件wnd.cpp中的connect, on_touch, on_key函数，理解界面元素的串联办法；理解响应触控操作的基本原理；理解响应硬按键的基本原理\n2. 快速浏览surface.cpp中用于绘制的draw_xxx函数，熟悉基本的绘制接口；精读c_surface构造函数，理解c_surface类的各种成员关系\n3. 精读button.cpp文件，初步掌握界面元素的基本开发方法\n4.  - 快速浏览HelloStar实例的BuildLinux/main.cpp，理解构建一般Linux应用的办法\n    - 快速浏览HelloStar实例的BuildMFC/HelloStarDlg.cpp，理解构建一般Windows应用的办法\n    - 快速浏览HelloStar实例的BuildSTM32F103-Keil/USER/main.c，理解构建一般单片机系统的办法\n"
  },
  {
    "path": "documents/HowToWork.md",
    "content": "# How GuiLite work\n- [What GuiLite do?](#What-GuiLite-do-)\n- [How to customize/extend GuiLite?](#How-to-customize/extend-GuiLite-)\n- [Code intro](#Code-intro)\n- [Widgets management](#Widgets-management)\n- [Rendering](#Rendering)\n***\n## What GuiLite do?\nGuiLite do 2 things only: widgets management and rendering.\n\nWidgets management include:\n- Add/Remove GUI element(e.g, button, label, dialog), set caption and location.\n- Dispatch/Response intput message: By analysis the location information from the message, GuiLite would find the widget which should be reponse, and call response function(e.g, on_mouse_click, on_keyboard_click)\n- Dispatch/Response customer message: By analysis the ID of message, GuiLite would find response funciotn, and calll it(: on_timer, on_custmer_refresh)\n\nRendering include:\n- Draw pixel, line, rect\n- Set frame layer; While your drawing, you should input frame layer index to make your drawing at a specific layer\n- Update frame layer; While frame layer changed(e.g, open/close dialog), GuiLite would determine which pixel of frame layer should be display on screen\n\n👉Note: Rendering do not depend on Widgets management, In some case, you would render line/text/bitmap directly without any widgets in your GUI system. For example: Limted resource MCU platform.\n\n## How to customize/extend GuiLite?\nIn order to make GuiLite simple and clear, GuiLite only provide basic widgets(e.g, button, label, keyboard, spinx etc) implementation. If you want do more things on widgets, you can do it like this:\n- Update widgets code in GuiLite directly\n- Add new widgets file, and implement new widgets by reference GuiLite widgets code.\n\nIf you would extend drawing method(e.g, draw circle/eclipse etc.), you can add your method in surface.cpp directly.\n\nHow to render?\nSee function draw_xxx() in surface.cpp word.cpp bitmap.cpp.\n\n## Code intro\ncore folder:\n- Implement message dispatch/response, multi frame layer management and rendering for all platforms\n- Adapter GuiLite on Windows/Linux/Android/iOS/macOS or none OS in adapter folder\n\nwidgets folder:\n- Here are code for controllers(eg. button, lable, keyboard) and containers(eg. view, dialog, flip pages); You can redraw your own widget by modify this code.\n- Here are code for message transition(eg. finger press/release), it will pass finger press/release message to widget which been touched, and call callback function if defined.\n\n## Widgets management\nWidgets include button, spinbox, label, keyboard, dialog, view; GuiLite will link all widgets by function: connect, then GuiLite will easy to find/add/remove any widget quickly. All the connections looks like a tree.\n\nFor example: When you click a button, device get your finger location(x, y) will be send the root of the tree, GuiLite would find the button you click by comparing location information, then call the response function(e.g, repaint the button/change button status)\n\n### How to create widgets?\nAll widgets derived from class c_wnd. The widget will be created when the class has been instanced, at this time, the widget still alone, has nothing to do with UI system, could not response any user operation.\n\n### How to link/unlink widgets\nBy using \"connect()\" function, we can link this widget into widgets tree, then the widgets could response user touch/keyboard action.\n\nBy using \"disconnect()\" function to unlink this widget from UI system. then the widget still live in memory, but could not response user touch/keyboard action any more.\n\n## Rendering\nRendering include rendering method and graphic management.\n- All rendering method base on draw_pixel() function\n- GuiLite support 3 frame layers so far, could handle 3 layers overlap senarios\n\n### Rendering method\n- Basic rendering function: surface_cpp.cpp::draw_xxx()\n- Bitmap rendering function: bitmap.cpp::draw_bitmap_xxx()\n- For take GPU advantage, you can refactor draw_xxx() by using GPU feature\n\n### Graphic layer\n![Graphic layer](GraphicLayer.png)![GuiLiteGraphic](GuiLiteGraphic.gif)\n- display layer：This layer for physical display device, one UI has only one display layer\n- surface layer: One display layer have many surface layers, one surface layer represent one flip page\n- frame layer: One surface layer has many frame layers, one frame layer represent one layer in Z direction\n\n## Source file annotation\n| core Importance/File name | Introduction | Time cost |\n| --- | --- | --- |\n| ★★★ wnd.h | Basic class for widgets; connect/disconnect widgets; response user on_touch, on_key action | 1.5 hour |\n| ★★ display.h | Initialize display device, create surface,  | 0.5 hour |\n| word.h | Draw text | < 1 hour |\n| image.h | Draw bitmap | < 0.5 hour |\n| rect.h | Rect for basic use(e.g, widgets location) | < 0.5 hour |\n| api_linux.cpp | Adapter for Linux | < 0.5 hour |\n| api_win.cpp | Adapter for Windows | < 0.5 hour |\n| api_unknow.cpp | Adapter for other OS or none OS | < 0.5 hour |\n***\n| widgets Difficulty/File name | Introduction | Time cost |\n| --- | --- | --- |\n| label.h | Draw label | < 0.5 hour |\n| button.h | Draw/Click button | < 0.5 hour |\n| table.h | Draw table | < 0.5 hour |\n| dialog.h | Draw/Open/Close dialog | < 0.5 hour |\n| ★ keyboard.h | Draw/Click keyboard | 0.5 hour |\n| ★★ list_box.h | Draw/Click list box | 1.5 hour |\n| ★★ spinbox.h | Draw/Click spin box | 1.5 hour |\n| ★★ edit.h | Draw/Click edit widget | 1.5 hour |\n| ★ slide_group.cpp | Draw multiple screens & Swip screen | 1.5 hour |\n| ★★★ wave_buffer.h | Manage wave buffer data | 1.5 hour |\n| ★★★ wave_ctrl.h | Draw wave widget with wave buffer data | 1.5 hour |\n"
  },
  {
    "path": "documents/UML.md",
    "content": "## Class structure\n![class-structure](uml-class.png)\n## UI process\n![ui-process](uml-ui-process.png)"
  },
  {
    "path": "src/.gitignore",
    "content": "# Prerequisites\n*.d\n\n# Compiled Object files\n*.slo\n*.lo\n*.o\n*.obj\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Compiled Dynamic libraries\n*.so\n*.dylib\n*.dll\n\n# Fortran module files\n*.mod\n*.smod\n\n# Executables\n# *.exe\n*.out\n*.app\n\n# Visual studio\nDebug\nRelease\n.vs\n\n# cmake\nCMakeCache.txt\nCMakeFiles\ncmake_install.cmake\nMakefile\n\nlibGuiLite.a\nlibGuiLite.so\n\n# Keil\nGuiLite.uvguix.*\nGuiLite.uvoptx\nObjects\nDebugConfig"
  },
  {
    "path": "src/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 2.8)\n\nPROJECT(GuiLite)\n\nSET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR})\n\nINCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})\n\nADD_DEFINITIONS(-DGUILITE_ON)\n\n# core\nFILE(GLOB CORE_SRC      core/*.cpp)\nFILE(GLOB CORE_ADAPTER  core/adapter/api_linux.cpp\n                        core/adapter/audio_linux.cpp)\n# widgets\nFILE(GLOB WIDGETS_SRC   widgets/*.cpp)\n\n# build static library\nADD_LIBRARY(GuiLite STATIC ${CORE_SRC} ${CORE_ADAPTER} ${WIDGETS_SRC})\n\n# build shared library\n# ADD_LIBRARY(GuiLite SHARED ${CORE_SRC} ${CORE_ADAPTER} ${WIDGETS_SRC})\n"
  },
  {
    "path": "src/GenerateGuiLite.h.sh",
    "content": "echo \"Build header-only library: GuiLite.h\"\n\n# build GuiLiteRaw.h\ncd core\ncat api.h resource.h theme.h display.h word.h image.h wnd.h > core.h\nmv core.h ../\ncd ..\n\ncd widgets\ncat button.h dialog.h keyboard.h edit.h label.h list_box.h slide_group.h spinbox.h table.h wave_buffer.h wave_ctrl.h > widgets.h\nmv widgets.h ../\ncd ..\n\ncat core.h widgets.h > GuiLiteRaw.h\n\n# build GuiLiteRaw.cpp\ncp core/core.cpp ./\ncp widgets/widgets.cpp ./\n\ncd core/adapter\ncat *.cpp > adapter.cpp\nmv adapter.cpp ../../\ncd ../..\n\ncat core.cpp adapter.cpp widgets.cpp > GuiLiteRaw.cpp\n# remove include core widgets from GuiLiteRaw.h\nsed -i '/^#include.*core\\|widgets.*/d' GuiLiteRaw.h\n# remove all #pragma once\nsed -i '/^#pragma once/d' GuiLiteRaw.h\n# add #pragma once for 1st line\nsed -i '1 s/^/#pragma once\\n/' GuiLiteRaw.h\n\n# remove include core widgets from GuiLiteRaw.cpp\nsed -i '/^#include.*core\\|widgets.*/d' GuiLiteRaw.cpp\n\n# Delete empty lines or blank lines\nsed '/^$/d' GuiLiteRaw.h > GuiLite.h\nsed '/^$/d' GuiLiteRaw.cpp > GuiLite.cpp\n\n# Append GuiLite.cpp to GuiLite.h\ncat GuiLite.cpp >> GuiLite.h\n\n# Verify\necho '#include \"GuiLite.h\"' > test.cpp\ngcc -c -D GUILITE_ON test.cpp\n\nmv GuiLite.h ../\necho \"Done!\"\necho \"You could find GuiLite.h in root folder\"\n\n# clean\nrm *.h *.cpp *.o\n"
  },
  {
    "path": "src/GuiLite.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 15\r\nVisualStudioVersion = 15.0.28307.572\r\nMinimumVisualStudioVersion = 10.0.40219.1\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"GuiLite\", \"GuiLite.vcxproj\", \"{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tDebug|x86 = Debug|x86\r\n\t\tRelease|x64 = Release|x64\r\n\t\tRelease|x86 = Release|x86\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}.Release|x64.Build.0 = Release|x64\r\n\t\t{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}.Release|x86.Build.0 = Release|Win32\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\t\tSolutionGuid = {50A71AAC-BDD2-499B-A992-6725DDB908AD}\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "src/GuiLite.uvprojx",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n<Project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"project_projx.xsd\">\n\n  <SchemaVersion>2.1</SchemaVersion>\n\n  <Header>### uVision Project, (C) Keil Software</Header>\n\n  <Targets>\n    <Target>\n      <TargetName>GuiLite</TargetName>\n      <ToolsetNumber>0x4</ToolsetNumber>\n      <ToolsetName>ARM-ADS</ToolsetName>\n      <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed>\n      <uAC6>0</uAC6>\n      <TargetOption>\n        <TargetCommonOption>\n          <Device>STM32F103ZE</Device>\n          <Vendor>STMicroelectronics</Vendor>\n          <PackID>Keil.STM32F1xx_DFP.2.3.0</PackID>\n          <PackURL>http://www.keil.com/pack/</PackURL>\n          <Cpu>IRAM(0x20000000,0x00010000) IROM(0x08000000,0x00080000) CPUTYPE(\"Cortex-M3\") CLOCK(12000000) ELITTLE</Cpu>\n          <FlashUtilSpec></FlashUtilSpec>\n          <StartupFile></StartupFile>\n          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_512 -FS08000000 -FL080000 -FP0($$Device:STM32F103ZE$Flash\\STM32F10x_512.FLM))</FlashDriverDll>\n          <DeviceId>0</DeviceId>\n          <RegisterFile>$$Device:STM32F103ZE$Device\\Include\\stm32f10x.h</RegisterFile>\n          <MemoryEnv></MemoryEnv>\n          <Cmp></Cmp>\n          <Asm></Asm>\n          <Linker></Linker>\n          <OHString></OHString>\n          <InfinionOptionDll></InfinionOptionDll>\n          <SLE66CMisc></SLE66CMisc>\n          <SLE66AMisc></SLE66AMisc>\n          <SLE66LinkerMisc></SLE66LinkerMisc>\n          <SFDFile>$$Device:STM32F103ZE$SVD\\STM32F103xx.svd</SFDFile>\n          <bCustSvd>0</bCustSvd>\n          <UseEnv>0</UseEnv>\n          <BinPath></BinPath>\n          <IncludePath></IncludePath>\n          <LibPath></LibPath>\n          <RegisterFilePath></RegisterFilePath>\n          <DBRegisterFilePath></DBRegisterFilePath>\n          <TargetStatus>\n            <Error>0</Error>\n            <ExitCodeStop>0</ExitCodeStop>\n            <ButtonStop>0</ButtonStop>\n            <NotGenerated>0</NotGenerated>\n            <InvalidFlash>1</InvalidFlash>\n          </TargetStatus>\n          <OutputDirectory>.\\Objects\\</OutputDirectory>\n          <OutputName>GuiLite</OutputName>\n          <CreateExecutable>0</CreateExecutable>\n          <CreateLib>1</CreateLib>\n          <CreateHexFile>0</CreateHexFile>\n          <DebugInformation>1</DebugInformation>\n          <BrowseInformation>1</BrowseInformation>\n          <ListingPath>.\\Listings\\</ListingPath>\n          <HexFormatSelection>1</HexFormatSelection>\n          <Merge32K>0</Merge32K>\n          <CreateBatchFile>0</CreateBatchFile>\n          <BeforeCompile>\n            <RunUserProg1>0</RunUserProg1>\n            <RunUserProg2>0</RunUserProg2>\n            <UserProg1Name></UserProg1Name>\n            <UserProg2Name></UserProg2Name>\n            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>\n            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>\n            <nStopU1X>0</nStopU1X>\n            <nStopU2X>0</nStopU2X>\n          </BeforeCompile>\n          <BeforeMake>\n            <RunUserProg1>0</RunUserProg1>\n            <RunUserProg2>0</RunUserProg2>\n            <UserProg1Name></UserProg1Name>\n            <UserProg2Name></UserProg2Name>\n            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>\n            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>\n            <nStopB1X>0</nStopB1X>\n            <nStopB2X>0</nStopB2X>\n          </BeforeMake>\n          <AfterMake>\n            <RunUserProg1>1</RunUserProg1>\n            <RunUserProg2>0</RunUserProg2>\n            <UserProg1Name></UserProg1Name>\n            <UserProg2Name></UserProg2Name>\n            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>\n            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>\n            <nStopA1X>0</nStopA1X>\n            <nStopA2X>0</nStopA2X>\n          </AfterMake>\n          <SelectedForBatchBuild>0</SelectedForBatchBuild>\n          <SVCSIdString></SVCSIdString>\n        </TargetCommonOption>\n        <CommonProperty>\n          <UseCPPCompiler>0</UseCPPCompiler>\n          <RVCTCodeConst>0</RVCTCodeConst>\n          <RVCTZI>0</RVCTZI>\n          <RVCTOtherData>0</RVCTOtherData>\n          <ModuleSelection>0</ModuleSelection>\n          <IncludeInBuild>1</IncludeInBuild>\n          <AlwaysBuild>0</AlwaysBuild>\n          <GenerateAssemblyFile>0</GenerateAssemblyFile>\n          <AssembleAssemblyFile>0</AssembleAssemblyFile>\n          <PublicsOnly>0</PublicsOnly>\n          <StopOnExitCode>3</StopOnExitCode>\n          <CustomArgument></CustomArgument>\n          <IncludeLibraryModules></IncludeLibraryModules>\n          <ComprImg>1</ComprImg>\n        </CommonProperty>\n        <DllOption>\n          <SimDllName>SARMCM3.DLL</SimDllName>\n          <SimDllArguments> -REMAP</SimDllArguments>\n          <SimDlgDll>DCM.DLL</SimDlgDll>\n          <SimDlgDllArguments>-pCM3</SimDlgDllArguments>\n          <TargetDllName>SARMCM3.DLL</TargetDllName>\n          <TargetDllArguments></TargetDllArguments>\n          <TargetDlgDll>TCM.DLL</TargetDlgDll>\n          <TargetDlgDllArguments>-pCM3</TargetDlgDllArguments>\n        </DllOption>\n        <DebugOption>\n          <OPTHX>\n            <HexSelection>1</HexSelection>\n            <HexRangeLowAddress>0</HexRangeLowAddress>\n            <HexRangeHighAddress>0</HexRangeHighAddress>\n            <HexOffset>0</HexOffset>\n            <Oh166RecLen>16</Oh166RecLen>\n          </OPTHX>\n        </DebugOption>\n        <Utilities>\n          <Flash1>\n            <UseTargetDll>1</UseTargetDll>\n            <UseExternalTool>0</UseExternalTool>\n            <RunIndependent>0</RunIndependent>\n            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>\n            <Capability>1</Capability>\n            <DriverSelection>-1</DriverSelection>\n          </Flash1>\n          <bUseTDR>1</bUseTDR>\n          <Flash2>BIN\\UL2CM3.DLL</Flash2>\n          <Flash3></Flash3>\n          <Flash4></Flash4>\n          <pFcarmOut></pFcarmOut>\n          <pFcarmGrp></pFcarmGrp>\n          <pFcArmRoot></pFcArmRoot>\n          <FcArmLst>0</FcArmLst>\n        </Utilities>\n        <TargetArmAds>\n          <ArmAdsMisc>\n            <GenerateListings>0</GenerateListings>\n            <asHll>1</asHll>\n            <asAsm>1</asAsm>\n            <asMacX>1</asMacX>\n            <asSyms>1</asSyms>\n            <asFals>1</asFals>\n            <asDbgD>1</asDbgD>\n            <asForm>1</asForm>\n            <ldLst>0</ldLst>\n            <ldmm>1</ldmm>\n            <ldXref>1</ldXref>\n            <BigEnd>0</BigEnd>\n            <AdsALst>1</AdsALst>\n            <AdsACrf>1</AdsACrf>\n            <AdsANop>0</AdsANop>\n            <AdsANot>0</AdsANot>\n            <AdsLLst>1</AdsLLst>\n            <AdsLmap>1</AdsLmap>\n            <AdsLcgr>1</AdsLcgr>\n            <AdsLsym>1</AdsLsym>\n            <AdsLszi>1</AdsLszi>\n            <AdsLtoi>1</AdsLtoi>\n            <AdsLsun>1</AdsLsun>\n            <AdsLven>1</AdsLven>\n            <AdsLsxf>1</AdsLsxf>\n            <RvctClst>0</RvctClst>\n            <GenPPlst>0</GenPPlst>\n            <AdsCpuType>\"Cortex-M3\"</AdsCpuType>\n            <RvctDeviceName></RvctDeviceName>\n            <mOS>0</mOS>\n            <uocRom>0</uocRom>\n            <uocRam>0</uocRam>\n            <hadIROM>1</hadIROM>\n            <hadIRAM>1</hadIRAM>\n            <hadXRAM>0</hadXRAM>\n            <uocXRam>0</uocXRam>\n            <RvdsVP>0</RvdsVP>\n            <RvdsMve>0</RvdsMve>\n            <hadIRAM2>0</hadIRAM2>\n            <hadIROM2>0</hadIROM2>\n            <StupSel>8</StupSel>\n            <useUlib>0</useUlib>\n            <EndSel>0</EndSel>\n            <uLtcg>0</uLtcg>\n            <nSecure>0</nSecure>\n            <RoSelD>3</RoSelD>\n            <RwSelD>3</RwSelD>\n            <CodeSel>0</CodeSel>\n            <OptFeed>0</OptFeed>\n            <NoZi1>0</NoZi1>\n            <NoZi2>0</NoZi2>\n            <NoZi3>0</NoZi3>\n            <NoZi4>0</NoZi4>\n            <NoZi5>0</NoZi5>\n            <Ro1Chk>0</Ro1Chk>\n            <Ro2Chk>0</Ro2Chk>\n            <Ro3Chk>0</Ro3Chk>\n            <Ir1Chk>1</Ir1Chk>\n            <Ir2Chk>0</Ir2Chk>\n            <Ra1Chk>0</Ra1Chk>\n            <Ra2Chk>0</Ra2Chk>\n            <Ra3Chk>0</Ra3Chk>\n            <Im1Chk>1</Im1Chk>\n            <Im2Chk>0</Im2Chk>\n            <OnChipMemories>\n              <Ocm1>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </Ocm1>\n              <Ocm2>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </Ocm2>\n              <Ocm3>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </Ocm3>\n              <Ocm4>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </Ocm4>\n              <Ocm5>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </Ocm5>\n              <Ocm6>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </Ocm6>\n              <IRAM>\n                <Type>0</Type>\n                <StartAddress>0x20000000</StartAddress>\n                <Size>0x10000</Size>\n              </IRAM>\n              <IROM>\n                <Type>1</Type>\n                <StartAddress>0x8000000</StartAddress>\n                <Size>0x80000</Size>\n              </IROM>\n              <XRAM>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </XRAM>\n              <OCR_RVCT1>\n                <Type>1</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </OCR_RVCT1>\n              <OCR_RVCT2>\n                <Type>1</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </OCR_RVCT2>\n              <OCR_RVCT3>\n                <Type>1</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </OCR_RVCT3>\n              <OCR_RVCT4>\n                <Type>1</Type>\n                <StartAddress>0x8000000</StartAddress>\n                <Size>0x80000</Size>\n              </OCR_RVCT4>\n              <OCR_RVCT5>\n                <Type>1</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </OCR_RVCT5>\n              <OCR_RVCT6>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </OCR_RVCT6>\n              <OCR_RVCT7>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </OCR_RVCT7>\n              <OCR_RVCT8>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </OCR_RVCT8>\n              <OCR_RVCT9>\n                <Type>0</Type>\n                <StartAddress>0x20000000</StartAddress>\n                <Size>0x10000</Size>\n              </OCR_RVCT9>\n              <OCR_RVCT10>\n                <Type>0</Type>\n                <StartAddress>0x0</StartAddress>\n                <Size>0x0</Size>\n              </OCR_RVCT10>\n            </OnChipMemories>\n            <RvctStartVector></RvctStartVector>\n          </ArmAdsMisc>\n          <Cads>\n            <interw>1</interw>\n            <Optim>1</Optim>\n            <oTime>0</oTime>\n            <SplitLS>0</SplitLS>\n            <OneElfS>0</OneElfS>\n            <Strict>0</Strict>\n            <EnumInt>0</EnumInt>\n            <PlainCh>0</PlainCh>\n            <Ropi>0</Ropi>\n            <Rwpi>0</Rwpi>\n            <wLevel>0</wLevel>\n            <uThumb>0</uThumb>\n            <uSurpInc>0</uSurpInc>\n            <uC99>0</uC99>\n            <uGnu>0</uGnu>\n            <useXO>0</useXO>\n            <v6Lang>1</v6Lang>\n            <v6LangP>1</v6LangP>\n            <vShortEn>1</vShortEn>\n            <vShortWch>1</vShortWch>\n            <v6Lto>0</v6Lto>\n            <v6WtE>0</v6WtE>\n            <v6Rtti>0</v6Rtti>\n            <VariousControls>\n              <MiscControls></MiscControls>\n              <Define></Define>\n              <Undefine></Undefine>\n              <IncludePath>./</IncludePath>\n            </VariousControls>\n          </Cads>\n          <Aads>\n            <interw>1</interw>\n            <Ropi>0</Ropi>\n            <Rwpi>0</Rwpi>\n            <thumb>0</thumb>\n            <SplitLS>0</SplitLS>\n            <SwStkChk>0</SwStkChk>\n            <NoWarn>0</NoWarn>\n            <uSurpInc>0</uSurpInc>\n            <useXO>0</useXO>\n            <uClangAs>0</uClangAs>\n            <VariousControls>\n              <MiscControls></MiscControls>\n              <Define></Define>\n              <Undefine></Undefine>\n              <IncludePath></IncludePath>\n            </VariousControls>\n          </Aads>\n          <LDads>\n            <umfTarg>0</umfTarg>\n            <Ropi>0</Ropi>\n            <Rwpi>0</Rwpi>\n            <noStLib>0</noStLib>\n            <RepFail>1</RepFail>\n            <useFile>0</useFile>\n            <TextAddressRange>0x00000000</TextAddressRange>\n            <DataAddressRange>0x20000000</DataAddressRange>\n            <pXoBase></pXoBase>\n            <ScatterFile></ScatterFile>\n            <IncludeLibs></IncludeLibs>\n            <IncludeLibsPath></IncludeLibsPath>\n            <Misc></Misc>\n            <LinkerInputFile></LinkerInputFile>\n            <DisabledWarnings></DisabledWarnings>\n          </LDads>\n        </TargetArmAds>\n      </TargetOption>\n      <Groups>\n        <Group>\n          <GroupName>core</GroupName>\n          <Files>\n            <File>\n              <FileName>api_unknow.cpp</FileName>\n              <FileType>8</FileType>\n              <FilePath>.\\core\\adapter\\api_unknow.cpp</FilePath>\n            </File>\n            <File>\n              <FileName>core.cpp</FileName>\n              <FileType>8</FileType>\n              <FilePath>.\\core\\core.cpp</FilePath>\n            </File>\n          </Files>\n        </Group>\n        <Group>\n          <GroupName>widgets</GroupName>\n          <Files>\n            <File>\n              <FileName>widgets.cpp</FileName>\n              <FileType>8</FileType>\n              <FilePath>.\\widgets\\widgets.cpp</FilePath>\n            </File>\n          </Files>\n        </Group>\n      </Groups>\n    </Target>\n  </Targets>\n\n  <RTE>\n    <apis/>\n    <components/>\n    <files/>\n  </RTE>\n\n</Project>\n"
  },
  {
    "path": "src/GuiLite.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"MinSizeRel|x64\">\r\n      <Configuration>MinSizeRel</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"MinSizeRel|Win32\">\r\n      <Configuration>MinSizeRel</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"RelWithDebInfo|Win32\">\r\n      <Configuration>RelWithDebInfo</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"RelWithDebInfo|x64\">\r\n      <Configuration>RelWithDebInfo</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <ProjectGuid>{DF7A4FAD-A68D-3E43-9C4B-7DE4EE77F732}</ProjectGuid>\r\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <Platform>Win32</Platform>\r\n    <ProjectName>GuiLite</ProjectName>\r\n    <VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <CharacterSet>MultiByte</CharacterSet>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='MinSizeRel|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <CharacterSet>MultiByte</CharacterSet>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <CharacterSet>MultiByte</CharacterSet>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <CharacterSet>MultiByte</CharacterSet>\r\n    <PlatformToolset>v141</PlatformToolset>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup>\r\n    <_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>\r\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(SolutionDir)$(Configuration)\\</OutDir>\r\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(Configuration)\\</IntDir>\r\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectName)</TargetName>\r\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectName)</TargetName>\r\n    <TargetExt Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">.lib</TargetExt>\r\n    <TargetExt Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">.lib</TargetExt>\r\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(SolutionDir)$(Configuration)\\</OutDir>\r\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(Configuration)\\</IntDir>\r\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectName)</TargetName>\r\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectName)</TargetName>\r\n    <TargetExt Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">.lib</TargetExt>\r\n    <TargetExt Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">.lib</TargetExt>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <OutDir>$(SolutionDir)$(Configuration)\\</OutDir>\r\n    <IntDir>$(Configuration)\\</IntDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <OutDir>$(SolutionDir)$(Configuration)\\</OutDir>\r\n    <IntDir>$(Configuration)\\</IntDir>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AssemblerListingLocation>Debug/</AssemblerListingLocation>\r\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r\n      <CompileAs>CompileAsCpp</CompileAs>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n      <ExceptionHandling>Sync</ExceptionHandling>\r\n      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>\r\n      <Optimization>Disabled</Optimization>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ObjectFileName>$(IntDir)</ObjectFileName>\r\n    </ClCompile>\r\n    <ResourceCompile>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;CMAKE_INTDIR=\\\"Debug\\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ResourceCompile>\r\n    <Midl>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>\r\n      <HeaderFileName>%(Filename).h</HeaderFileName>\r\n      <TypeLibraryName>%(Filename).tlb</TypeLibraryName>\r\n      <InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>\r\n      <ProxyFileName>%(Filename)_p.c</ProxyFileName>\r\n    </Midl>\r\n    <Lib>\r\n      <AdditionalOptions>%(AdditionalOptions) /machine:X86</AdditionalOptions>\r\n    </Lib>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AssemblerListingLocation>Debug/</AssemblerListingLocation>\r\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r\n      <CompileAs>CompileAsCpp</CompileAs>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n      <ExceptionHandling>Sync</ExceptionHandling>\r\n      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>\r\n      <Optimization>Disabled</Optimization>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PreprocessorDefinitions>GUILITE_ON;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ObjectFileName>$(IntDir)</ObjectFileName>\r\n    </ClCompile>\r\n    <ResourceCompile>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;CMAKE_INTDIR=\\\"Debug\\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ResourceCompile>\r\n    <Midl>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>\r\n      <HeaderFileName>%(Filename).h</HeaderFileName>\r\n      <TypeLibraryName>%(Filename).tlb</TypeLibraryName>\r\n      <InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>\r\n      <ProxyFileName>%(Filename)_p.c</ProxyFileName>\r\n    </Midl>\r\n    <Lib>\r\n      <AdditionalOptions>%(AdditionalOptions) /machine:X64</AdditionalOptions>\r\n    </Lib>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AssemblerListingLocation>Release/</AssemblerListingLocation>\r\n      <CompileAs>CompileAsCpp</CompileAs>\r\n      <ExceptionHandling>Sync</ExceptionHandling>\r\n      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ObjectFileName>$(IntDir)</ObjectFileName>\r\n      <DebugInformationFormat>\r\n      </DebugInformationFormat>\r\n    </ClCompile>\r\n    <ResourceCompile>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\\\"Release\\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ResourceCompile>\r\n    <Midl>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>\r\n      <HeaderFileName>%(Filename).h</HeaderFileName>\r\n      <TypeLibraryName>%(Filename).tlb</TypeLibraryName>\r\n      <InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>\r\n      <ProxyFileName>%(Filename)_p.c</ProxyFileName>\r\n    </Midl>\r\n    <Lib>\r\n      <AdditionalOptions>%(AdditionalOptions) /machine:X86</AdditionalOptions>\r\n    </Lib>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AssemblerListingLocation>Release/</AssemblerListingLocation>\r\n      <CompileAs>CompileAsCpp</CompileAs>\r\n      <ExceptionHandling>Sync</ExceptionHandling>\r\n      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ObjectFileName>$(IntDir)</ObjectFileName>\r\n      <DebugInformationFormat>\r\n      </DebugInformationFormat>\r\n    </ClCompile>\r\n    <ResourceCompile>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\\\"Release\\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ResourceCompile>\r\n    <Midl>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>\r\n      <HeaderFileName>%(Filename).h</HeaderFileName>\r\n      <TypeLibraryName>%(Filename).tlb</TypeLibraryName>\r\n      <InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>\r\n      <ProxyFileName>%(Filename)_p.c</ProxyFileName>\r\n    </Midl>\r\n    <Lib>\r\n      <AdditionalOptions>%(AdditionalOptions) /machine:X64</AdditionalOptions>\r\n    </Lib>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AssemblerListingLocation>MinSizeRel/</AssemblerListingLocation>\r\n      <CompileAs>CompileAsCpp</CompileAs>\r\n      <ExceptionHandling>Sync</ExceptionHandling>\r\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r\n      <Optimization>MinSpace</Optimization>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"MinSizeRel\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ObjectFileName>$(IntDir)</ObjectFileName>\r\n      <DebugInformationFormat>\r\n      </DebugInformationFormat>\r\n    </ClCompile>\r\n    <ResourceCompile>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\\\"MinSizeRel\\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ResourceCompile>\r\n    <Midl>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>\r\n      <HeaderFileName>%(Filename).h</HeaderFileName>\r\n      <TypeLibraryName>%(Filename).tlb</TypeLibraryName>\r\n      <InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>\r\n      <ProxyFileName>%(Filename)_p.c</ProxyFileName>\r\n    </Midl>\r\n    <Lib>\r\n      <AdditionalOptions>%(AdditionalOptions) /machine:X86</AdditionalOptions>\r\n    </Lib>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='MinSizeRel|x64'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AssemblerListingLocation>MinSizeRel/</AssemblerListingLocation>\r\n      <CompileAs>CompileAsCpp</CompileAs>\r\n      <ExceptionHandling>Sync</ExceptionHandling>\r\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r\n      <Optimization>MinSpace</Optimization>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"MinSizeRel\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ObjectFileName>$(IntDir)</ObjectFileName>\r\n      <DebugInformationFormat>\r\n      </DebugInformationFormat>\r\n    </ClCompile>\r\n    <ResourceCompile>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\\\"MinSizeRel\\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ResourceCompile>\r\n    <Midl>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>\r\n      <HeaderFileName>%(Filename).h</HeaderFileName>\r\n      <TypeLibraryName>%(Filename).tlb</TypeLibraryName>\r\n      <InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>\r\n      <ProxyFileName>%(Filename)_p.c</ProxyFileName>\r\n    </Midl>\r\n    <Lib>\r\n      <AdditionalOptions>%(AdditionalOptions) /machine:X86</AdditionalOptions>\r\n    </Lib>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AssemblerListingLocation>RelWithDebInfo/</AssemblerListingLocation>\r\n      <CompileAs>CompileAsCpp</CompileAs>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n      <ExceptionHandling>Sync</ExceptionHandling>\r\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"RelWithDebInfo\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ObjectFileName>$(IntDir)</ObjectFileName>\r\n    </ClCompile>\r\n    <ResourceCompile>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\\\"RelWithDebInfo\\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ResourceCompile>\r\n    <Midl>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>\r\n      <HeaderFileName>%(Filename).h</HeaderFileName>\r\n      <TypeLibraryName>%(Filename).tlb</TypeLibraryName>\r\n      <InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>\r\n      <ProxyFileName>%(Filename)_p.c</ProxyFileName>\r\n    </Midl>\r\n    <Lib>\r\n      <AdditionalOptions>%(AdditionalOptions) /machine:X86</AdditionalOptions>\r\n    </Lib>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AssemblerListingLocation>RelWithDebInfo/</AssemblerListingLocation>\r\n      <CompileAs>CompileAsCpp</CompileAs>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n      <ExceptionHandling>Sync</ExceptionHandling>\r\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"RelWithDebInfo\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ObjectFileName>$(IntDir)</ObjectFileName>\r\n    </ClCompile>\r\n    <ResourceCompile>\r\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\\\"RelWithDebInfo\\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ResourceCompile>\r\n    <Midl>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>\r\n      <HeaderFileName>%(Filename).h</HeaderFileName>\r\n      <TypeLibraryName>%(Filename).tlb</TypeLibraryName>\r\n      <InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>\r\n      <ProxyFileName>%(Filename)_p.c</ProxyFileName>\r\n    </Midl>\r\n    <Lib>\r\n      <AdditionalOptions>%(AdditionalOptions) /machine:X86</AdditionalOptions>\r\n    </Lib>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"core\\adapter\\api_win.cpp\" />\r\n    <ClCompile Include=\"core\\core.cpp\" />\r\n    <ClCompile Include=\"widgets\\widgets.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"core\\api.h\" />\r\n    <ClInclude Include=\"core\\display.h\" />\r\n    <ClInclude Include=\"core\\image.h\" />\r\n    <ClInclude Include=\"core\\resource.h\" />\r\n    <ClInclude Include=\"core\\theme.h\" />\r\n    <ClInclude Include=\"core\\wnd.h\" />\r\n    <ClInclude Include=\"core\\word.h\" />\r\n    <ClInclude Include=\"widgets\\button.h\" />\r\n    <ClInclude Include=\"widgets\\dialog.h\" />\r\n    <ClInclude Include=\"widgets\\edit.h\" />\r\n    <ClInclude Include=\"widgets\\keyboard.h\" />\r\n    <ClInclude Include=\"widgets\\label.h\" />\r\n    <ClInclude Include=\"widgets\\list_box.h\" />\r\n    <ClInclude Include=\"widgets\\slide_group.h\" />\r\n    <ClInclude Include=\"widgets\\spinbox.h\" />\r\n    <ClInclude Include=\"widgets\\table.h\" />\r\n    <ClInclude Include=\"widgets\\wave_buffer.h\" />\r\n    <ClInclude Include=\"widgets\\wave_ctrl.h\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "src/GuiLite.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <ClCompile Include=\"widgets\\widgets.cpp\">\r\n      <Filter>widgets</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"core\\adapter\\api_win.cpp\">\r\n      <Filter>core\\adapter</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"core\\core.cpp\">\r\n      <Filter>core</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Filter Include=\"core\">\r\n      <UniqueIdentifier>{90BF9B29-451D-34AC-BF45-13C635ED39CD}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"widgets\">\r\n      <UniqueIdentifier>{338d9696-2a1d-4569-b435-dd3da382a8d2}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"core\\adapter\">\r\n      <UniqueIdentifier>{691801eb-7076-4af6-aa0c-5ce5b0fcb21c}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"core\\api.h\">\r\n      <Filter>core</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"core\\display.h\">\r\n      <Filter>core</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"core\\image.h\">\r\n      <Filter>core</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"core\\resource.h\">\r\n      <Filter>core</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"core\\theme.h\">\r\n      <Filter>core</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"core\\wnd.h\">\r\n      <Filter>core</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"core\\word.h\">\r\n      <Filter>core</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\button.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\dialog.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\edit.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\keyboard.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\label.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\list_box.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\slide_group.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\spinbox.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\table.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\wave_buffer.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"widgets\\wave_ctrl.h\">\r\n      <Filter>widgets</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/core/adapter/api_linux.cpp",
    "content": "#ifdef GUILITE_ON\n#if ((defined __linux__) && (!defined __none_os__)) || (defined __APPLE__)\n\n#include \"../../core/api.h\"\n#include <unistd.h>\n#include <pthread.h>\n#include <string.h>\n#include <time.h>\n#include <sys/time.h>\n#include <signal.h>\n#include <sys/times.h>\n#include <fcntl.h>\n#include <termios.h>\n#include <sys/stat.h>\n#include <semaphore.h>\n#include <errno.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#define MAX_TIMER_CNT 10\n#define TIMER_UNIT 50//ms\n\nstatic void(*do_assert)(const char* file, int line);\nstatic void(*do_log_out)(const char* log);\nvoid register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))\n{\n\tdo_assert = my_assert;\n\tdo_log_out = my_log_out;\n}\n\nvoid _assert(const char* file, int line)\n{\n\tif(do_assert)\n\t{\n\t\tdo_assert(file, line);\n\t}\n\telse\n\t{\n\t\tprintf(\"assert@ file:%s, line:%d, error no: %d\\n\", file, line, errno);\n\t} \n}\n\nvoid log_out(const char* log)\n{\n\tif (do_log_out)\n\t{\n\t\tdo_log_out(log);\n\t}\n\telse\n\t{\n\t\tprintf(\"%s\", log);\n\t\tfflush(stdout);\n\t}\n}\n\ntypedef struct _timer_manage\n{\n    struct  _timer_info\n    {\n        int state; /* on or off */\n        int interval;\n        int elapse; /* 0~interval */\n        void (* timer_proc) (void* param);\n\t\tvoid* param;\n    }timer_info[MAX_TIMER_CNT];\n\n    void (* old_sigfunc)(int);\n    void (* new_sigfunc)(int);\n}_timer_manage_t;\nstatic struct _timer_manage timer_manage;\n\nstatic void* timer_routine(void*)\n{\n    int i;\n    while(true)\n    {\n    \tfor(i = 0; i < MAX_TIMER_CNT; i++)\n\t\t{\n\t\t\tif(timer_manage.timer_info[i].state == 0)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttimer_manage.timer_info[i].elapse++;\n\t\t\tif(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)\n\t\t\t{\n\t\t\t\ttimer_manage.timer_info[i].elapse = 0;\n\t\t\t\ttimer_manage.timer_info[i].timer_proc(timer_manage.timer_info[i].param);\n\t\t\t}\n\t\t}\n    \tusleep(1000 * TIMER_UNIT);\n    }\n    return NULL;\n}\n\nstatic int init_mul_timer()\n{\n\tstatic bool s_is_init = false;\n\tif(s_is_init == true)\n\t{\n\t\treturn 0;\n\t}\n    memset(&timer_manage, 0, sizeof(struct _timer_manage));\n    pthread_t pid;\n    pthread_create(&pid, NULL, timer_routine, NULL);\n    s_is_init = true;\n    return 1;\n}\n\nstatic int set_a_timer(int interval, void (* timer_proc)(void* param), void* param)\n{\n\tinit_mul_timer();\n\n\tint i;\n    if(timer_proc == NULL || interval <= 0)\n    {\n        return (-1);\n    }\n\n    for(i = 0; i < MAX_TIMER_CNT; i++)\n    {\n        if(timer_manage.timer_info[i].state == 1)\n        {\n            continue;\n        }\n        memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));\n        timer_manage.timer_info[i].timer_proc = timer_proc;\n\t\ttimer_manage.timer_info[i].param = param;\n        timer_manage.timer_info[i].interval = interval;\n        timer_manage.timer_info[i].elapse = 0;\n        timer_manage.timer_info[i].state = 1;\n        break;\n    }\n\n    if(i >= MAX_TIMER_CNT)\n    {\n    \tASSERT(false);\n        return (-1);\n    }\n    return (i);\n}\n\ntypedef void (*EXPIRE_ROUTINE)(void* arg);\nEXPIRE_ROUTINE s_expire_function;\nstatic c_fifo s_real_timer_fifo;\n\nstatic void* real_timer_routine(void*)\n{\n\tchar dummy;\n\twhile(1)\n\t{\n\t\tif(s_real_timer_fifo.read(&dummy, 1) > 0)\n\t\t{\n\t\t\tif(s_expire_function)s_expire_function(0);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tASSERT(false);\n\t\t}\n\t}\n\treturn 0;\n}\n\nstatic void expire_real_timer(int sigo)\n{\n\tchar dummy = 0x33;\n\tif(s_real_timer_fifo.write(&dummy, 1) <= 0)\n\t{\n\t\tASSERT(false);\n\t}\n}\n\nvoid start_real_timer(void (*func)(void* arg))\n{\n\tif(NULL == func)\n\t{\n\t\treturn;\n\t}\n\n\ts_expire_function = func;\n\tsignal(SIGALRM, expire_real_timer);\n\tstruct itimerval value, ovalue;\n\tvalue.it_value.tv_sec = 0;\n\tvalue.it_value.tv_usec = REAL_TIME_TASK_CYCLE_MS * 1000;\n\tvalue.it_interval.tv_sec = 0;\n\tvalue.it_interval.tv_usec = REAL_TIME_TASK_CYCLE_MS * 1000;\n\tsetitimer(ITIMER_REAL, &value, &ovalue);\n\n\tstatic pthread_t s_pid;\n\tif(s_pid == 0)\n\t{\n\t\tpthread_create(&s_pid, NULL, real_timer_routine, NULL);\n\t}\n}\n\nunsigned int get_cur_thread_id()\n{\n\treturn (unsigned long)pthread_self();\n}\n\nvoid register_timer(int milli_second,void func(void* param), void* param)\n{\n\tset_a_timer(milli_second/TIMER_UNIT,func, param);\n}\n\nlong get_time_in_second()\n{\n\treturn time(NULL);         /* + 8*60*60*/\n}\n\nT_TIME get_time()\n{\n\tT_TIME ret = {0};\n\tstruct tm *fmt;\n\ttime_t timer;\n\n\ttimer = get_time_in_second();\n\tfmt = localtime(&timer);\n\tret.year   = fmt->tm_year + 1900;\n\tret.month  = fmt->tm_mon + 1;\n\tret.day    = fmt->tm_mday;\n\tret.hour   = fmt->tm_hour;\n\tret.minute = fmt->tm_min;\n\tret.second = fmt->tm_sec;\n\treturn ret;\n}\n\nT_TIME second_to_day(long second)\n{\n\tT_TIME ret = {0};\n\tstruct tm *fmt;\n\tfmt = localtime(&second);\n\tret.year   = fmt->tm_year + 1900;\n\tret.month  = fmt->tm_mon + 1;\n\tret.day    = fmt->tm_mday;\n\tret.hour   = fmt->tm_hour;\n\tret.minute = fmt->tm_min;\n\tret.second = fmt->tm_sec;\n\treturn ret;\n}\n\nvoid create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)\n{\n    pthread_create((pthread_t*)thread_id, (pthread_attr_t const*)attr, start_routine, arg);\n}\n\nvoid thread_sleep(unsigned int milli_seconds)\n{\n\tusleep(milli_seconds * 1000);\n}\n\ntypedef struct {\n\tunsigned short\tbfType;\n\tunsigned int   \tbfSize;\n\tunsigned short  bfReserved1;\n\tunsigned short  bfReserved2;\n\tunsigned int   \tbfOffBits;\n}__attribute__((packed))FileHead;\n\ntypedef struct{\n\tunsigned int  \tbiSize;\n\tint \t\t\tbiWidth;\n\tint       \t\tbiHeight;\n\tunsigned short\tbiPlanes;\n\tunsigned short  biBitCount;\n\tunsigned int    biCompress;\n\tunsigned int    biSizeImage;\n\tint       \t\tbiXPelsPerMeter;\n\tint       \t\tbiYPelsPerMeter;\n\tunsigned int \tbiClrUsed;\n\tunsigned int    biClrImportant;\n\tunsigned int \tbiRedMask;\n\tunsigned int \tbiGreenMask;\n\tunsigned int \tbiBlueMask;\n}__attribute__((packed))Infohead;\n\nint build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)\n{\n\tFileHead bmp_head;\n\tInfohead bmp_info;\n\tint size = width * height * 2;\n\n\t//initialize bmp head.\n\tbmp_head.bfType = 0x4d42;\n\tbmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead);\n\tbmp_head.bfReserved1 = bmp_head.bfReserved2 = 0;\n\tbmp_head.bfOffBits = bmp_head.bfSize - size;\n\n\t//initialize bmp info.\n\tbmp_info.biSize = 40;\n\tbmp_info.biWidth = width;\n\tbmp_info.biHeight = height;\n\tbmp_info.biPlanes = 1;\n\tbmp_info.biBitCount = 16;\n\tbmp_info.biCompress = 3;\n\tbmp_info.biSizeImage = size;\n\tbmp_info.biXPelsPerMeter = 0;\n\tbmp_info.biYPelsPerMeter = 0;\n\tbmp_info.biClrUsed = 0;\n\tbmp_info.biClrImportant = 0;\n\n\t//RGB565\n\tbmp_info.biRedMask = 0xF800;\n\tbmp_info.biGreenMask = 0x07E0;\n\tbmp_info.biBlueMask = 0x001F;\n\n\t//copy the data\n\tFILE *fp;\n\tif(!(fp=fopen(filename,\"wb\")))\n\t{\n\t\treturn -1;\n\t}\n\n\tfwrite(&bmp_head, 1, sizeof(FileHead),fp);\n\tfwrite(&bmp_info, 1, sizeof(Infohead),fp);\n\n\t//fwrite(data, 1, size, fp);//top <-> bottom\n\tfor (int i = (height - 1); i >= 0; --i)\n\t{\n\t\tfwrite(&data[i * width * 2], 1, width * 2, fp);\n\t}\n\t\n\tfclose(fp);\n\treturn 0;\n}\n\nc_fifo::c_fifo()\n{\n\tm_head = m_tail = 0;\n\tm_read_sem = malloc(sizeof(sem_t));\n\tm_write_mutex = malloc(sizeof(pthread_mutex_t));\n\t\n\tsem_init((sem_t*)m_read_sem, 0, 0);\n\tpthread_mutex_init((pthread_mutex_t*)m_write_mutex, 0);\n}\n\nint c_fifo::read(void* buf, int len)\n{\n\tunsigned char* pbuf = (unsigned char*)buf;\n\tint i = 0;\n\twhile(i < len)\n\t{\n\t\tif (m_tail == m_head)\n\t\t{//empty\n\t\t\tsem_wait((sem_t*)m_read_sem);\n\t\t\tcontinue;\n\t\t}\n\t\t*pbuf++ = m_buf[m_head];\n\t\tm_head = (m_head + 1) % FIFO_BUFFER_LEN;\n\t\ti++;\n\t}\n\tif(i != len)\n\t{\n\t\tASSERT(false);\n\t}\n\treturn i;\n}\n\nint c_fifo::write(void* buf, int len)\n{\n\tunsigned char* pbuf = (unsigned char*)buf;\n\tint i = 0;\n\tint tail = m_tail;\n\n\tpthread_mutex_lock((pthread_mutex_t*)m_write_mutex);\n\twhile(i < len)\n\t{\n\t\tif ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)\n\t\t{//full, clear data has been written;\n\t\t\tm_tail = tail;\n\t\t\tlog_out(\"Warning: fifo full\\n\");\n\t\t\tpthread_mutex_unlock((pthread_mutex_t*)m_write_mutex);\n\t\t\treturn 0;\n\t\t}\n\t\tm_buf[m_tail] = *pbuf++;\n\t\tm_tail = (m_tail + 1) % FIFO_BUFFER_LEN;\n\t\ti++;\n\t}\n\tpthread_mutex_unlock((pthread_mutex_t*)m_write_mutex);\n\n\tif(i != len)\n\t{\n\t\tASSERT(false);\n\t}\n\telse\n\t{\n\t\tsem_post((sem_t*)m_read_sem);\n\t}\n\treturn i;\n}\n\n#endif\n#endif\n"
  },
  {
    "path": "src/core/adapter/api_unknow.cpp",
    "content": "#ifdef GUILITE_ON\r\n#if (defined __none_os__) || ((!defined _WIN32) && (!defined WIN32) && (!defined _WIN64) && (!defined WIN64) && (!defined __linux__) && (!defined __APPLE__))\r\n\r\n#include \"../../core/api.h\"\r\n#include <stdio.h>\r\n\r\nstatic void(*do_assert)(const char* file, int line);\r\nstatic void(*do_log_out)(const char* log);\r\nvoid register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))\r\n{\r\n\tdo_assert = my_assert;\r\n\tdo_log_out = my_log_out;\r\n}\r\n\r\nvoid _assert(const char* file, int line)\r\n{\r\n\tif(do_assert)\r\n\t{\r\n\t\tdo_assert(file, line);\r\n\t}\r\n\twhile(1);\r\n}\r\n\r\nvoid log_out(const char* log)\r\n{\r\n\tif (do_log_out)\r\n\t{\r\n\t\tdo_log_out(log);\r\n\t}\r\n}\r\n\r\nlong get_time_in_second()\r\n{\r\n    return 0;\r\n}\r\n\r\nT_TIME second_to_day(long second)\r\n{\r\n    T_TIME ret = {0};\r\n    return ret;\r\n}\r\n\r\nT_TIME get_time()\r\n{\r\n    T_TIME ret = {0};\r\n    return ret;\r\n}\r\n\r\nvoid start_real_timer(void (*func)(void* arg))\r\n{\r\n    log_out(\"Not support now\");\r\n}\r\n\r\nvoid register_timer(int milli_second, void func(void* ptmr, void* parg))\r\n{\r\n    log_out(\"Not support now\");\r\n}\r\n\r\nunsigned int get_cur_thread_id()\r\n{\r\n    log_out(\"Not support now\");\r\n    return 0;\r\n}\r\n\r\nvoid create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)\r\n{\r\n    log_out(\"Not support now\");\r\n}\r\n\r\nextern \"C\" void delay_ms(unsigned short nms);\r\nvoid thread_sleep(unsigned int milli_seconds)\r\n{//MCU alway implemnet driver code in APP.\r\n\t\tdelay_ms(milli_seconds);\r\n}\r\n\r\nint build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)\r\n{\r\n    log_out(\"Not support now\");\r\n    return 0;\r\n}\r\n\r\nc_fifo::c_fifo()\r\n{\r\n\tm_head = m_tail = 0;\r\n\tm_read_sem = m_write_mutex = 0;\r\n}\r\n\r\nint c_fifo::read(void* buf, int len)\r\n{\r\n\tunsigned char* pbuf = (unsigned char*)buf;\r\n\tint i = 0;\r\n\twhile(i < len)\r\n\t{\r\n\t\tif (m_tail == m_head)\r\n\t\t{//empty\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\t*pbuf++ = m_buf[m_head];\r\n\t\tm_head = (m_head + 1) % FIFO_BUFFER_LEN;\r\n\t\ti++;\r\n\t}\r\n\tif(i != len)\r\n\t{\r\n\t\tASSERT(false);\r\n\t}\r\n\treturn i;\r\n}\r\n\r\nint c_fifo::write(void* buf, int len)\r\n{\r\n\tunsigned char* pbuf = (unsigned char*)buf;\r\n\tint i = 0;\r\n\tint tail = m_tail;\r\n\r\n\twhile(i < len)\r\n\t{\r\n\t\tif ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)\r\n\t\t{//full, clear data has been written;\r\n\t\t\tm_tail = tail;\r\n\t\t\tlog_out(\"Warning: fifo full\\n\");\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\tm_buf[m_tail] = *pbuf++;\r\n\t\tm_tail = (m_tail + 1) % FIFO_BUFFER_LEN;\r\n\t\ti++;\r\n\t}\r\n\r\n\tif(i != len)\r\n\t{\r\n\t\tASSERT(false);\r\n\t}\r\n\treturn i;\r\n}\r\n\r\n#endif\r\n#endif\r\n"
  },
  {
    "path": "src/core/adapter/api_win.cpp",
    "content": "#ifdef GUILITE_ON\n#if (defined _WIN32) || (defined WIN32) || (defined _WIN64) || (defined WIN64)\n\n#include \"../../core/api.h\"\n#include <string.h>\n#include <stdio.h>\n#include <time.h>\n#include <conio.h>\n#include <windows.h>\n#include <assert.h>\n\n#define MAX_TIMER_CNT 10\n#define TIMER_UNIT 50//ms\n\nstatic void(*do_assert)(const char* file, int line);\nstatic void(*do_log_out)(const char* log);\nvoid register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))\n{\n\tdo_assert = my_assert;\n\tdo_log_out = my_log_out;\n}\n\nvoid _assert(const char* file, int line)\n{\n\tstatic char s_buf[192];\n\tif (do_assert) \n\t{\n\t\tdo_assert(file, line);\n\t}\n\telse\n\t{\n\t\tmemset(s_buf, 0, sizeof(s_buf));\n\t\tsprintf_s(s_buf, sizeof(s_buf), \"vvvvvvvvvvvvvvvvvvvvvvvvvvvv\\n\\nAssert@ file = %s, line = %d\\n\\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n\", file, line);\n\t\tOutputDebugStringA(s_buf);\n\t\tprintf(\"%s\", s_buf);\n\t\tfflush(stdout);\n\t\tassert(false);\n\t}\n}\n\nvoid log_out(const char* log)\n{\n\tif (do_log_out)\n\t{\n\t\tdo_log_out(log);\n\t}\n\telse\n\t{\n\t\tprintf(\"%s\", log);\n\t\tfflush(stdout);\n\t\tOutputDebugStringA(log);\n\t}\n}\n\ntypedef struct _timer_manage\n{\n    struct  _timer_info\n    {\n        int state; /* on or off */\n        int interval;\n        int elapse; /* 0~interval */\n        void (* timer_proc) (void* param);\n\t\tvoid* param;\n    }timer_info[MAX_TIMER_CNT];\n\n    void (* old_sigfunc)(int);\n    void (* new_sigfunc)(int);\n}_timer_manage_t;\nstatic struct _timer_manage timer_manage;\n\nDWORD WINAPI timer_routine(LPVOID lpParam)\n{\n    int i;\n    while(true)\n    {\n    \tfor(i = 0; i < MAX_TIMER_CNT; i++)\n\t\t{\n\t\t\tif(timer_manage.timer_info[i].state == 0)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttimer_manage.timer_info[i].elapse++;\n\t\t\tif(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)\n\t\t\t{\n\t\t\t\ttimer_manage.timer_info[i].elapse = 0;\n\t\t\t\ttimer_manage.timer_info[i].timer_proc(timer_manage.timer_info[i].param);\n\t\t\t}\n\t\t}\n\t\tSleep(TIMER_UNIT);\n    }\n    return 0;\n}\n\nstatic int init_mul_timer()\n{\n\tstatic bool s_is_init = false;\n\tif(s_is_init == true)\n\t{\n\t\treturn 0;\n\t}\n    memset(&timer_manage, 0, sizeof(struct _timer_manage));\n    DWORD pid;\n\tCreateThread(0, 0, timer_routine, 0, 0, &pid);\n    s_is_init = true;\n    return 1;\n}\n\nstatic int set_a_timer(int interval, void (* timer_proc) (void* param), void* param)\n{\n\tinit_mul_timer();\n\n\tint i;\n    if(timer_proc == 0 || interval <= 0)\n    {\n        return (-1);\n    }\n\n    for(i = 0; i < MAX_TIMER_CNT; i++)\n    {\n        if(timer_manage.timer_info[i].state == 1)\n        {\n            continue;\n        }\n        memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));\n        timer_manage.timer_info[i].timer_proc = timer_proc;\n\t\ttimer_manage.timer_info[i].param = param;\n        timer_manage.timer_info[i].interval = interval;\n        timer_manage.timer_info[i].elapse = 0;\n        timer_manage.timer_info[i].state = 1;\n        break;\n    }\n\n    if(i >= MAX_TIMER_CNT)\n    {\n\t\tASSERT(false);\n        return (-1);\n    }\n    return (i);\n}\n\ntypedef void (*EXPIRE_ROUTINE)(void* arg);\nEXPIRE_ROUTINE s_expire_function;\nstatic c_fifo s_real_timer_fifo;\n\nstatic DWORD WINAPI fire_real_timer(LPVOID lpParam)\n{\n\tchar dummy;\n\twhile(1)\n\t{\n\t\tif(s_real_timer_fifo.read(&dummy, 1) > 0)\n\t\t{\n\t\t\tif(s_expire_function)s_expire_function(0);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tASSERT(false);\n\t\t}\n\t}\n\treturn 0;\n}\n\n/*Win32 desktop only\nstatic void CALLBACK trigger_real_timer(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR)\n{\n\tchar dummy = 0x33;\n\ts_real_timer_fifo.write(&dummy, 1);\n}\n*/\n\nstatic DWORD WINAPI trigger_real_timer(LPVOID lpParam)\n{\n\tchar dummy = 0x33;\n\twhile (1)\n\t{\n\t\ts_real_timer_fifo.write(&dummy, 1);\n\t\tSleep(REAL_TIME_TASK_CYCLE_MS);\n\t}\n\treturn 0;\n}\n\nvoid start_real_timer(void (*func)(void* arg))\n{\n\tif(0 == func)\n\t{\n\t\treturn;\n\t}\n\n\ts_expire_function = func;\n\t//timeSetEvent(REAL_TIME_TASK_CYCLE_MS, 0, trigger_real_timer, 0, TIME_PERIODIC);//Win32 desktop only\n\n\tstatic DWORD s_pid;\n\tif(s_pid == 0)\n\t{\n\t\tCreateThread(0, 0, trigger_real_timer, 0, 0, &s_pid);\n\t\tCreateThread(0, 0, fire_real_timer, 0, 0, &s_pid);\n\t}\n}\n\nunsigned int get_cur_thread_id()\n{\n\treturn GetCurrentThreadId();\n}\n\nvoid register_timer(int milli_second,void func(void* param), void* param)\n{\n\tset_a_timer(milli_second/TIMER_UNIT,func, param);\n}\n\nlong get_time_in_second()\n{\n\treturn (long)time(0);\n}\n\nT_TIME get_time()\n{\n\tT_TIME ret = {0};\n\t\n\tSYSTEMTIME time;\n\tGetLocalTime(&time);\n\tret.year = time.wYear;\n\tret.month = time.wMonth;\n\tret.day = time.wDay;\n\tret.hour = time.wHour;\n\tret.minute = time.wMinute;\n\tret.second = time.wSecond;\n\treturn ret;\n}\n\nT_TIME second_to_day(long second)\n{\n\tT_TIME ret;\n\tret.year = 1999;\n\tret.month = 10;\n\tret.date = 1;\n\n\tret.second = second % 60;\n\tsecond /= 60;\n\tret.minute = second % 60;\n\tsecond /= 60;\n\tret.hour = (second + 8) % 24;//China time zone.\n\treturn ret;\n}\n\nvoid create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)\n{\n\tDWORD pid = 0;\n\tCreateThread(0, 0, LPTHREAD_START_ROUTINE(start_routine), arg, 0, &pid);\n\t*thread_id = pid;\n}\n\nvoid thread_sleep(unsigned int milli_seconds)\n{\n\tSleep(milli_seconds);\n}\n\n#pragma pack(push,1)\ntypedef struct {\n\tunsigned short\tbfType;\n\tunsigned int   \tbfSize;\n\tunsigned short  bfReserved1;\n\tunsigned short  bfReserved2;\n\tunsigned int   \tbfOffBits;\n}FileHead;\n\ntypedef struct {\n\tunsigned int  \tbiSize;\n\tint \t\t\tbiWidth;\n\tint       \t\tbiHeight;\n\tunsigned short\tbiPlanes;\n\tunsigned short  biBitCount;\n\tunsigned int    biCompress;\n\tunsigned int    biSizeImage;\n\tint       \t\tbiXPelsPerMeter;\n\tint       \t\tbiYPelsPerMeter;\n\tunsigned int \tbiClrUsed;\n\tunsigned int    biClrImportant;\n\tunsigned int \tbiRedMask;\n\tunsigned int \tbiGreenMask;\n\tunsigned int \tbiBlueMask;\n}Infohead;\n#pragma pack(pop)\n\nint build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)\n{\n\tFileHead bmp_head;\n\tInfohead bmp_info;\n\tint size = width * height * 2;\n\n\t//initialize bmp head.\n\tbmp_head.bfType = 0x4d42;\n\tbmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead);\n\tbmp_head.bfReserved1 = bmp_head.bfReserved2 = 0;\n\tbmp_head.bfOffBits = bmp_head.bfSize - size;\n\n\t//initialize bmp info.\n\tbmp_info.biSize = 40;\n\tbmp_info.biWidth = width;\n\tbmp_info.biHeight = height;\n\tbmp_info.biPlanes = 1;\n\tbmp_info.biBitCount = 16;\n\tbmp_info.biCompress = 3;\n\tbmp_info.biSizeImage = size;\n\tbmp_info.biXPelsPerMeter = 0;\n\tbmp_info.biYPelsPerMeter = 0;\n\tbmp_info.biClrUsed = 0;\n\tbmp_info.biClrImportant = 0;\n\n\t//RGB565\n\tbmp_info.biRedMask = 0xF800;\n\tbmp_info.biGreenMask = 0x07E0;\n\tbmp_info.biBlueMask = 0x001F;\n\n\t//copy the data\n\tFILE *fp;\n\tif (!(fp = fopen(filename, \"wb\")))\n\t{\n\t\treturn -1;\n\t}\n\n\tfwrite(&bmp_head, 1, sizeof(FileHead), fp);\n\tfwrite(&bmp_info, 1, sizeof(Infohead), fp);\n\n\t//fwrite(data, 1, size, fp);//top <-> bottom\n\tfor (int i = (height - 1); i >= 0; --i)\n\t{\n\t\tfwrite(&data[i * width * 2], 1, width * 2, fp);\n\t}\n\n\tfclose(fp);\n\treturn 0;\n}\n\nc_fifo::c_fifo()\n{\n\tm_head = m_tail = 0;\n\tm_read_sem = CreateSemaphore(0,\t// default security attributes\n\t\t0,\t\t// initial count\n\t\t1,\t\t// maximum count\n\t\t0);\t// unnamed semaphore\n\tm_write_mutex = CreateMutex(0, false, 0);\n}\n\nint c_fifo::read(void* buf, int len)\n{\n\tunsigned char* pbuf = (unsigned char*)buf;\n\tint i = 0;\n\twhile (i < len)\n\t{\n\t\tif (m_tail == m_head)\n\t\t{//empty\n\t\t\tWaitForSingleObject(m_read_sem, INFINITE);\n\t\t\tcontinue;\n\t\t}\n\t\t*pbuf++ = m_buf[m_head];\n\t\tm_head = (m_head + 1) % FIFO_BUFFER_LEN;\n\t\ti++;\n\t}\n\tif (i != len)\n\t{\n\t\tASSERT(false);\n\t}\n\treturn i;\n}\n\nint c_fifo::write(void* buf, int len)\n{\n\tunsigned char* pbuf = (unsigned char*)buf;\n\tint i = 0;\n\tint tail = m_tail;\n\n\tWaitForSingleObject(m_write_mutex, INFINITE);\n\twhile (i < len)\n\t{\n\t\tif ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)\n\t\t{//full, clear data has been written;\n\t\t\tm_tail = tail;\n\t\t\tlog_out(\"Warning: fifo full\\n\");\n\t\t\tReleaseMutex(m_write_mutex);\n\t\t\treturn 0;\n\t\t}\n\t\tm_buf[m_tail] = *pbuf++;\n\t\tm_tail = (m_tail + 1) % FIFO_BUFFER_LEN;\n\t\ti++;\n\t}\n\tReleaseMutex(m_write_mutex);\n\n\tif (i != len)\n\t{\n\t\tASSERT(false);\n\t}\n\telse\n\t{\n\t\tReleaseSemaphore(m_read_sem, 1, 0);\n\t}\n\treturn i;\n}\n\n#endif\n#endif\n"
  },
  {
    "path": "src/core/api.h",
    "content": "#pragma once\n\n#define REAL_TIME_TASK_CYCLE_MS\t\t50\n#define MAX(a,b) (((a)>(b))?(a):(b))\n#define MIN(a,b) (((a)<(b))?(a):(b))\n\n#define GL_ARGB(a, r, g, b) ((((unsigned int)(a)) << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))\n#define GL_ARGB_A(rgb) ((((unsigned int)(rgb)) >> 24) & 0xFF)\n\n#define GL_RGB(r, g, b) ((0xFF << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))\n#define GL_RGB_R(rgb) ((((unsigned int)(rgb)) >> 16) & 0xFF)\n#define GL_RGB_G(rgb) ((((unsigned int)(rgb)) >> 8) & 0xFF)\n#define GL_RGB_B(rgb) (((unsigned int)(rgb)) & 0xFF)\n#define GL_RGB_32_to_16(rgb) (((((unsigned int)(rgb)) & 0xFF) >> 3) | ((((unsigned int)(rgb)) & 0xFC00) >> 5) | ((((unsigned int)(rgb)) & 0xF80000) >> 8))\n#define GL_RGB_16_to_32(rgb) ((0xFF << 24) | ((((unsigned int)(rgb)) & 0x1F) << 3) | ((((unsigned int)(rgb)) & 0x7E0) << 5) | ((((unsigned int)(rgb)) & 0xF800) << 8))\n\n#define ALIGN_HCENTER\t\t0x00000000L\n#define ALIGN_LEFT\t\t\t0x01000000L\n#define ALIGN_RIGHT\t\t\t0x02000000L\n#define ALIGN_HMASK\t\t\t0x03000000L\n\n#define ALIGN_VCENTER\t\t0x00000000L\n#define ALIGN_TOP\t\t\t0x00100000L\n#define ALIGN_BOTTOM\t\t0x00200000L\n#define ALIGN_VMASK\t\t\t0x00300000L\n\ntypedef struct\n{\n\tunsigned short year;\n\tunsigned short month;\n\tunsigned short date;\n\tunsigned short day;\n\tunsigned short hour;\n\tunsigned short minute;\n\tunsigned short second;\n}T_TIME;\n\nvoid register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log));\nvoid _assert(const char* file, int line);\n#define ASSERT(condition)\t\\\n\tdo{                     \\\n\tif(!(condition))_assert(__FILE__, __LINE__);\\\n\t}while(0)\nvoid log_out(const char* log);\n\nlong get_time_in_second();\nT_TIME second_to_day(long second);\nT_TIME get_time();\n\nvoid start_real_timer(void (*func)(void* arg));\nvoid register_timer(int milli_second, void func(void* param), void* param);\n\nunsigned int get_cur_thread_id();\nvoid create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg);\nvoid thread_sleep(unsigned int milli_seconds);\nint build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data);\n\n#define FIFO_BUFFER_LEN\t\t1024\nclass c_fifo\n{\npublic:\n\tc_fifo();\n\tint read(void* buf, int len);\n\tint write(void* buf, int len);\nprivate:\n\tunsigned char \tm_buf[FIFO_BUFFER_LEN];\n\tint\t\tm_head;\n\tint\t\tm_tail;\n\tvoid* m_read_sem;\n\tvoid* m_write_mutex;\n};\n\nclass c_rect\n{\npublic:\n\tc_rect(){ m_left = m_top = m_right = m_bottom = -1; }//empty rect\n\tc_rect(int left, int top, int width, int height)\n\t{\n\t\tset_rect(left, top, width, height);\n\t}\n\tvoid set_rect(int left, int top, int width, int height)\n\t{\n\t\tASSERT(width > 0 && height > 0);\n\t\tm_left = left;\n\t\tm_top = top;\n\t\tm_right = left + width - 1;\n\t\tm_bottom = top + height -1;\n\t}\n\tbool pt_in_rect(int x, int y) const\n\t{\n\t\treturn x >= m_left && x <= m_right && y >= m_top && y <= m_bottom;\n\t}\n\tint operator==(const c_rect& rect) const\n\t{\n\t\treturn (m_left == rect.m_left) && (m_top == rect.m_top) && (m_right == rect.m_right) && (m_bottom == rect.m_bottom);\n\t}\n\tint width() const { return m_right - m_left + 1; }\n\tint height() const { return m_bottom - m_top + 1 ; }\n\n\tint\t    m_left;\n\tint     m_top;\n\tint     m_right;\n\tint     m_bottom;\n};\n"
  },
  {
    "path": "src/core/core.cpp",
    "content": "#include \"../core/display.h\"\n#include \"../core//image.h\"\n#include \"../core/theme.h\"\n#include \"../core/wnd.h\"\n#include \"../core/word.h\"\n\n#ifdef GUILITE_ON\nc_bitmap_operator the_bitmap_op = c_bitmap_operator();\nc_image_operator* c_image::image_operator = &the_bitmap_op;\n\nconst void* c_theme::s_font_map[FONT_MAX];\nconst void* c_theme::s_image_map[IMAGE_MAX];\nunsigned int c_theme::s_color_map[COLOR_MAX];\n\nc_lattice_font_op the_lattice_font_op = c_lattice_font_op();\nc_font_operator* c_word::fontOperator = &the_lattice_font_op;\n#endif\n"
  },
  {
    "path": "src/core/display.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#define SURFACE_CNT_MAX\t6//root + pages\n\ntypedef enum\n{\n\tZ_ORDER_LEVEL_0,//lowest graphic level\n\tZ_ORDER_LEVEL_1,//middle graphic level, call activate_layer before use it, draw everything inside the active rect.\n\tZ_ORDER_LEVEL_2,//highest graphic level, call activate_layer before use it, draw everything inside the active rect.\n\tZ_ORDER_LEVEL_MAX\n}Z_ORDER_LEVEL;\n\nstruct DISPLAY_DRIVER\n{\n\tvoid(*draw_pixel)(int x, int y, unsigned int rgb);\n\tvoid(*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);\n};\n\nclass c_surface;\nclass c_display {\n\tfriend class c_surface;\npublic:\n\tinline c_display(void* phy_fb, int display_width, int display_height, c_surface* surface, DISPLAY_DRIVER* driver = 0);//single custom surface\n\tinline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, DISPLAY_DRIVER* driver = 0);//multiple surface\n\tinline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect layer_rect = c_rect());//for slide group\n\tinline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset);\n\tint get_width() { return m_width; }\n\tint get_height() { return m_height; }\n\tvoid* get_phy_fb() { return m_phy_fb; }\n\n\tvoid* get_updated_fb(int* width, int* height, bool force_update = false)\n\t{\n\t\tif (width && height)\n\t\t{\n\t\t\t*width = m_width;\n\t\t\t*height = m_height;\n\t\t}\n\t\tif (force_update)\n\t\t{\n\t\t\treturn m_phy_fb;\n\t\t}\n\t\tif (m_phy_read_index == m_phy_write_index)\n\t\t{//No update\n\t\t\treturn 0;\n\t\t}\n\t\tm_phy_read_index = m_phy_write_index;\n\t\treturn m_phy_fb;\n\t}\n\n\tint snap_shot(const char* file_name)\n\t{\n\t\tif (!m_phy_fb || (m_color_bytes !=2 && m_color_bytes != 4))\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\n\t\t//16 bits framebuffer\n\t\tif (m_color_bytes == 2)\n\t\t{\n\t\t\treturn build_bmp(file_name, m_width, m_height, (unsigned char*)m_phy_fb);\n\t\t}\n\n\t\t//32 bits framebuffer\n\t\tunsigned short* p_bmp565_data = new unsigned short[m_width * m_height];\n\t\tunsigned int* p_raw_data = (unsigned int*)m_phy_fb;\n\n\t\tfor (int i = 0; i < m_width * m_height; i++)\n\t\t{\n\t\t\tunsigned int rgb = *p_raw_data++;\n\t\t\tp_bmp565_data[i] = GL_RGB_32_to_16(rgb);\n\t\t}\n\n\t\tint ret = build_bmp(file_name, m_width, m_height, (unsigned char*)p_bmp565_data);\n\t\tdelete[]p_bmp565_data;\n\t\treturn ret;\n\t}\n\nprotected:\n\tvirtual void draw_pixel(int x, int y, unsigned int rgb)\n\t{\n\t\tif ((x >= m_width) || (y >= m_height)) { return; }\n\n\t\tif (m_driver && m_driver->draw_pixel)\n\t\t{\n\t\t\treturn m_driver->draw_pixel(x, y, rgb);\n\t\t}\n\n\t\tif (m_color_bytes == 2)\n\t\t{\n\t\t\t((unsigned short*)m_phy_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t((unsigned int*)m_phy_fb)[y * m_width + x] = rgb;\n\t\t}\n\t}\n\n\tvirtual void fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb)\n\t{\n\t\tif (m_driver && m_driver->fill_rect)\n\t\t{\n\t\t\treturn m_driver->fill_rect(x0, y0, x1, y1, rgb);\n\t\t}\n\n\t\tif (m_driver && m_driver->draw_pixel)\n\t\t{\n\t\t\tfor (int y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tfor (int x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\tm_driver->draw_pixel(x, y, rgb);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tint _width = m_width;\n\t\tint _height = m_height;\n\t\tint x, y;\n\t\tif (m_color_bytes == 2)\n\t\t{\n\t\t\tunsigned short* phy_fb;\n\t\t\tunsigned int rgb_16 = GL_RGB_32_to_16(rgb);\n\t\t\tfor (y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tphy_fb = &((unsigned short*)m_phy_fb)[y * _width + x0];\n\t\t\t\tfor (x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\tif ((x < _width) && (y < _height))\n\t\t\t\t\t{\n\t\t\t\t\t\t*phy_fb++ = rgb_16;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tunsigned int* phy_fb;\n\t\t\tfor (y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tphy_fb = &((unsigned int*)m_phy_fb)[y * _width + x0];\n\t\t\t\tfor (x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\tif ((x < _width) && (y < _height))\n\t\t\t\t\t{\n\t\t\t\t\t\t*phy_fb++ = rgb;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tvirtual int flush_screen(int left, int top, int right, int bottom, void* fb, int fb_width)\n\t{\n\t\tif ((0 == m_phy_fb) || (0 == fb))\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\n\t\tint _width = m_width;\n\t\tint _height = m_height;\n\n\t\tleft = (left >= _width) ? (_width - 1) : left;\n\t\tright = (right >= _width) ? (_width - 1) : right;\n\t\ttop = (top >= _height) ? (_height - 1) : top;\n\t\tbottom = (bottom >= _height) ? (_height - 1) : bottom;\n\n\t\tfor (int y = top; y < bottom; y++)\n\t\t{\n\t\t\tvoid* s_addr = (char*)fb + ((y * fb_width + left) * m_color_bytes);\n\t\t\tvoid* d_addr = (char*)m_phy_fb + ((y * _width + left) * m_color_bytes);\n\t\t\tmemcpy(d_addr, s_addr, (right - left) * m_color_bytes);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tint\t\t\t\t\t\tm_width;\t\t//in pixels\n\tint\t\t\t\t\t\tm_height;\t\t//in pixels\n\tint\t\t\t\t\t\tm_color_bytes;\t//16/32 bits for default\n\tvoid*\t\t\t\t\tm_phy_fb;\t\t//physical framebuffer for default\n\tstruct DISPLAY_DRIVER*  m_driver;\t\t//Rendering by external method without default physical framebuffer\n\n\tint\t\t\t\tm_phy_read_index;\n\tint\t\t\t\tm_phy_write_index;\n\tc_surface*\t\tm_surface_group[SURFACE_CNT_MAX];\n\tint\t\t\t\tm_surface_cnt;\t//surface count\n\tint\t\t\t\tm_surface_index;\n\t\n};\n\nclass c_layer\n{\npublic:\n\tc_layer() { fb = 0; }\n\tvoid* fb;\t\t//framebuffer\n\tc_rect rect;\t//framebuffer area\n\tc_rect active_rect;\n};\n\nclass c_surface {\n\tfriend class c_display; friend class c_bitmap_operator;\npublic:\n\tZ_ORDER_LEVEL get_max_z_order() { return m_max_zorder; }\n\n\tc_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0, c_rect overlpa_rect = c_rect()) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_write_index(0), m_display(0)\n\t{\n\t\t(overlpa_rect == c_rect()) ? set_surface(max_zorder, c_rect(0, 0, width, height)) : set_surface(max_zorder, overlpa_rect);\n\t}\n\n\tunsigned int get_pixel(int x, int y, unsigned int z_order)\n\t{\n\t\tif (x >= m_width || y >= m_height || x < 0 || y < 0 || z_order >= Z_ORDER_LEVEL_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\tif (m_layers[z_order].fb)\n\t\t{\n\t\t\treturn (m_color_bytes == 2) ? GL_RGB_16_to_32(((unsigned short*)(m_layers[z_order].fb))[y * m_width + x]) : ((unsigned int*)(m_layers[z_order].fb))[y * m_width + x];\n\t\t}\n\t\telse if (m_fb)\n\t\t{\n\t\t\treturn (m_color_bytes == 2) ? GL_RGB_16_to_32(((unsigned short*)m_fb)[y * m_width + x]) : ((unsigned int*)m_fb)[y * m_width + x];\n\t\t}\n\t\telse if (m_display->m_phy_fb)\n\t\t{\n\t\t\treturn (m_color_bytes == 2) ? GL_RGB_16_to_32(((unsigned short*)m_display->m_phy_fb)[y * m_width + x]) : ((unsigned int*)m_display->m_phy_fb)[y * m_width + x];\n\t\t}\n\t\treturn 0;\n\t}\n\n\tvirtual void draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tif (x >= m_width || y >= m_height || x < 0 || y < 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tif (z_order > (unsigned int)m_max_zorder)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn;\n\t\t}\n\n\t\tif (z_order > (unsigned int)m_top_zorder)\n\t\t{\n\t\t\tm_top_zorder = (Z_ORDER_LEVEL)z_order;\n\t\t}\n\n\t\tif (z_order == m_max_zorder)\n\t\t{\n\t\t\treturn draw_pixel_low_level(x, y, rgb);\n\t\t}\n\n\t\tif (m_layers[z_order].rect.pt_in_rect(x, y))\n\t\t{\n\t\t\tc_rect layer_rect = m_layers[z_order].rect;\n\t\t\tif (m_color_bytes == 2)\n\t\t\t{\n\t\t\t\t((unsigned short*)(m_layers[z_order].fb))[(x - layer_rect.m_left) + (y - layer_rect.m_top) * layer_rect.width()] = GL_RGB_32_to_16(rgb);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t((unsigned int*)(m_layers[z_order].fb))[(x - layer_rect.m_left) + (y - layer_rect.m_top) * layer_rect.width()] = rgb;\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (z_order == m_top_zorder)\n\t\t{\n\t\t\treturn draw_pixel_low_level(x, y, rgb);\n\t\t}\n\n\t\tbool be_overlapped = false;\n\t\tfor (unsigned int tmp_z_order = Z_ORDER_LEVEL_MAX - 1; tmp_z_order > z_order; tmp_z_order--)\n\t\t{\n\t\t\tif (m_layers[tmp_z_order].active_rect.pt_in_rect(x, y))\n\t\t\t{\n\t\t\t\tbe_overlapped = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!be_overlapped)\n\t\t{\n\t\t\tdraw_pixel_low_level(x, y, rgb);\n\t\t}\n\t}\n\n\tvirtual void fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tx0 = (x0 < 0) ? 0 : x0;\n\t\ty0 = (y0 < 0) ? 0 : y0;\n\t\tx1 = (x1 > (m_width - 1)) ? (m_width - 1) : x1;\n\t\ty1 = (y1 > (m_height - 1)) ? (m_height - 1) : y1;\n\n\t\tif (z_order == m_max_zorder)\n\t\t{\n\t\t\treturn fill_rect_low_level(x0, y0, x1, y1, rgb);\n\t\t}\n\n\t\tif (z_order == m_top_zorder)\n\t\t{\n\t\t\tint width = m_layers[z_order].rect.width();\n\t\t\tc_rect layer_rect = m_layers[z_order].rect;\n\t\t\tunsigned int rgb_16 = GL_RGB_32_to_16(rgb);\n\t\t\tfor (int y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tfor (int x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\tif (layer_rect.pt_in_rect(x, y))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (m_color_bytes == 2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t((unsigned short*)m_layers[z_order].fb)[(y - layer_rect.m_top) * width + (x - layer_rect.m_left)] = rgb_16;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t((unsigned int*)m_layers[z_order].fb)[(y - layer_rect.m_top) * width + (x - layer_rect.m_left)] = rgb;\t\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn fill_rect_low_level(x0, y0, x1, y1, rgb);\n\t\t}\n\n\t\tfor (; y0 <= y1; y0++)\n\t\t{\n\t\t\tdraw_hline(x0, x1, y0, rgb, z_order);\n\t\t}\n\t}\n\n\tvoid draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tfor (; x0 <= x1; x0++)\n\t\t{\n\t\t\tdraw_pixel(x0, y, rgb, z_order);\n\t\t}\n\t}\n\n\tvoid draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tfor (; y0 <= y1; y0++)\n\t\t{\n\t\t\tdraw_pixel(x, y0, rgb, z_order);\n\t\t}\n\t}\n\n\tvoid draw_line(int x1, int y1, int x2, int y2, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tint dx, dy, x, y, e;\n\n\t\t(x1 > x2) ? (dx = x1 - x2) : (dx = x2 - x1);\n\t\t(y1 > y2) ? (dy = y1 - y2) : (dy = y2 - y1);\n\n\t\tif (((dx > dy) && (x1 > x2)) || ((dx <= dy) && (y1 > y2)))\n\t\t{\n\t\t\tx = x2; y = y2;\n\t\t\tx2 = x1; y2 = y1;\n\t\t\tx1 = x; y1 = y;\n\t\t}\n\t\tx = x1; y = y1;\n\n\t\tif (dx > dy)\n\t\t{\n\t\t\te = dy - dx / 2;\n\t\t\tfor (; x1 <= x2; ++x1, e += dy)\n\t\t\t{\n\t\t\t\tdraw_pixel(x1, y1, rgb, z_order);\n\t\t\t\tif (e > 0) { e -= dx; (y > y2) ? --y1 : ++y1; }\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\te = dx - dy / 2;\n\t\t\tfor (; y1 <= y2; ++y1, e += dx)\n\t\t\t{\n\t\t\t\tdraw_pixel(x1, y1, rgb, z_order);\n\t\t\t\tif (e > 0) { e -= dy; (x > x2) ? --x1 : ++x1; }\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size = 1)\n\t{\n\t\tfor (unsigned int offset = 0; offset < size; offset++)\n\t\t{\n\t\t\tdraw_hline(x0 + offset, x1 - offset, y0 + offset, rgb, z_order);\n\t\t\tdraw_hline(x0 + offset, x1 - offset, y1 - offset, rgb, z_order);\n\t\t\tdraw_vline(x0 + offset, y0 + offset, y1 - offset, rgb, z_order);\n\t\t\tdraw_vline(x1 - offset, y0 + offset, y1 - offset, rgb, z_order);\n\t\t}\n\t}\n\n\tvoid draw_rect(c_rect rect, unsigned int rgb, unsigned int size, unsigned int z_order)\n\t{\n\t\tdraw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order, size);\n\t}\n\n\tvoid fill_rect(c_rect rect, unsigned int rgb, unsigned int z_order)\n\t{\n\t\tfill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order);\n\t}\n\n\tint flush_screen(int left, int top, int right, int bottom)\n\t{\n\t\tif (!m_is_active)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\n\t\tif (left < 0 || left >= m_width || right < 0 || right >= m_width ||\n\t\t\ttop < 0 || top >= m_height || bottom < 0 || bottom >= m_height)\n\t\t{\n\t\t\tASSERT(false);\n\t\t}\n\n\t\tm_display->flush_screen(left, top, right, bottom, m_fb, m_width);\n\t\t*m_phy_write_index = *m_phy_write_index + 1;\n\t\treturn 0;\n\t}\n\n\tbool is_active() { return m_is_active; }\n\tc_display* get_display() { return m_display; }\n\n\tvoid activate_layer(c_rect active_rect, unsigned int active_z_order)//empty active rect means inactivating the layer\n\t{\n\t\tASSERT(active_z_order > Z_ORDER_LEVEL_0 && active_z_order <= Z_ORDER_LEVEL_MAX);\n\t\t\n\t\t//Show the layers below the current active rect.\n\t\tc_rect current_active_rect = m_layers[active_z_order].active_rect;\n\t\tfor(int low_z_order = Z_ORDER_LEVEL_0; low_z_order < active_z_order; low_z_order++)\n\t\t{\n\t\t\tc_rect low_layer_rect = m_layers[low_z_order].rect;\n\t\t\tc_rect low_active_rect = m_layers[low_z_order].active_rect;\n\t\t\tvoid* fb = m_layers[low_z_order].fb;\n\t\t\tint width = low_layer_rect.width();\n\t\t\tfor (int y = current_active_rect.m_top; y <= current_active_rect.m_bottom; y++)\n\t\t\t{\n\t\t\t\tfor (int x = current_active_rect.m_left; x <= current_active_rect.m_right; x++)\n\t\t\t\t{\n\t\t\t\t\tif (low_active_rect.pt_in_rect(x, y) && low_layer_rect.pt_in_rect(x, y))//active rect maybe is bigger than layer rect\n\t\t\t\t\t{\n\t\t\t\t\t\tunsigned int rgb = (m_color_bytes == 2) ? GL_RGB_16_to_32(((unsigned short*)fb)[(x - low_layer_rect.m_left) + (y - low_layer_rect.m_top) * width]) : ((unsigned int*)fb)[(x - low_layer_rect.m_left) + (y - low_layer_rect.m_top) * width];\n\t\t\t\t\t\tdraw_pixel_low_level(x, y, rgb);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tm_layers[active_z_order].active_rect = active_rect;//set the new acitve rect.\n\t}\n\n\tvoid set_active(bool flag) { m_is_active = flag; }\nprotected:\n\tvirtual void fill_rect_low_level(int x0, int y0, int x1, int y1, unsigned int rgb)\n\t{//fill rect on framebuffer of surface\n\t\tint x, y;\n\t\tif (m_color_bytes == 2)\n\t\t{\n\t\t\tunsigned short* fb;\n\t\t\tunsigned int rgb_16 = GL_RGB_32_to_16(rgb);\n\t\t\tfor (y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tfb = m_fb ? &((unsigned short*)m_fb)[y * m_width + x0] : 0;\n\t\t\t\tif (!fb) { break; }\n\t\t\t\tfor (x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\t*fb++ = rgb_16;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tunsigned int* fb;\n\t\t\tfor (y = y0; y <= y1; y++)\n\t\t\t{\n\t\t\t\tfb = m_fb ? &((unsigned int*)m_fb)[y * m_width + x0] : 0;\n\t\t\t\tif (!fb) { break; }\n\t\t\t\tfor (x = x0; x <= x1; x++)\n\t\t\t\t{\n\t\t\t\t\t*fb++ = rgb;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!m_is_active) { return; }\n\t\tm_display->fill_rect(x0, y0, x1, y1, rgb);\n\t\t*m_phy_write_index = *m_phy_write_index + 1;\n\t}\n\n\tvirtual void draw_pixel_low_level(int x, int y, unsigned int rgb)\n\t{\n\t\tif (m_fb)\n\t\t{//draw pixel on framebuffer of surface\n\t\t\t(m_color_bytes == 2) ? ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb): ((unsigned int*)m_fb)[y * m_width + x] = rgb;\n\t\t}\n\t\tif (!m_is_active) { return; }\n\t\tm_display->draw_pixel(x, y, rgb);\n\t\t*m_phy_write_index = *m_phy_write_index + 1;\n\t}\n\n\tvoid attach_display(c_display* display)\n\t{\n\t\tASSERT(display);\n\t\tm_display = display;\n\t\tm_phy_write_index = &display->m_phy_write_index;\n\t}\n\n\tvoid set_surface(Z_ORDER_LEVEL max_z_order, c_rect layer_rect)\n\t{\n\t\tm_max_zorder = max_z_order;\n\t\tif (m_display && (m_display->m_surface_cnt > 1))\n\t\t{\n\t\t\tm_fb = calloc(m_width * m_height, m_color_bytes);\n\t\t}\n\n\t\tfor (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++)\n\t\t{//Top layber fb always be 0\n\t\t\tASSERT(m_layers[i].fb = calloc(layer_rect.width() * layer_rect.height(), m_color_bytes));\n\t\t\tm_layers[i].rect = layer_rect;\n\t\t}\n\n\t\tm_layers[Z_ORDER_LEVEL_0].active_rect = layer_rect;\n\t}\n\n\tint\t\t\t\tm_width;\t\t//in pixels\n\tint\t\t\t\tm_height;\t\t//in pixels\n\tint\t\t\t\tm_color_bytes;\t//16 bits, 32 bits for default\n\tvoid*\t\t\tm_fb;\t\t\t//frame buffer you could see\n\tc_layer \t\tm_layers[Z_ORDER_LEVEL_MAX];//all graphic layers\n\tbool\t\t\tm_is_active;\t//active flag\n\tZ_ORDER_LEVEL\tm_max_zorder;\t//the highest graphic layer the surface will have\n\tZ_ORDER_LEVEL\tm_top_zorder;\t//the current highest graphic layer the surface have\n\tint*\t\t\tm_phy_write_index;\n\tc_display*\t\tm_display;\n};\n\ninline c_display::c_display(void* phy_fb, int display_width, int display_height, c_surface* surface, DISPLAY_DRIVER* driver) : m_phy_fb(phy_fb), m_width(display_width), m_height(display_height), m_driver(driver), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(1), m_surface_index(0)\n{\n\tm_color_bytes = surface->m_color_bytes;\n\tsurface->m_is_active = true;\n\t(m_surface_group[0] = surface)->attach_display(this);\n}\n\ninline c_display::c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, DISPLAY_DRIVER* driver) : m_phy_fb(phy_fb), m_width(display_width), m_height(display_height), m_color_bytes(color_bytes), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(surface_cnt), m_driver(driver), m_surface_index(0)\n{\n\tASSERT(color_bytes == 2 || color_bytes == 4);\n\tASSERT(m_surface_cnt <= SURFACE_CNT_MAX);\n\tmemset(m_surface_group, 0, sizeof(m_surface_group));\n\t\n\tfor (int i = 0; i < m_surface_cnt; i++)\n\t{\n\t\tm_surface_group[i] = new c_surface(surface_width, surface_height, color_bytes);\n\t\tm_surface_group[i]->attach_display(this);\n\t}\n}\n\ninline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect layer_rect)\n{\n\tASSERT(max_zorder < Z_ORDER_LEVEL_MAX && m_surface_index < m_surface_cnt);\n\t(layer_rect == c_rect()) ? m_surface_group[m_surface_index]->set_surface(max_zorder, c_rect(0, 0, m_width, m_height)) : m_surface_group[m_surface_index]->set_surface(max_zorder, layer_rect);\n\treturn m_surface_group[m_surface_index++];\n}\n\ninline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset)\n{\n\tint surface_width = s0->m_width;\n\tint surface_height = s0->m_height;\n\n\tif (offset < 0 || offset > surface_width || y0 < 0 || y0 >= surface_height ||\n\t\ty1 < 0 || y1 >= surface_height || x0 < 0 || x0 >= surface_width || x1 < 0 || x1 >= surface_width)\n\t{\n\t\tASSERT(false);\n\t\treturn -1;\n\t}\n\n\tint width = (x1 - x0 + 1);\n\tif (width < 0 || width > surface_width || width < offset)\n\t{\n\t\tASSERT(false);\n\t\treturn -1;\n\t}\n\n\tx0 = (x0 >= m_width) ? (m_width - 1) : x0;\n\tx1 = (x1 >= m_width) ? (m_width - 1) : x1;\n\ty0 = (y0 >= m_height) ? (m_height - 1) : y0;\n\ty1 = (y1 >= m_height) ? (m_height - 1) : y1;\n\n\tif (m_phy_fb)\n\t{\n\t\tfor (int y = y0; y <= y1; y++)\n\t\t{\n\t\t\t//Left surface\n\t\t\tchar* addr_s = ((char*)(s0->m_fb) + (y * surface_width + x0 + offset) * m_color_bytes);\n\t\t\tchar* addr_d = ((char*)(m_phy_fb)+(y * m_width + x0) * m_color_bytes);\n\t\t\tmemcpy(addr_d, addr_s, (width - offset) * m_color_bytes);\n\t\t\t//Right surface\n\t\t\taddr_s = ((char*)(s1->m_fb) + (y * surface_width + x0) * m_color_bytes);\n\t\t\taddr_d = ((char*)(m_phy_fb)+(y * m_width + x0 + (width - offset)) * m_color_bytes);\n\t\t\tmemcpy(addr_d, addr_s, offset * m_color_bytes);\n\t\t}\n\t}\n\telse if (m_color_bytes == 2)\n\t{\n\t\tvoid(*draw_pixel)(int x, int y, unsigned int rgb) = m_driver->draw_pixel;\n\t\tfor (int y = y0; y <= y1; y++)\n\t\t{\n\t\t\t//Left surface\n\t\t\tfor (int x = x0; x <= (x1 - offset); x++)\n\t\t\t{\n\t\t\t\tdraw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s0->m_fb)[y * m_width + x + offset]));\n\t\t\t}\n\t\t\t//Right surface\n\t\t\tfor (int x = x1 - offset; x <= x1; x++)\n\t\t\t{\n\t\t\t\tdraw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s1->m_fb)[y * m_width + x + offset - x1 + x0]));\n\t\t\t}\n\t\t}\n\t}\n\telse //m_color_bytes == 3/4...\n\t{\n\t\tvoid(*draw_pixel)(int x, int y, unsigned int rgb) = m_driver->draw_pixel;\n\t\tfor (int y = y0; y <= y1; y++)\n\t\t{\n\t\t\t//Left surface\n\t\t\tfor (int x = x0; x <= (x1 - offset); x++)\n\t\t\t{\n\t\t\t\tdraw_pixel(x, y, ((unsigned int*)s0->m_fb)[y * m_width + x + offset]);\n\t\t\t}\n\t\t\t//Right surface\n\t\t\tfor (int x = x1 - offset; x <= x1; x++)\n\t\t\t{\n\t\t\t\tdraw_pixel(x, y, ((unsigned int*)s1->m_fb)[y * m_width + x + offset - x1 + x0]);\n\t\t\t}\n\t\t}\n\t}\n\n\tm_phy_write_index++;\n\treturn 0;\n}\n"
  },
  {
    "path": "src/core/image.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/resource.h\"\n#include \"../core/display.h\"\n\n#define\tDEFAULT_MASK_COLOR 0xFF080408\nclass c_surface;\n\nclass c_image_operator\n{\npublic:\n\tvirtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR) = 0;\n\tvirtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR) = 0;\n};\n\nclass c_bitmap_operator : public c_image_operator\n{\npublic:\n\tvirtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR)\n\t{\n\t\tASSERT(image_info);\n\t\tBITMAP_INFO* pBitmap = (BITMAP_INFO*)image_info;\n\t\tunsigned short* lower_fb_16 = 0;\n\t\tunsigned int* lower_fb_32 = 0;\n\t\tint lower_fb_width = 0;\n\t\tc_rect lower_fb_rect;\n\t\tif (z_order >= Z_ORDER_LEVEL_1)\n\t\t{\n\t\t\tlower_fb_16 = (unsigned short*)surface->m_layers[z_order - 1].fb;\n\t\t\tlower_fb_32 = (unsigned int*)surface->m_layers[z_order - 1].fb;\n\t\t\tlower_fb_rect = surface->m_layers[z_order - 1].rect;\n\t\t\tlower_fb_width = lower_fb_rect.width();\n\t\t}\n\t\tunsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb);\n\t\tint xsize = pBitmap->width;\n\t\tint ysize = pBitmap->height;\n\t\tconst unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array;\n\t\tint color_bytes = surface->m_color_bytes;\n\t\tfor (int y_ = y; y_ < y + ysize; y_++)\n\t\t{\n\t\t\tfor (int x_ = x; x_ < x + xsize; x_++)\n\t\t\t{\n\t\t\t\tunsigned int rgb = *pData++;\n\t\t\t\tif (mask_rgb_16 == rgb)\n\t\t\t\t{\n\t\t\t\t\tif (lower_fb_rect.pt_in_rect(x_, y_))\n\t\t\t\t\t{//show lower layer\n\t\t\t\t\t\tsurface->draw_pixel(x_, y_, (color_bytes == 4) ? lower_fb_32[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)] : GL_RGB_16_to_32(lower_fb_16[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)]), z_order);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsurface->draw_pixel(x_, y_, GL_RGB_16_to_32(rgb), z_order);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tvirtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR)\n\t{\n\t\tASSERT(image_info);\n\t\tBITMAP_INFO* pBitmap = (BITMAP_INFO*)image_info;\n\t\tif (0 == pBitmap || (src_x + width > pBitmap->width) || (src_y + height > pBitmap->height))\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tunsigned short* lower_fb_16 = 0;\n\t\tunsigned int* lower_fb_32 = 0;\n\t\tint lower_fb_width = 0;\n\t\tc_rect lower_fb_rect;\n\t\tif (z_order >= Z_ORDER_LEVEL_1)\n\t\t{\n\t\t\tlower_fb_16 = (unsigned short*)surface->m_layers[z_order - 1].fb;\n\t\t\tlower_fb_32 = (unsigned int*)surface->m_layers[z_order - 1].fb;\n\t\t\tlower_fb_rect = surface->m_layers[z_order - 1].rect;\n\t\t\tlower_fb_width = lower_fb_rect.width();\n\t\t}\n\t\tunsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb);\n\t\tconst unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array;\n\t\tint color_bytes = surface->m_color_bytes;\n\t\tfor (int y_ = 0; y_ < height; y_++)\n\t\t{\n\t\t\tconst unsigned short* p = &pData[src_x + (src_y + y_) * pBitmap->width];\n\t\t\tfor (int x_ = 0; x_ < width; x_++)\n\t\t\t{\n\t\t\t\tunsigned int rgb = *p++;\n\t\t\t\tif (mask_rgb_16 == rgb)\n\t\t\t\t{\n\t\t\t\t\tif (lower_fb_rect.pt_in_rect(x + x_, y + y_))\n\t\t\t\t\t{//show lower layer\n\t\t\t\t\t\tsurface->draw_pixel(x + x_, y + y_, (color_bytes == 4) ? lower_fb_32[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left] : GL_RGB_16_to_32(lower_fb_16[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left]), z_order);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsurface->draw_pixel(x + x_, y + y_, GL_RGB_16_to_32(rgb), z_order);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\nclass c_image\n{\npublic:\n\tstatic void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR)\n\t{\n\t\timage_operator->draw_image(surface, z_order, image_info, x, y, mask_rgb);\n\t}\n\n\tstatic void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR)\n\t{\n\t\timage_operator->draw_image(surface, z_order, image_info, x, y, src_x, src_y, width, height, mask_rgb);\n\t}\n\t\n\tstatic c_image_operator* image_operator;\n};\n"
  },
  {
    "path": "src/core/resource.h",
    "content": "#pragma once\n\n//BITMAP\ntypedef struct struct_bitmap_info\n{\n\tunsigned short width;\n\tunsigned short height;\n\tunsigned short color_bits;//support 16 bits only\n\tconst unsigned short* pixel_color_array;\n} BITMAP_INFO;\n\n//FONT\ntypedef struct struct_lattice\n{\n\tunsigned int\t\t\tutf8_code;\n\tunsigned char\t\t\twidth;\n\tconst unsigned char*\tpixel_buffer;\n} LATTICE;\n\ntypedef struct struct_lattice_font_info\n{\n\tunsigned char\theight;\n\tunsigned int\tcount;\n\tLATTICE*\t\tlattice_array;\n} LATTICE_FONT_INFO;\n"
  },
  {
    "path": "src/core/theme.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/resource.h\"\n\n//Rebuild gui library once you change this file\nenum FONT_LIST\n{\n\tFONT_NULL,\n\tFONT_DEFAULT,\n\tFONT_CUSTOM1,\n\tFONT_CUSTOM2,\n\tFONT_CUSTOM3,\n\tFONT_CUSTOM4,\n\tFONT_CUSTOM5,\n\tFONT_CUSTOM6,\n\n\tFONT_MAX\n};\n\nenum IMAGE_LIST\n{\n\tIMAGE_CUSTOM1,\n\tIMAGE_CUSTOM2,\n\tIMAGE_CUSTOM3,\n\tIMAGE_CUSTOM4,\n\tIMAGE_CUSTOM5,\n\tIMAGE_CUSTOM6,\n\n\tIMAGE_MAX\n};\n\nenum COLOR_LIST\n{\n\tCOLOR_WND_FONT,\n\tCOLOR_WND_NORMAL,\n\tCOLOR_WND_PUSHED,\n\tCOLOR_WND_FOCUS,\n\tCOLOR_WND_BORDER,\n\n\tCOLOR_CUSTOME1,\n\tCOLOR_CUSTOME2,\n\tCOLOR_CUSTOME3,\n\tCOLOR_CUSTOME4,\n\tCOLOR_CUSTOME5,\n\tCOLOR_CUSTOME6,\n\n\tCOLOR_MAX\n};\n\nclass c_theme\n{\npublic:\n\tstatic int add_font(FONT_LIST index, const void* font)\n\t{\n\t\tif (index >= FONT_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\ts_font_map[index] = font;\n\t\treturn 0;\n\t}\n\n\tstatic const void* get_font(FONT_LIST index)\n\t{\n\t\tif (index >= FONT_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\treturn s_font_map[index];\n\t}\n\n\tstatic int add_image(IMAGE_LIST index, const void* image_info)\n\t{\n\t\tif (index >= IMAGE_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\ts_image_map[index] = image_info;\n\t\treturn 0;\n\t}\n\n\tstatic const void* get_image(IMAGE_LIST index)\n\t{\n\t\tif (index >= IMAGE_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\treturn s_image_map[index];\n\t}\n\t\n\tstatic int add_color(COLOR_LIST index, const unsigned int color)\n\t{\n\t\tif (index >= COLOR_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\ts_color_map[index] = color;\n\t\treturn 0;\n\t}\n\n\tstatic const unsigned int get_color(COLOR_LIST index)\n\t{\n\t\tif (index >= COLOR_MAX)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\treturn s_color_map[index];\n\t}\n\nprivate:\n\tstatic const void* s_font_map[FONT_MAX];\n\tstatic const void* s_image_map[IMAGE_MAX];\n\tstatic unsigned int s_color_map[COLOR_MAX];\n};\n"
  },
  {
    "path": "src/core/wnd.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/resource.h\"\n#include \"../core/display.h\"\n\nclass c_wnd;\nclass c_surface;\n\ntypedef enum\n{\n\tATTR_VISIBLE\t= 0x40000000L,\n\tATTR_FOCUS\t\t= 0x20000000L,\n\tATTR_PRIORITY\t= 0x10000000L// Handle touch action at high priority\n}WND_ATTRIBUTION;\n\ntypedef enum\n{\n\tSTATUS_NORMAL,\n\tSTATUS_PUSHED,\n\tSTATUS_FOCUSED,\n\tSTATUS_DISABLED\n}WND_STATUS;\n\ntypedef enum\n{\n\tNAV_FORWARD,\n\tNAV_BACKWARD,\n\tNAV_ENTER\n}NAVIGATION_KEY;\n\ntypedef enum\n{\n\tTOUCH_DOWN,\n\tTOUCH_UP\n}TOUCH_ACTION;\n\ntypedef struct struct_wnd_tree\n{\n\tc_wnd*\t\t\t\t\tp_wnd;//window instance\n\tunsigned int\t\t\tresource_id;//ID\n\tconst char*\t\t\t\tstr;//caption\n\tshort   \t\t\t\tx;//position x\n\tshort   \t\t\t\ty;//position y\n\tshort   \t\t\t\twidth;\n\tshort        \t\t\theight;\n\tstruct struct_wnd_tree*\tp_child_tree;//sub tree\n}WND_TREE;\n\ntypedef void (c_wnd::*WND_CALLBACK)(int, int);\n\nclass c_wnd\n{\npublic:\n\tc_wnd() : m_status(STATUS_NORMAL), m_attr((WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)), m_parent(0), m_top_child(0), m_prev_sibling(0), m_next_sibling(0),\n\t\tm_str(0), m_font_color(0), m_bg_color(0), m_id(0), m_z_order(Z_ORDER_LEVEL_0), m_focus_child(0), m_surface(0) {};\n\tvirtual ~c_wnd() {};\n\tvirtual int connect(c_wnd *parent, unsigned short resource_id, const char* str,\n\t\tshort x, short y, short width, short height, WND_TREE* p_child_tree = 0)\n\t{\n\t\tif (0 == resource_id)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\n\t\tm_id = resource_id;\n\t\tset_str(str);\n\t\tm_parent = parent;\n\t\tm_status = STATUS_NORMAL;\n\n\t\tif (parent)\n\t\t{\n\t\t\tm_z_order = parent->m_z_order;\n\t\t\tm_surface = parent->m_surface;\n\t\t}\n\t\tif (0 == m_surface)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -2;\n\t\t}\n\n\t\t/* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/\n\t\tm_wnd_rect.m_left = x;\n\t\tm_wnd_rect.m_top = y;\n\t\tm_wnd_rect.m_right = (x + width - 1);\n\t\tm_wnd_rect.m_bottom = (y + height - 1);\n\n\t\tpre_create_wnd();\n\n\t\tif (0 != parent)\n\t\t{\n\t\t\tparent->add_child_2_tail(this);\n\t\t}\n\n\t\tif (load_child_wnd(p_child_tree) >= 0)\n\t\t{\n\t\t\ton_init_children();\n\t\t}\n\t\treturn 0;\n\t}\n\n\tvoid disconnect()\n\t{\n\t\tif (0 != m_top_child)\n\t\t{\n\t\t\tc_wnd* child = m_top_child;\n\t\t\tc_wnd* next_child = 0;\n\n\t\t\twhile (child)\n\t\t\t{\n\t\t\t\tnext_child = child->m_next_sibling;\n\t\t\t\tchild->disconnect();\n\t\t\t\tchild = next_child;\n\t\t\t}\n\t\t}\n\n\t\tif (0 != m_parent)\n\t\t{\n\t\t\tm_parent->unlink_child(this);\n\t\t}\n\t\tm_focus_child = 0;\n\t\tm_attr = WND_ATTRIBUTION(0);\n\t}\n\n\tvirtual void on_init_children() {}\n\tvirtual void on_paint() {}\n\tvirtual void show_window()\n\t{\n\t\tif (ATTR_VISIBLE == (m_attr & ATTR_VISIBLE))\n\t\t{\n\t\t\ton_paint();\n\t\t\tc_wnd* child = m_top_child;\n\t\t\tif (0 != child)\n\t\t\t{\n\t\t\t\twhile (child)\n\t\t\t\t{\n\t\t\t\t\tchild->show_window();\n\t\t\t\t\tchild = child->m_next_sibling;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tunsigned short get_id() const { return m_id; }\n\tint get_z_order() { return m_z_order; }\n\tc_wnd* get_wnd_ptr(unsigned short id) const\n\t{\n\t\tc_wnd* child = m_top_child;\n\n\t\twhile (child)\n\t\t{\n\t\t\tif (child->get_id() == id)\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tchild = child->m_next_sibling;\n\t\t}\n\n\t\treturn child;\n\t}\n\tunsigned int get_attr() const { return m_attr; }\n\n\tvoid set_str(const char* str) { m_str = str; }\n\tvoid set_attr(WND_ATTRIBUTION attr) { m_attr = attr; }\n\tbool is_focus_wnd() const\n\t{\n\t\treturn ((m_attr & ATTR_VISIBLE) && (m_attr & ATTR_FOCUS)) ? true : false;\n\t}\n\n\tvoid set_font_color(unsigned int color) { m_font_color = color; }\n\tunsigned int get_font_color() { return m_font_color; }\n\tvoid set_bg_color(unsigned int color) { m_bg_color = color; }\n\tunsigned int get_bg_color() { return m_bg_color; }\n\tvoid set_font_type(const LATTICE_FONT_INFO *font_type) { m_font = font_type; }\n\tconst void* get_font_type() { return m_font; }\n\tvoid get_wnd_rect(c_rect &rect) const {\trect = m_wnd_rect; }\n\n\tvoid get_screen_rect(c_rect &rect) const\n\t{\n\t\tint l = 0;\n\t\tint t = 0;\n\t\twnd2screen(l, t);\n\t\trect.set_rect(l, t, m_wnd_rect.width(), m_wnd_rect.height());\n\t}\n\n\tc_wnd* set_child_focus(c_wnd *focus_child)\n\t{\n\t\tASSERT(0 != focus_child);\n\t\tASSERT(focus_child->m_parent == this);\n\n\t\tc_wnd* old_focus_child = m_focus_child;\n\t\tif (focus_child->is_focus_wnd())\n\t\t{\n\t\t\tif (focus_child != old_focus_child)\n\t\t\t{\n\t\t\t\tif (old_focus_child)\n\t\t\t\t{\n\t\t\t\t\told_focus_child->on_kill_focus();\n\t\t\t\t}\n\t\t\t\tm_focus_child = focus_child;\n\t\t\t\tm_focus_child->on_focus();\n\t\t\t}\n\t\t}\n\t\treturn m_focus_child;\n\t}\n\n\tc_wnd* get_parent() const { return m_parent; }\n\tc_wnd* get_last_child() const\n\t{\n\t\tif (0 == m_top_child)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\n\t\tc_wnd* child = m_top_child;\n\n\t\twhile (child->m_next_sibling)\n\t\t{\n\t\t\tchild = child->m_next_sibling;\n\t\t}\n\n\t\treturn child;\n\t}\n\tint\tunlink_child(c_wnd *child)\n\t{\n\t\tif ((0 == child)\n\t\t\t|| (this != child->m_parent))\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\n\t\tif (0 == m_top_child)\n\t\t{\n\t\t\treturn -2;\n\t\t}\n\n\t\tbool find = false;\n\n\t\tc_wnd* tmp_child = m_top_child;\n\t\tif (tmp_child == child)\n\t\t{\n\t\t\tm_top_child = child->m_next_sibling;\n\t\t\tif (0 != child->m_next_sibling)\n\t\t\t{\n\t\t\t\tchild->m_next_sibling->m_prev_sibling = 0;\n\t\t\t}\n\n\t\t\tfind = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile (tmp_child->m_next_sibling)\n\t\t\t{\n\t\t\t\tif (child == tmp_child->m_next_sibling)\n\t\t\t\t{\n\t\t\t\t\ttmp_child->m_next_sibling = child->m_next_sibling;\n\t\t\t\t\tif (0 != child->m_next_sibling)\n\t\t\t\t\t{\n\t\t\t\t\t\tchild->m_next_sibling->m_prev_sibling = tmp_child;\n\t\t\t\t\t}\n\n\t\t\t\t\tfind = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\ttmp_child = tmp_child->m_next_sibling;\n\t\t\t}\n\t\t}\n\n\t\tif (true == find)\n\t\t{\n\t\t\tif (m_focus_child == child)\n\t\t\t{\n\t\t\t\tm_focus_child = 0;\n\t\t\t}\n\n\t\t\tchild->m_next_sibling = 0;\n\t\t\tchild->m_prev_sibling = 0;\n\t\t\treturn 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t}\n\tc_wnd* get_prev_sibling() const { return m_prev_sibling; }\n\tc_wnd* get_next_sibling() const { return m_next_sibling; }\n\n\tc_wnd* search_priority_sibling(c_wnd* root)\n\t{\n\t\tc_wnd* priority_wnd = 0;\n\t\twhile (root)\n\t\t{\n\t\t\tif ((root->m_attr & ATTR_PRIORITY) && (root->m_attr & ATTR_VISIBLE))\n\t\t\t{\n\t\t\t\tpriority_wnd = root;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\troot = root->m_next_sibling;\n\t\t}\n\n\t\treturn priority_wnd;\n\t}\n\n\tvirtual void on_touch(int x, int y, TOUCH_ACTION action)\n\t{\n\t\tx -= m_wnd_rect.m_left;\n\t\ty -= m_wnd_rect.m_top;\n\n\t\tc_wnd* priority_wnd = search_priority_sibling(m_top_child);\n\t\tif (priority_wnd)\n\t\t{\n\t\t\treturn priority_wnd->on_touch(x, y, action);\n\t\t}\n\n\t\tc_wnd* child = m_top_child;\n\t\twhile (child)\n\t\t{\n\t\t\tif (child->is_focus_wnd())\n\t\t\t{\n\t\t\t\tc_rect rect;\n\t\t\t\tchild->get_wnd_rect(rect);\n\t\t\t\tif (true == rect.pt_in_rect(x, y))\n\t\t\t\t{\n\t\t\t\t\treturn child->on_touch(x, y, action);\n\t\t\t\t}\n\t\t\t}\n\t\t\tchild = child->m_next_sibling;\n\t\t}\n\t}\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tc_wnd* priority_wnd = search_priority_sibling(m_top_child);\n\t\tif (priority_wnd)\n\t\t{\n\t\t\treturn priority_wnd->on_navigate(key);\n\t\t}\n\n\t\tif (!is_focus_wnd())\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tif (key != NAV_BACKWARD && key != NAV_FORWARD)\n\t\t{\n\t\t\tif (m_focus_child)\n\t\t\t{\n\t\t\t\tm_focus_child->on_navigate(key);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Move focus\n\t\tc_wnd* old_focus_wnd = m_focus_child;\n\t\t// No current focus wnd, new one.\n\t\tif (!old_focus_wnd)\n\t\t{\n\t\t\tc_wnd* child = m_top_child;\n\t\t\tc_wnd* new_focus_wnd = 0;\n\t\t\twhile (child)\n\t\t\t{\n\t\t\t\tif (child->is_focus_wnd())\n\t\t\t\t{\n\t\t\t\t\tnew_focus_wnd = child;\n\t\t\t\t\tnew_focus_wnd->m_parent->set_child_focus(new_focus_wnd);\n\t\t\t\t\tchild = child->m_top_child;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tchild = child->m_next_sibling;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Move focus from old wnd to next wnd\n\t\tc_wnd* next_focus_wnd = (key == NAV_FORWARD) ? old_focus_wnd->m_next_sibling : old_focus_wnd->m_prev_sibling;\n\t\twhile (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))\n\t\t{// Search neighbor of old focus wnd\n\t\t\tnext_focus_wnd = (key == NAV_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;\n\t\t}\n\t\tif (!next_focus_wnd)\n\t\t{// Search whole brother wnd\n\t\t\tnext_focus_wnd = (key == NAV_FORWARD) ? old_focus_wnd->m_parent->m_top_child : old_focus_wnd->m_parent->get_last_child();\n\t\t\twhile (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))\n\t\t\t{\n\t\t\t\tnext_focus_wnd = (key == NAV_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;\n\t\t\t}\n\t\t}\n\t\tif (next_focus_wnd)\n\t\t{\n\t\t\tnext_focus_wnd->m_parent->set_child_focus(next_focus_wnd);\n\t\t}\n\t}\n\n\tc_surface* get_surface() { return m_surface; }\n\tvoid set_surface(c_surface* surface) { m_surface = surface; }\nprotected:\n\tvirtual void pre_create_wnd() {};\n\tvoid add_child_2_tail(c_wnd *child)\n\t{\n\t\tif (0 == child)return;\n\t\tif (child == get_wnd_ptr(child->m_id))return;\n\n\t\tif (0 == m_top_child)\n\t\t{\n\t\t\tm_top_child = child;\n\t\t\tchild->m_prev_sibling = 0;\n\t\t\tchild->m_next_sibling = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tc_wnd* last_child = get_last_child();\n\t\t\tif (0 == last_child)\n\t\t\t{\n\t\t\t\tASSERT(false);\n\t\t\t}\n\t\t\tlast_child->m_next_sibling = child;\n\t\t\tchild->m_prev_sibling = last_child;\n\t\t\tchild->m_next_sibling = 0;\n\t\t}\n\t}\n\n\tvoid wnd2screen(int &x, int &y) const\n\t{\n\t\tc_wnd* parent = m_parent;\n\t\tc_rect rect;\n\n\t\tx += m_wnd_rect.m_left;\n\t\ty += m_wnd_rect.m_top;\n\n\t\twhile (0 != parent)\n\t\t{\n\t\t\tparent->get_wnd_rect(rect);\n\t\t\tx += rect.m_left;\n\t\t\ty += rect.m_top;\n\n\t\t\tparent = parent->m_parent;\n\t\t}\n\t}\n\n\tint load_child_wnd(WND_TREE *p_child_tree)\n\t{\n\t\tif (0 == p_child_tree)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\tint sum = 0;\n\n\t\tWND_TREE* p_cur = p_child_tree;\n\t\twhile (p_cur->p_wnd)\n\t\t{\n\t\t\tp_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);\n\t\t\tp_cur++;\n\t\t\tsum++;\n\t\t}\n\t\treturn sum;\n\t}\n\tvoid set_active_child(c_wnd* child) { m_focus_child = child; }\n\n\tvirtual void on_focus() {};\n\tvirtual void on_kill_focus() {};\nprotected:\n\tunsigned short\tm_id;\n\tWND_STATUS\t\tm_status;\n\tWND_ATTRIBUTION\tm_attr;\n\tc_rect\t\t\tm_wnd_rect;\t\t//position relative to parent window.\n\tc_wnd*\t\t\tm_parent;\t\t//parent window\n\tc_wnd*\t\t\tm_top_child;\t//the first sub window would be navigated\n\tc_wnd*\t\t\tm_prev_sibling;\t//previous brother\n\tc_wnd*\t\t\tm_next_sibling;\t//next brother\n\tc_wnd*\t\t\tm_focus_child;\t//current focused window\n\tconst char*\t\tm_str;\t\t\t//caption\n\n\tconst void*\t\tm_font;\t\t\t//font face\n\tunsigned int\tm_font_color;\n\tunsigned int\tm_bg_color;\n\n\tint\t\t\t\tm_z_order;\t\t//the graphic level for rendering\n\tc_surface*\t\tm_surface;\n};\n"
  },
  {
    "path": "src/core/word.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/resource.h\"\n#include \"../core/display.h\"\n#include <string.h>\n#include <stdio.h>\n\n#define VALUE_STR_LEN\t16\n\nclass c_surface;\nclass c_font_operator\n{\npublic:\n\tvirtual void draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color) = 0;\n\tvirtual void draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT) = 0;\n\tvirtual void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color) = 0;\n\tvirtual void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT) = 0;\n\tvirtual int get_str_size(const void* string, const void* font, int& width, int& height) = 0;\n\n\tvoid get_string_pos(const void* string, const void* font, c_rect rect, unsigned int align_type, int& x, int& y)\n\t{\n\t\tint x_size, y_size;\n\t\tget_str_size(string, font, x_size, y_size);\n\t\tint height = rect.m_bottom - rect.m_top + 1;\n\t\tint width = rect.m_right - rect.m_left + 1;\n\t\tx = y = 0;\n\t\tswitch (align_type & ALIGN_HMASK)\n\t\t{\n\t\tcase ALIGN_HCENTER:\n\t\t\t//m_text_org_x=0\n\t\t\tif (width > x_size)\n\t\t\t{\n\t\t\t\tx = (width - x_size) / 2;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase ALIGN_LEFT:\n\t\t\tx = 0;\n\t\t\tbreak;\n\t\tcase ALIGN_RIGHT:\n\t\t\t//m_text_org_x=0\n\t\t\tif (width > x_size)\n\t\t\t{\n\t\t\t\tx = width - x_size;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(0);\n\t\t\tbreak;\n\t\t}\n\t\tswitch (align_type & ALIGN_VMASK)\n\t\t{\n\t\tcase ALIGN_VCENTER:\n\t\t\t//m_text_org_y=0\n\t\t\tif (height > y_size)\n\t\t\t{\n\t\t\t\ty = (height - y_size) / 2;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase ALIGN_TOP:\n\t\t\ty = 0;\n\t\t\tbreak;\n\t\tcase ALIGN_BOTTOM:\n\t\t\t//m_text_org_y=0\n\t\t\tif (height > y_size)\n\t\t\t{\n\t\t\t\ty = height - y_size;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(0);\n\t\t\tbreak;\n\t\t}\n\t}\n};\n\nclass c_lattice_font_op : public c_font_operator\n{\npublic:\n\tvoid draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)\n\t{\n\t\tconst char* s = (const char*)string;\n\t\tif (0 == s)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tint offset = 0;\n\t\tunsigned int utf8_code;\n\t\twhile (*s)\n\t\t{\n\t\t\ts += get_utf8_code(s, utf8_code);\n\t\t\toffset += draw_single_char(surface, z_order, utf8_code, (x + offset), y, (const LATTICE_FONT_INFO*)font, font_color, bg_color);\n\t\t}\n\t}\n\n\tvoid draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)\n\t{\n\t\tconst char* s = (const char*)string;\n\t\tif (0 == s)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tint x, y;\n\t\tget_string_pos(s, (const LATTICE_FONT_INFO*)font, rect, align_type, x, y);\n\t\tdraw_string(surface, z_order, string, rect.m_left + x, rect.m_top + y, font, font_color, bg_color);\n\t}\n\n\tvoid draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)\n\t{\n\t\tchar buf[VALUE_STR_LEN];\n\t\tvalue_2_string(value, dot_position, buf, VALUE_STR_LEN);\n\t\tdraw_string(surface, z_order, buf, x, y, (const LATTICE_FONT_INFO*)font, font_color, bg_color);\n\t}\n\n\tvoid draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)\n\t{\n\t\tchar buf[VALUE_STR_LEN];\n\t\tvalue_2_string(value, dot_position, buf, VALUE_STR_LEN);\n\t\tdraw_string_in_rect(surface, z_order, buf, rect, (const LATTICE_FONT_INFO*)font, font_color, bg_color, align_type);\n\t}\n\n\tint get_str_size(const void *string, const void* font, int& width, int& height)\n\t{\n\t\tconst char* s = (const char*)string;\n\t\tif (0 == s || 0 == font)\n\t\t{\n\t\t\twidth = height = 0;\n\t\t\treturn -1;\n\t\t}\n\n\t\tint lattice_width = 0;\n\t\tunsigned int utf8_code;\n\t\tint utf8_bytes;\n\t\twhile (*s)\n\t\t{\n\t\t\tutf8_bytes = get_utf8_code(s, utf8_code);\n\t\t\tconst LATTICE* p_lattice = get_lattice((const LATTICE_FONT_INFO*)font, utf8_code);\n\t\t\tlattice_width += p_lattice ? p_lattice->width : ((const LATTICE_FONT_INFO*)font)->height;\n\t\t\ts += utf8_bytes;\n\t\t}\n\t\twidth = lattice_width;\n\t\theight = ((const LATTICE_FONT_INFO*)font)->height;\n\t\treturn 0;\n\t}\nprivate:\n\tvoid value_2_string(int value, int dot_position, char* buf, int len)\n\t{\n\t\tmemset(buf, 0, len);\n\t\tswitch (dot_position)\n\t\t{\n\t\tcase 0:\n\t\t\tsprintf(buf, \"%d\", value);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsprintf(buf, \"%.1f\", value * 1.0 / 10);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsprintf(buf, \"%.2f\", value * 1.0 / 100);\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsprintf(buf, \"%.3f\", value * 1.0 / 1000);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tint draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const LATTICE_FONT_INFO* font, unsigned int font_color, unsigned int bg_color)\n\t{\n\t\tunsigned int error_color = 0xFFFFFFFF;\n\t\tif (font)\n\t\t{\n\t\t\tconst LATTICE* p_lattice = get_lattice(font, utf8_code);\n\t\t\tif (p_lattice)\n\t\t\t{\n\t\t\t\tdraw_lattice(surface, z_order, x, y, p_lattice->width, font->height, p_lattice->pixel_buffer, font_color, bg_color);\n\t\t\t\treturn p_lattice->width;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\terror_color = GL_RGB(255, 0, 0);\n\t\t}\n\n\t\t//lattice/font not found, draw \"X\"\n\t\tint len = 16;\n\t\tfor (int y_ = 0; y_ < len; y_++)\n\t\t{\n\t\t\tfor (int x_ = 0; x_ < len; x_++)\n\t\t\t{\n\t\t\t\tint diff = (x_ - y_);\n\t\t\t\tint sum = (x_ + y_);\n\t\t\t\t(diff == 0 || diff == -1 || diff == 1 || sum == len || sum == (len - 1) || sum == (len + 1)) ?\n\t\t\t\t\tsurface->draw_pixel((x + x_), (y + y_), error_color, z_order) : surface->draw_pixel((x + x_), (y + y_), 0, z_order);\n\t\t\t}\n\t\t}\n\t\treturn len;\n\t}\n\n\tvoid 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)\n\t{\n\t\tunsigned int r, g, b, rgb;\n\t\tunsigned char blk_value = *p_data++;\n\t\tunsigned char blk_cnt = *p_data++;\n\t\tb = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8;\n\t\tg = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8;\n\t\tr = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8;\n\t\trgb = GL_RGB(r, g, b);\n\t\tfor (int y_ = 0; y_ < height; y_++)\n\t\t{\n\t\t\tfor (int x_ = 0; x_ < width; x_++)\n\t\t\t{\n\t\t\t\tASSERT(blk_cnt);\n\t\t\t\tif (0x00 == blk_value)\n\t\t\t\t{\n\t\t\t\t\tif (GL_ARGB_A(bg_color))\n\t\t\t\t\t{\n\t\t\t\t\t\tsurface->draw_pixel(x + x_, y + y_, bg_color, z_order);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsurface->draw_pixel((x + x_), (y + y_), rgb, z_order);\n\t\t\t\t}\n\t\t\t\tif (--blk_cnt == 0)\n\t\t\t\t{//reload new block\n\t\t\t\t\tblk_value = *p_data++;\n\t\t\t\t\tblk_cnt = *p_data++;\n\t\t\t\t\tb = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8;\n\t\t\t\t\tg = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8;\n\t\t\t\t\tr = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8;\n\t\t\t\t\trgb = GL_RGB(r, g, b);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tconst LATTICE* get_lattice(const LATTICE_FONT_INFO* font, unsigned int utf8_code)\n\t{\n\t\tint first = 0;\n\t\tint last = font->count - 1;\n\t\tint middle = (first + last) / 2;\n\n\t\twhile (first <= last)\n\t\t{\n\t\t\tif (font->lattice_array[middle].utf8_code < utf8_code)\n\t\t\t\tfirst = middle + 1;\n\t\t\telse if (font->lattice_array[middle].utf8_code == utf8_code)\n\t\t\t{\n\t\t\t\treturn &font->lattice_array[middle];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlast = middle - 1;\n\t\t\t}\n\t\t\tmiddle = (first + last) / 2;\n\t\t}\n\t\treturn 0;\n\t}\n\t\n\tstatic int get_utf8_code(const char* s, unsigned int& output_utf8_code)\n\t{\n\t\tstatic unsigned char s_utf8_length_table[256] =\n\t\t{\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t\t\t2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t\t\t3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n\t\t\t4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1\n\t\t};\n\n\t\tunsigned char* us = (unsigned char*)s;\n\t\tint utf8_bytes = s_utf8_length_table[*us];\n\t\tswitch (utf8_bytes)\n\t\t{\n\t\tcase 1:\n\t\t\toutput_utf8_code = *us;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\toutput_utf8_code = (*us << 8) | (*(us + 1));\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\toutput_utf8_code = (*us << 16) | ((*(us + 1)) << 8) | *(us + 2);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\toutput_utf8_code = (*us << 24) | ((*(us + 1)) << 16) | (*(us + 2) << 8) | *(us + 3);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t\treturn utf8_bytes;\n\t}\n};\n\nclass c_word\n{\npublic:\n\tstatic void draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)//string: char or wchar_t\n\t{\n\t\tfontOperator->draw_string(surface, z_order, string, x, y, font, font_color, bg_color);\n\t}\n\n\tstatic void draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)//string: char or wchar_t\n\t{\n\t\tfontOperator->draw_string_in_rect(surface, z_order, string, rect, font, font_color, bg_color, align_type);\n\t}\n\n\tstatic void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)\n\t{\n\t\tfontOperator->draw_value_in_rect(surface, z_order, value, dot_position, rect, font, font_color, bg_color, align_type);\n\t}\n\n\tstatic void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)\n\t{\n\t\tfontOperator->draw_value(surface, z_order, value, dot_position, x, y, font, font_color, bg_color);\n\t}\n\t\n\tstatic int get_str_size(const void* string, const void* font, int& width, int& height)\n\t{\n\t\treturn fontOperator->get_str_size(string, font, width, height);\n\t}\n\tstatic c_font_operator* fontOperator;\n};\n"
  },
  {
    "path": "src/widgets/button.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/wnd.h\"\n#include \"../core/resource.h\"\n#include \"../core/word.h\"\n#include \"../core/display.h\"\n#include \"../core/theme.h\"\n\nclass c_button : public c_wnd\n{\npublic:\n\tvoid set_on_click(WND_CALLBACK on_click) { this->on_click = on_click; }\nprotected:\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\n\t\tswitch (m_status)\n\t\t{\n\t\tcase STATUS_NORMAL:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\t\tif (m_str)\n\t\t\t{\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase STATUS_FOCUSED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\tif (m_str)\n\t\t\t{\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase STATUS_PUSHED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);\n\t\t\tm_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);\n\t\t\tif (m_str)\n\t\t\t{\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t}\n\tvirtual void on_focus()\n\t{\n\t\tm_status = STATUS_FOCUSED;\n\t\ton_paint();\n\t}\n\tvirtual void on_kill_focus()\n\t{\n\t\tm_status = STATUS_NORMAL;\n\t\ton_paint();\n\t}\n\tvirtual void pre_create_wnd()\n\t{\n\t\ton_click = 0;\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t}\n\n\tvirtual void on_touch(int x, int y, TOUCH_ACTION action)\n\t{\n\t\tif (action == TOUCH_DOWN)\n\t\t{\n\t\t\tm_parent->set_child_focus(this);\n\t\t\tm_status = STATUS_PUSHED;\n\t\t\ton_paint();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_status = STATUS_FOCUSED;\n\t\t\ton_paint();\n\t\t\tif(on_click)\n\t\t\t{\n\t\t\t\t(m_parent->*(on_click))(m_id, 0);\n\t\t\t}\n\t\t}\n\t}\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tswitch (key)\n\t\t{\n\t\tcase NAV_ENTER:\n\t\t\ton_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN);\n\t\t\ton_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP);\n\t\t\tbreak;\n\t\tcase NAV_FORWARD:\n\t\tcase NAV_BACKWARD:\n\t\t\tbreak;\n\t\t}\n\t\treturn c_wnd::on_navigate(key);\n\t}\n\tWND_CALLBACK on_click;\n};\n"
  },
  {
    "path": "src/widgets/dialog.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/wnd.h\"\n#include \"../core/display.h\"\n#include \"../core/resource.h\"\n#include \"../core/word.h\"\n#include \"../core/theme.h\"\n\nclass c_surface;\nclass c_dialog;\n\ntypedef struct\n{\n\tc_dialog* \tdialog;\n\tc_surface*\tsurface;\n} DIALOG_ARRAY;\n\nclass c_dialog : public c_wnd\n{\npublic:\n\tstatic int open_dialog(c_dialog* p_dlg, bool modal_mode = true)\n\t{\n\t\tif (0 == p_dlg)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn 0;\n\t\t}\n\t\tc_dialog* cur_dlg = get_the_dialog(p_dlg->get_surface());\n\t\tif (cur_dlg == p_dlg)\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (cur_dlg)\n\t\t{\n\t\t\tcur_dlg->set_attr(WND_ATTRIBUTION(0));\n\t\t}\n\n\t\tc_rect rc;\n\t\tp_dlg->get_screen_rect(rc);\n\t\tp_dlg->get_surface()->activate_layer(rc, p_dlg->m_z_order);\n\n\t\tp_dlg->set_attr(modal_mode ? (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY) : (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS));\n\t\tp_dlg->show_window();\n\t\tp_dlg->set_me_the_dialog();\n\t\treturn 1;\n\t}\n\n\tstatic int close_dialog(c_surface* surface)\n\t{\n\t\tc_dialog* dlg = get_the_dialog(surface);\n\n\t\tif (0 == dlg)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\n\t\tdlg->set_attr(WND_ATTRIBUTION(0));\n\t\tsurface->activate_layer(c_rect(), dlg->m_z_order);//inactivate the layer of dialog by empty rect.\n\n\t\t//clear the dialog\n\t\tfor (int i = 0; i < SURFACE_CNT_MAX; i++)\n\t\t{\n\t\t\tif (ms_the_dialogs[i].surface == surface)\n\t\t\t{\n\t\t\t\tms_the_dialogs[i].dialog = 0;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tASSERT(false);\n\t\treturn -1;\n\t}\n\n\tstatic c_dialog* get_the_dialog(c_surface* surface)\n\t{\n\t\tfor (int i = 0; i < SURFACE_CNT_MAX; i++)\n\t\t{\n\t\t\tif (ms_the_dialogs[i].surface == surface)\n\t\t\t{\n\t\t\t\treturn ms_the_dialogs[i].dialog;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = WND_ATTRIBUTION(0);// no focus/visible\n\t\tm_z_order = Z_ORDER_LEVEL_1;\n\t\tm_bg_color = GL_RGB(33, 42, 53);\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tm_surface->fill_rect(rect, m_bg_color, m_z_order);\n\n\t\tif (m_str)\n\t\t{\n\t\t\tc_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));\n\t\t}\n\t}\nprivate:\n\tint set_me_the_dialog()\n\t{\n\t\tc_surface* surface = get_surface();\n\t\tfor (int i = 0; i < SURFACE_CNT_MAX; i++)\n\t\t{\n\t\t\tif (ms_the_dialogs[i].surface == surface)\n\t\t\t{\n\t\t\t\tms_the_dialogs[i].dialog = this;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tfor (int i = 0; i < SURFACE_CNT_MAX; i++)\n\t\t{\n\t\t\tif (ms_the_dialogs[i].surface == 0)\n\t\t\t{\n\t\t\t\tms_the_dialogs[i].dialog = this;\n\t\t\t\tms_the_dialogs[i].surface = surface;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tASSERT(false);\n\t\treturn -2;\n\t}\n\tstatic DIALOG_ARRAY ms_the_dialogs[SURFACE_CNT_MAX];\n};\n"
  },
  {
    "path": "src/widgets/edit.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/wnd.h\"\n#include \"../core/resource.h\"\n#include \"../core/word.h\"\n#include \"../core/display.h\"\n#include \"../core/theme.h\"\n#include \"../widgets/button.h\"\n#include \"../widgets/label.h\"\n#include \"../widgets/keyboard.h\"\n#include <string.h>\n\n#define MAX_EDIT_STRLEN\t\t32\n#define IDD_KEY_BOARD\t\t0x1\nclass c_edit : public c_wnd\n{\n\tfriend class c_keyboard;\npublic:\n\tconst char* get_text(){return m_str;}\n\tvoid set_text(const char* str)\n\t{\n\t\tif (str != 0 && strlen(str) < sizeof(m_str))\n\t\t{\n\t\t\tstrcpy(m_str, str);\n\t\t}\n\t}\n\tvoid set_keyboard_style(KEYBOARD_STYLE kb_sytle) { m_kb_style = kb_sytle; }\n\t\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\tm_kb_style = STYLE_ALL_BOARD;\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\n\t\tmemset(m_str_input, 0, sizeof(m_str_input));\n\t\tmemset(m_str, 0, sizeof(m_str));\n\t\tset_text(c_wnd::m_str);\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect, kb_rect;\n\t\tget_screen_rect(rect);\n\t\ts_keyboard.get_screen_rect(kb_rect);\n\t\tswitch (m_status)\n\t\t{\n\t\tcase STATUS_NORMAL:\n\t\t\tif ((s_keyboard.get_attr()&ATTR_VISIBLE) == ATTR_VISIBLE)\n\t\t\t{\n\t\t\t\ts_keyboard.close_keyboard();\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\t\t}\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tcase STATUS_FOCUSED:\n\t\t\tif ((s_keyboard.get_attr()&ATTR_VISIBLE) == ATTR_VISIBLE)\n\t\t\t{\n\t\t\t\ts_keyboard.close_keyboard();\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\t\t}\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tcase STATUS_PUSHED:\n\t\t\tif ((s_keyboard.get_attr()&ATTR_VISIBLE) != ATTR_VISIBLE)\n\t\t\t{\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY);\n\t\t\t\ts_keyboard.open_keyboard(this, IDD_KEY_BOARD, m_kb_style, WND_CALLBACK(&c_edit::on_key_board_click));\n\t\t\t}\n\t\t\tm_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());\n\t\t\tm_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);\n\t\t\tstrlen(m_str_input) ? c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str_input, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER) :\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t}\n\t}\n\tvirtual void on_focus()\n\t{\n\t\tm_status = STATUS_FOCUSED;\n\t\ton_paint();\n\t}\n\tvirtual void on_kill_focus()\n\t{\n\t\tm_status = STATUS_NORMAL;\n\t\ton_paint();\n\t}\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tswitch (key)\n\t\t{\n\t\tcase NAV_ENTER:\n\t\t\t(m_status == STATUS_PUSHED) ? s_keyboard.on_navigate(key) : (on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN), on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP));\n\t\t\treturn;\n\t\tcase NAV_BACKWARD:\n\t\tcase NAV_FORWARD:\n\t\t\treturn (m_status == STATUS_PUSHED) ? s_keyboard.on_navigate(key) : c_wnd::on_navigate(key);\n\t\t}\n\t}\n\tvirtual void on_touch(int x, int y, TOUCH_ACTION action)\n\t{\n\t\t(action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y);\n\t}\t\n\tvoid on_key_board_click(int id, int param)\n\t{\n\t\tswitch (param)\n\t\t{\n\t\tcase CLICK_CHAR:\n\t\t\tstrcpy(m_str_input, s_keyboard.get_str());\n\t\t\ton_paint();\n\t\t\tbreak;\n\t\tcase CLICK_ENTER:\n\t\t\tif (strlen(m_str_input))\n\t\t\t{\n\t\t\t\tmemcpy(m_str, m_str_input, sizeof(m_str_input));\n\t\t\t}\n\t\t\tm_status = STATUS_FOCUSED;\n\t\t\ton_paint();\n\t\t\tbreak;\n\t\tcase CLICK_ESC:\n\t\t\tmemset(m_str_input, 0, sizeof(m_str_input));\n\t\t\tm_status = STATUS_FOCUSED;\n\t\t\ton_paint();\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\t}\nprivate:\n\tvoid on_touch_down(int x, int y)\n\t{\n\t\tc_rect kb_rect_relate_2_edit_parent;\n\t\ts_keyboard.get_wnd_rect(kb_rect_relate_2_edit_parent);\n\t\tkb_rect_relate_2_edit_parent.m_left += m_wnd_rect.m_left;\n\t\tkb_rect_relate_2_edit_parent.m_right += m_wnd_rect.m_left;\n\t\tkb_rect_relate_2_edit_parent.m_top += m_wnd_rect.m_top;\n\t\tkb_rect_relate_2_edit_parent.m_bottom += m_wnd_rect.m_top;\n\n\t\tif (m_wnd_rect.pt_in_rect(x, y))\n\t\t{//click edit box\n\t\t\tif (STATUS_NORMAL == m_status)\n\t\t\t{\n\t\t\t\tm_parent->set_child_focus(this);\n\t\t\t}\n\t\t}\n\t\telse if (kb_rect_relate_2_edit_parent.pt_in_rect(x, y))\n\t\t{//click key board\n\t\t\tc_wnd::on_touch(x, y, TOUCH_DOWN);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (STATUS_PUSHED == m_status)\n\t\t\t{\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\ton_paint();\n\t\t\t}\n\t\t}\n\t}\n\tvoid on_touch_up(int x, int y)\n\t{\n\t\tif (STATUS_FOCUSED == m_status)\n\t\t{\n\t\t\tm_status = STATUS_PUSHED;\n\t\t\ton_paint();\n\t\t}\n\t\telse if (STATUS_PUSHED == m_status)\n\t\t{\n\t\t\tif (m_wnd_rect.pt_in_rect(x, y))\n\t\t\t{//click edit box\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\ton_paint();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tc_wnd::on_touch(x, y, TOUCH_UP);\n\t\t\t}\n\t\t}\n\t}\n\tstatic c_keyboard  s_keyboard;\n\tKEYBOARD_STYLE m_kb_style;\n\tchar m_str_input[MAX_EDIT_STRLEN];\n\tchar m_str[MAX_EDIT_STRLEN];\n};\n"
  },
  {
    "path": "src/widgets/keyboard.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/resource.h\"\n#include \"../core/word.h\"\n#include \"../core/wnd.h\"\n#include \"../core/display.h\"\n#include \"../core/theme.h\"\n#include \"../widgets/button.h\"\n#include <string.h>\n\n//Changing key width/height will change the width/height of keyboard\n#define KEY_WIDTH          65\n#define KEY_HEIGHT         38\n\n#define KEYBOARD_WIDTH\t\t((KEY_WIDTH + 2) * 10)\n#define KEYBOARD_HEIGHT\t\t((KEY_HEIGHT + 2) * 4)\n#define NUM_BOARD_WIDTH\t\t((KEY_WIDTH + 2) * 4)\n#define NUM_BOARD_HEIGHT\t((KEY_HEIGHT + 2) * 4)\n\n#define CAPS_WIDTH\t\t\t(KEY_WIDTH * 3 / 2)\n#define DEL_WIDTH\t\t\t(KEY_WIDTH * 3 / 2 + 1)\n#define ESC_WIDTH\t\t\t(KEY_WIDTH * 2 + 2)\n#define SWITCH_WIDTH\t\t(KEY_WIDTH * 3 / 2 )\n#define SPACE_WIDTH\t\t\t(KEY_WIDTH * 3 + 2 * 2)\n#define DOT_WIDTH\t\t\t(KEY_WIDTH * 3 / 2 + 3)\n#define ENTER_WIDTH\t\t\t(KEY_WIDTH * 2 + 2)\n\n#define POS_X(c)\t\t\t((KEY_WIDTH * c) + (c + 1) * 2)\n#define POS_Y(r)\t\t\t((KEY_HEIGHT * r) + (r + 1) * 2)\n\n#define KEYBOARD_CLICK\t\t\t0x5014\n#define ON_KEYBORAD_UPDATE(func)  \\\n{MSG_TYPE_WND, KEYBOARD_CLICK, 0,  msgCallback(&func)},\n\ntypedef enum\n{\n\tSTATUS_UPPERCASE,\n\tSTATUS_LOWERCASE\n}KEYBOARD_STATUS;\n\ntypedef enum\n{\n\tSTYLE_ALL_BOARD,\n\tSTYLE_NUM_BOARD\n}KEYBOARD_STYLE;\n\ntypedef enum\n{\n\tCLICK_CHAR,\n\tCLICK_ENTER,\n\tCLICK_ESC\n}CLICK_STATUS;\n\nextern WND_TREE g_key_board_children[];\nextern WND_TREE g_number_board_children[];\nclass c_keyboard: public c_wnd\n{\npublic:\n\tc_keyboard() { m_attr = WND_ATTRIBUTION(0); }\n\tint open_keyboard(c_wnd *user, unsigned short resource_id, KEYBOARD_STYLE style, WND_CALLBACK on_click)\n\t{\n\t\tc_rect user_rect;\n\t\tuser->get_wnd_rect(user_rect);\n\t\tif ((style != STYLE_ALL_BOARD) && (style != STYLE_NUM_BOARD))\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\tif (style == STYLE_ALL_BOARD)\n\t\t{//Place keyboard at the bottom of user's parent window.\n\t\t\tc_rect user_parent_rect;\n\t\t\tuser->get_parent()->get_wnd_rect(user_parent_rect);\n\t\t\tc_wnd::connect(user, resource_id, 0, (0 - user_rect.m_left), (user_parent_rect.height() - user_rect.m_top - KEYBOARD_HEIGHT - 1), KEYBOARD_WIDTH, KEYBOARD_HEIGHT, g_key_board_children);\n\t\t}\n\t\telse if (style == STYLE_NUM_BOARD)\n\t\t{//Place keyboard below the user window.\n\t\t\tc_wnd::connect(user, resource_id, 0, 0, user_rect.height(), NUM_BOARD_WIDTH, NUM_BOARD_HEIGHT, g_number_board_children);\n\t\t}\n\n\t\tm_on_click = on_click;\n\t\tc_rect rc;\n\t\tget_screen_rect(rc);\n\t\tm_surface->activate_layer(rc, m_z_order);\n\t\tshow_window();\n\t\treturn 0;\n\t}\n\n\tvoid close_keyboard()\n\t{\n\t\tc_wnd::disconnect();\n\t\tm_surface->activate_layer(c_rect(), m_z_order);//inactivate the layer of keyboard by empty rect.\n\t}\n\t\n\tvirtual void on_init_children()\n\t{\n\t\tc_wnd* child = m_top_child;\n\t\tif (0 != child)\n\t\t{\n\t\t\twhile (child)\n\t\t\t{\n\t\t\t\t((c_button*)child)->set_on_click(WND_CALLBACK(&c_keyboard::on_key_clicked));\n\t\t\t\tchild = child->get_next_sibling();\n\t\t\t}\n\t\t}\n\t}\n\n\tKEYBOARD_STATUS get_cap_status(){return m_cap_status;}\n\tchar* get_str() { return m_str; }\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY);\n\t\tm_cap_status = STATUS_UPPERCASE;\n\t\tm_z_order = m_surface->get_max_z_order();\n\t\tmemset(m_str, 0, sizeof(m_str));\n\t\tm_str_len = 0;\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tm_surface->fill_rect(rect, GL_RGB(0, 0, 0), m_z_order);\n\t}\n\n\tvoid on_key_clicked(int id, int param)\n\t{\n\t\tswitch (id)\n\t\t{\n\t\tcase 0x14:\n\t\t\ton_caps_clicked(id, param);\n\t\t\tbreak;\n\t\tcase '\\n':\n\t\t\ton_enter_clicked(id, param);\n\t\t\tbreak;\n\t\tcase 0x1B:\n\t\t\ton_esc_clicked(id, param);\n\t\t\tbreak;\n\t\tcase 0x7F:\n\t\t\ton_del_clicked(id, param);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ton_char_clicked(id, param);\n\t\t\tbreak;\n\t\t}\n\t}\n\tvoid on_char_clicked(int id, int param)\n\t{//id = char ascii code.\n\t\tif (m_str_len >= sizeof(m_str))\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tif ((id >= '0' && id <= '9') || id == ' ' || id == '.')\n\t\t{\n\t\t\tgoto InputChar;\n\t\t}\n\n\t\tif (id >= 'A' && id <= 'Z')\n\t\t{\n\t\t\tif (STATUS_LOWERCASE == m_cap_status)\n\t\t\t{\n\t\t\t\tid += 0x20;\n\t\t\t}\n\t\t\tgoto InputChar;\n\t\t}\n\t\tif (id == 0x90) return;//TBD\n\t\tASSERT(false);\n\tInputChar:\n\t\tm_str[m_str_len++] = id;\n\t\t(m_parent->*(m_on_click))(m_id, CLICK_CHAR);\n\t}\n\tvoid on_del_clicked(int id, int param)\n\t{\n\t\tif (m_str_len <= 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tm_str[--m_str_len] = 0;\n\t\t(m_parent->*(m_on_click))(m_id, CLICK_CHAR);\n\t}\n\tvoid on_caps_clicked(int id, int param)\n\t{\n\t\tm_cap_status = (m_cap_status == STATUS_LOWERCASE) ? STATUS_UPPERCASE : STATUS_LOWERCASE;\n\t\tshow_window();\n\t}\n\tvoid on_enter_clicked(int id, int param)\n\t{\n\t\tmemset(m_str, 0, sizeof(m_str));\n\t\t(m_parent->*(m_on_click))(m_id, CLICK_ENTER);\n\t}\n\tvoid on_esc_clicked(int id, int param)\n\t{\n\t\tmemset(m_str, 0, sizeof(m_str));\n\t\t(m_parent->*(m_on_click))(m_id, CLICK_ESC);\n\t}\nprivate:\n\tchar m_str[32];\n\tint\t m_str_len;\n\tKEYBOARD_STATUS m_cap_status;\n\tWND_CALLBACK m_on_click;\n};\n\nclass c_keyboard_button : public c_button\n{\nprotected:\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tswitch (m_status)\n\t\t{\n\t\tcase STATUS_NORMAL:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\t\tbreak;\n\t\tcase STATUS_FOCUSED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\tbreak;\n\t\tcase STATUS_PUSHED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);\n\t\t\tm_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (m_id == 0x14)\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Caps\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == 0x1B)\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Esc\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == ' ')\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Space\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == '\\n')\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Enter\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == '.')\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \".\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == 0x7F)\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"Back\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\t\telse if (m_id == 0x90)\n\t\t{\n\t\t\treturn c_word::draw_string_in_rect(m_surface, m_z_order, \"?123\", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t\t}\n\n\t\tchar letter[] = { 0, 0 };\n\t\tif (m_id >= 'A' && m_id <= 'Z')\n\t\t{\n\t\t\tletter[0] = (((c_keyboard*)m_parent)->get_cap_status() == STATUS_UPPERCASE) ? m_id : (m_id + 0x20);\n\t\t}\n\t\telse if (m_id >= '0' && m_id <= '9')\n\t\t{\n\t\t\tletter[0] = (char)m_id;\n\t\t}\n\t\tc_word::draw_string_in_rect(m_surface, m_z_order, letter, rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER);\n\t}\n};\n"
  },
  {
    "path": "src/widgets/label.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/wnd.h\"\n#include \"../core/display.h\"\n#include \"../core/resource.h\"\n#include \"../core/theme.h\"\n#include \"../core/word.h\"\n\nclass c_label : public c_wnd\n{\npublic:\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tunsigned int bg_color = m_bg_color ? m_bg_color : m_parent->get_bg_color();\n\t\tget_screen_rect(rect);\n\t\tif (m_str)\n\t\t{\n\t\t\tm_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, bg_color, m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, bg_color, ALIGN_LEFT | ALIGN_VCENTER);\n\t\t}\n\t}\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = ATTR_VISIBLE;\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t}\n};\n"
  },
  {
    "path": "src/widgets/list_box.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/resource.h\"\n#include \"../core/wnd.h\"\n#include \"../core/display.h\"\n#include \"../core/word.h\"\n#include \"../core/theme.h\"\n#include \"../widgets/button.h\"\n#include <string.h>\n\n#define MAX_ITEM_NUM\t\t\t4\n#define ITEM_HEIGHT\t\t\t\t45\n\nclass c_list_box : public c_wnd\n{\npublic:\n\tvoid set_on_change(WND_CALLBACK on_change) { this->on_change = on_change; }\n\tshort get_item_count() { return m_item_total; }\n\n\tint add_item(char* str)\n\t{\n\t\tif (m_item_total >= MAX_ITEM_NUM)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn -1;\n\t\t}\n\t\tm_item_array[m_item_total++] = str;\n\t\tupdate_list_size();\n\t\treturn 0;\n\t}\n\tvoid clear_item()\n\t{\n\t\tm_selected_item = m_item_total = 0;\n\t\tmemset(m_item_array, 0, sizeof(m_item_array));\n\t\tupdate_list_size();\n\t}\n\tvoid  select_item(short index)\n\t{\n\t\tif (index < 0 || index >= m_item_total)\n\t\t{\n\t\t\tASSERT(false);\n\t\t}\n\t\tm_selected_item = index;\n\t}\n\t\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\tmemset(m_item_array, 0, sizeof(m_item_array));\n\t\tm_item_total = 0;\n\t\tm_selected_item = 0;\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t}\n\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\n\t\tswitch (m_status)\n\t\t{\n\t\tcase STATUS_NORMAL:\n\t\t\tif (m_z_order > m_parent->get_z_order())\n\t\t\t{\n\t\t\t\tm_surface->activate_layer(c_rect(), m_z_order);//inactivate the layer of list by empty rect.\n\t\t\t\tm_z_order = m_parent->get_z_order();\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\t\t}\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tcase STATUS_FOCUSED:\n\t\t\tif (m_z_order > m_parent->get_z_order())\n\t\t\t{\n\t\t\t\tm_surface->activate_layer(c_rect(), m_z_order);//inactivate the layer of list by empty rect.\n\t\t\t\tm_z_order = m_parent->get_z_order();\n\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);\n\t\t\t}\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\tbreak;\n\t\tcase STATUS_PUSHED:\n\t\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);\n\t\t\tm_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);\n\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, GL_RGB(2, 124, 165), GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t//draw list\n\t\t\tif (m_item_total > 0)\n\t\t\t{\n\t\t\t\tif (m_z_order == m_parent->get_z_order())\n\t\t\t\t{\n\t\t\t\t\tm_z_order++;\n\t\t\t\t\tm_surface->activate_layer(m_list_screen_rect, m_z_order);\n\t\t\t\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY);\n\t\t\t\t}\n\t\t\t\tshow_list();\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tASSERT(false);\n\t\t}\n\t}\n\tvirtual void on_focus()\n\t{\n\t\tm_status = STATUS_FOCUSED;\n\t\ton_paint();\n\t}\n\tvirtual void on_kill_focus()\n\t{\n\t\tm_status = STATUS_NORMAL;\n\t\ton_paint();\n\t}\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tswitch (key)\n\t\t{\n\t\tcase NAV_ENTER:\n\t\t\tif (STATUS_PUSHED == m_status)\n\t\t\t{\n\t\t\t\tif(on_change)\n\t\t\t\t{\n\t\t\t\t\t(m_parent->*(on_change))(m_id, m_selected_item);\n\t\t\t\t}\n\t\t\t}\n\t\t\ton_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN);\n\t\t\ton_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP);\n\t\t\treturn;\n\t\tcase NAV_BACKWARD:\n\t\t\tif (m_status != STATUS_PUSHED)\n\t\t\t{\n\t\t\t\treturn c_wnd::on_navigate(key);\n\t\t\t}\n\t\t\tm_selected_item = (m_selected_item > 0) ? (m_selected_item - 1) : m_selected_item;\n\t\t\treturn show_list();\n\t\tcase NAV_FORWARD:\n\t\t\tif (m_status != STATUS_PUSHED)\n\t\t\t{\n\t\t\t\treturn c_wnd::on_navigate(key);\n\t\t\t}\n\t\t\tm_selected_item = (m_selected_item < (m_item_total - 1)) ? (m_selected_item + 1) : m_selected_item;\n\t\t\treturn show_list();\n\t\t}\n\t}\n\tvirtual void on_touch(int x, int y, TOUCH_ACTION action)\n\t{\n\t\t(action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y);\n\t}\n\t\nprivate:\n\tvoid update_list_size()\n\t{\n\t\tm_list_wnd_rect = m_wnd_rect;\n\t\tm_list_wnd_rect.m_top = m_wnd_rect.m_bottom + 1;\n\t\tm_list_wnd_rect.m_bottom = m_list_wnd_rect.m_top + m_item_total * ITEM_HEIGHT;\n\n\t\tget_screen_rect(m_list_screen_rect);\n\t\tm_list_screen_rect.m_top = m_list_screen_rect.m_bottom + 1;\n\t\tm_list_screen_rect.m_bottom = m_list_screen_rect.m_top + m_item_total * ITEM_HEIGHT;\n\t}\n\tvoid show_list()\n\t{\n\t\t//draw all items\n\t\tc_rect tmp_rect;\n\t\tfor (int i = 0; i < m_item_total; i++)\n\t\t{\n\t\t\ttmp_rect.m_left = m_list_screen_rect.m_left;\n\t\t\ttmp_rect.m_right = m_list_screen_rect.m_right;\n\t\t\ttmp_rect.m_top = m_list_screen_rect.m_top + i * ITEM_HEIGHT;\n\t\t\ttmp_rect.m_bottom = tmp_rect.m_top + ITEM_HEIGHT;\n\n\t\t\tif (m_selected_item == i)\n\t\t\t{\n\t\t\t\tm_surface->fill_rect(tmp_rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_surface->fill_rect(tmp_rect, GL_RGB(17, 17, 17), m_z_order);\n\t\t\t\tc_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font, m_font_color, GL_RGB(17, 17, 17), ALIGN_HCENTER | ALIGN_VCENTER);\n\t\t\t}\n\t\t}\n\t}\n\tvoid on_touch_down(int x, int y)\n\t{\n\t\tif (m_wnd_rect.pt_in_rect(x, y))\n\t\t{//click base\n\t\t\tif (STATUS_NORMAL == m_status)\n\t\t\t{\n\t\t\t\tm_parent->set_child_focus(this);\n\t\t\t}\n\t\t}\n\t\telse if (m_list_wnd_rect.pt_in_rect(x, y))\n\t\t{//click extend list\n\t\t\tc_wnd::on_touch(x, y, TOUCH_DOWN);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (STATUS_PUSHED == m_status)\n\t\t\t{\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\ton_paint();\n\t\t\t\tif(on_change)\n\t\t\t\t{\n\t\t\t\t\t(m_parent->*(on_change))(m_id, m_selected_item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvoid on_touch_up(int x, int y)\n\t{\n\t\tif (STATUS_FOCUSED == m_status)\n\t\t{\n\t\t\tm_status = STATUS_PUSHED;\n\t\t\ton_paint();\n\t\t}\n\t\telse if (STATUS_PUSHED == m_status)\n\t\t{\n\t\t\tif (m_wnd_rect.pt_in_rect(x, y))\n\t\t\t{//click base\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\ton_paint();\n\t\t\t}\n\t\t\telse if (m_list_wnd_rect.pt_in_rect(x, y))\n\t\t\t{//click extend list\n\t\t\t\tm_status = STATUS_FOCUSED;\n\t\t\t\tselect_item((y - m_list_wnd_rect.m_top) / ITEM_HEIGHT);\n\t\t\t\ton_paint();\n\t\t\t\tif(on_change)\n\t\t\t\t{\n\t\t\t\t\t(m_parent->*(on_change))(m_id, m_selected_item);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tc_wnd::on_touch(x, y, TOUCH_UP);\n\t\t\t}\n\t\t}\n\t}\n\n\tshort\t\t\tm_selected_item;\n\tshort\t\t\tm_item_total;\n\tchar*\t\t\tm_item_array[MAX_ITEM_NUM];\n\tc_rect\t\t\tm_list_wnd_rect;\t//rect relative to parent wnd.\n\tc_rect\t\t\tm_list_screen_rect;\t//rect relative to physical screen(frame buffer)\n\tWND_CALLBACK \ton_change;\n};\n"
  },
  {
    "path": "src/widgets/slide_group.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/display.h\"\n#include \"../core/wnd.h\"\n#include \"../widgets/dialog.h\"\n#include <stdlib.h>\n\n#define MAX_PAGES\t5\nclass c_gesture;\nclass c_slide_group : public c_wnd {\npublic:\n\tinline c_slide_group();\n\n\tint set_active_slide(int index, bool is_redraw = true)\n\t{\n\t\tif (index >= MAX_PAGES || index < 0)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tif (0 == m_slides[index])\n\t\t{\n\t\t\treturn -2;\n\t\t}\n\t\tm_active_slide_index = index;\n\n\t\tfor (int i = 0; i < MAX_PAGES; i++)\n\t\t{\n\t\t\tif (m_slides[i] == 0)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (i == index)\n\t\t\t{\n\t\t\t\tm_slides[i]->get_surface()->set_active(true);\n\t\t\t\tadd_child_2_tail(m_slides[i]);\n\t\t\t\tif (is_redraw)\n\t\t\t\t{\n\t\t\t\t\tc_rect rc;\n\t\t\t\t\tget_screen_rect(rc);\n\t\t\t\t\tm_slides[i]->get_surface()->flush_screen(rc.m_left, rc.m_top, rc.m_right, rc.m_bottom);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_slides[i]->get_surface()->set_active(false);\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tc_wnd* get_slide(int index){return m_slides[index];}\n\tc_wnd* get_active_slide(){return m_slides[m_active_slide_index];}\n\tint get_active_slide_index(){return m_active_slide_index;}\n\tint 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)\n\t{\n\t\tif (0 == slide)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\n\t\tc_surface* old_surface = get_surface();\n\t\tc_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder);\n\t\tnew_surface->set_active(false);\n\t\tset_surface(new_surface);\n\t\tslide->connect(this, resource_id, 0, x, y, width, height, p_child_tree);\n\t\tset_surface(old_surface);\n\n\t\tint i = 0;\n\t\twhile (i < MAX_PAGES)\n\t\t{\n\t\t\tif (m_slides[i] == slide)\n\t\t\t{//slide has lived\n\t\t\t\tASSERT(false);\n\t\t\t\treturn -2;\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\n\t\t//new slide\n\t\ti = 0;\n\t\twhile (i < MAX_PAGES)\n\t\t{\n\t\t\tif (m_slides[i] == 0)\n\t\t\t{\n\t\t\t\tm_slides[i] = slide;\n\t\t\t\tslide->show_window();\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\n\t\t//no more slide can be add\n\t\tASSERT(false);\n\t\treturn -3;\n\t}\n\tvoid disabel_all_slide()\n\t{\n\t\tfor (int i = 0; i < MAX_PAGES; i++)\n\t\t{\n\t\t\tif (m_slides[i])\n\t\t\t{\n\t\t\t\tm_slides[i]->get_surface()->set_active(false);\n\t\t\t}\n\t\t}\n\t}\n\tinline virtual void on_touch(int x, int y, TOUCH_ACTION action);\n\tvirtual void on_navigate(NAVIGATION_KEY key)\n\t{\n\t\tif (m_slides[m_active_slide_index])\n\t\t{\n\t\t\tm_slides[m_active_slide_index]->on_navigate(key);\n\t\t}\n\t}\nprotected:\n\tc_wnd* m_slides[MAX_PAGES];\n\tint m_active_slide_index;\n\tc_gesture* m_gesture;\n};\n\n//#define SWIPE_STEP\t\t\t300//for arm\n#define SWIPE_STEP\t\t\t10//for PC & ANDROID\n#define MOVE_THRESHOLD\t\t10\n\ntypedef enum {\n\tTOUCH_MOVE,\n\tTOUCH_IDLE\n}TOUCH_STATE;\n\nclass c_slide_group;\nclass c_gesture {\npublic:\n\tc_gesture(c_slide_group* group)\n\t{\n\t\tm_slide_group = group;\n\t\tm_state = TOUCH_IDLE;\n\t\tm_down_x = m_down_y = m_move_x = m_move_y = 0;\n\t}\n\tbool handle_swipe(int x, int y, TOUCH_ACTION action)\n\t{\n\t\tif (action == TOUCH_DOWN)//MOUSE_LBUTTONDOWN\n\t\t{\n\t\t\tif (m_state == TOUCH_IDLE)\n\t\t\t{\n\t\t\t\tm_state = TOUCH_MOVE;\n\t\t\t\tm_move_x = m_down_x = x;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse//TOUCH_MOVE\n\t\t\t{\n\t\t\t\treturn on_move(x);\n\t\t\t}\n\t\t}\n\t\telse if (action == TOUCH_UP)//MOUSE_LBUTTONUP\n\t\t{\n\t\t\tif (m_state == TOUCH_MOVE)\n\t\t\t{\n\t\t\t\tm_state = TOUCH_IDLE;\n\t\t\t\treturn on_swipe(x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t\t//ASSERT(false);\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\nprivate:\n\tbool on_move(int x)\n\t{\n\t\tif (m_slide_group == 0)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif (abs(x - m_move_x) < MOVE_THRESHOLD)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tm_slide_group->disabel_all_slide();\n\t\tm_move_x = x;\n\t\tif ((m_move_x - m_down_x) > 0)\n\t\t{\n\t\t\tmove_right();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmove_left();\n\t\t}\n\t\treturn false;\n\t}\n\tbool on_swipe(int x)\n\t{\n\t\tif (m_slide_group == 0)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif ((m_down_x == m_move_x) && (abs(x - m_down_x) < MOVE_THRESHOLD))\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tm_slide_group->disabel_all_slide();\n\t\tint page = -1;\n\t\tm_move_x = x;\n\t\tif ((m_move_x - m_down_x) > 0)\n\t\t{\n\t\t\tpage = swipe_right();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tpage = swipe_left();\n\t\t}\n\t\tif (page >= 0)\n\t\t{\n\t\t\tm_slide_group->set_active_slide(page);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_slide_group->set_active_slide(m_slide_group->get_active_slide_index(), false);\n\t\t}\n\t\treturn false;\n\t}\n\tint swipe_left()\n\t{\n\t\tif (m_slide_group == 0)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tint index = m_slide_group->get_active_slide_index();\n\t\tif ((index + 1) >= MAX_PAGES ||\n\t\t\tm_slide_group->get_slide(index + 1) == 0 ||\n\t\t\tm_slide_group->get_slide(index) == 0)\n\t\t{\n\t\t\treturn -2;\n\t\t}\n\t\tc_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface();\n\t\tc_surface * s2 = m_slide_group->get_slide(index)->get_surface();\n\t\tif (s1->get_display() != s2->get_display())\n\t\t{\n\t\t\treturn -3;\n\t\t}\n\n\t\tint step = m_down_x - m_move_x;\n\t\tc_rect rc;\n\t\tm_slide_group->get_screen_rect(rc);\n\t\twhile (step < rc.width())\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step);\n\t\t\tstep += SWIPE_STEP;\n\t\t}\n\t\tif (step != rc.width())\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, rc.width());\n\t\t}\n\t\treturn (index + 1);\n\t}\n\n\tint swipe_right()\n\t{\n\t\tif (m_slide_group == 0)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tint index = m_slide_group->get_active_slide_index();\n\t\tif (index <= 0 ||\n\t\t\tm_slide_group->get_slide(index - 1) == 0 ||\n\t\t\tm_slide_group->get_slide(index) == 0)\n\t\t{\n\t\t\treturn -2;\n\t\t}\n\t\tc_surface* s1 = m_slide_group->get_slide(index - 1)->get_surface();\n\t\tc_surface * s2 = m_slide_group->get_slide(index)->get_surface();\n\t\tif (s1->get_display() != s2->get_display())\n\t\t{\n\t\t\treturn -3;\n\t\t}\n\n\t\tc_rect rc;\n\t\tm_slide_group->get_screen_rect(rc);\n\t\tint step = rc.width() - (m_move_x - m_down_x);\n\t\twhile (step > 0)\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step);\n\t\t\tstep -= SWIPE_STEP;\n\t\t}\n\t\tif (step != 0)\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, 0);\n\t\t}\n\t\treturn (index - 1);\n\t}\n\tvoid move_left()\n\t{\n\t\tint index = m_slide_group->get_active_slide_index();\n\t\tif ((index + 1) >= MAX_PAGES ||\n\t\t\tm_slide_group->get_slide(index + 1) == 0 ||\n\t\t\tm_slide_group->get_slide(index) == 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tc_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface();\n\t\tc_surface * s2 = m_slide_group->get_slide(index)->get_surface();\n\t\tc_rect rc;\n\t\tm_slide_group->get_screen_rect(rc);\n\t\tif (s1->get_display() == s2->get_display())\n\t\t{\n\t\t\ts1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (m_down_x - m_move_x));\n\t\t}\n\t}\n\tvoid move_right()\n\t{\n\t\tint index = m_slide_group->get_active_slide_index();\n\t\tif (index <= 0 ||\n\t\t\tm_slide_group->get_slide(index - 1) == 0 ||\n\t\t\tm_slide_group->get_slide(index) == 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tc_surface* s1 = m_slide_group->get_slide(index - 1)->get_surface();\n\t\tc_surface * s2 = m_slide_group->get_slide(index)->get_surface();\n\t\tc_rect rc;\n\t\tm_slide_group->get_screen_rect(rc);\n\t\tif (s1->get_display() == s2->get_display())\n\t\t{\n\t\t\ts1->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)));\n\t\t}\n\t}\n\n\tint m_down_x;\n\tint m_down_y;\n\tint m_move_x;\n\tint m_move_y;\n\tTOUCH_STATE m_state;\n\tc_slide_group* m_slide_group;\n};\n\ninline c_slide_group::c_slide_group()\n{\n\tm_gesture = new c_gesture(this);\n\tfor (int i = 0; i < MAX_PAGES; i++)\n\t{\n\t\tm_slides[i] = 0;\n\t}\n\tm_active_slide_index = 0;\n}\n\ninline void c_slide_group::on_touch(int x, int y, TOUCH_ACTION action)\n{\n\tx -= m_wnd_rect.m_left;\n\ty -= m_wnd_rect.m_top;\n\n\tif (m_gesture->handle_swipe(x, y, action))\n\t{\n\t\tif (m_slides[m_active_slide_index])\n\t\t{\n\t\t\tm_slides[m_active_slide_index]->on_touch(x, y, action);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/widgets/spinbox.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/wnd.h\"\n#include \"../core/resource.h\"\n#include \"../core/word.h\"\n#include \"../core/display.h\"\n#include \"../core/theme.h\"\n#include \"../widgets/button.h\"\n\n#define ID_BT_ARROW_UP      \t0x1111\n#define ID_BT_ARROW_DOWN    \t0x2222\n\nclass c_spin_box;\nclass c_spin_button : public c_button\n{\n\tfriend class c_spin_box;\n\tinline virtual void on_touch(int x, int y, TOUCH_ACTION action);\n\tc_spin_box* m_spin_box;\n};\n\nclass c_spin_box : public c_wnd\n{\n\tfriend class c_spin_button;\npublic:\n\tshort get_value() { return m_value; }\n\tvoid set_value(unsigned short value) { m_value = m_cur_value = value; }\n\tvoid set_max_min(short max, short min) { m_max = max; m_min = min; }\n\tvoid set_step(short step) { m_step = step; }\n\tshort get_min() { return m_min; }\n\tshort get_max() { return m_max; }\n\tshort get_step() { return m_step; }\n\tvoid set_value_digit(short digit) { m_digit = digit; }\n\tshort get_value_digit() { return m_digit; }\n\tvoid set_on_change(WND_CALLBACK on_change) { this->on_change = on_change; }\nprotected:\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\trect.m_right = rect.m_left + (rect.width() * 2 / 3);\n\n\t\tm_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);\n\t\tc_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);\n\t}\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE);\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t\tm_max = 6;\n\t\tm_min = 1;\n\t\tm_digit = 0;\n\t\tm_step = 1;\n\n\t\t//link arrow button position.\n\t\tc_rect rect;\n\t\tget_wnd_rect(rect);\n\t\tm_bt_down.m_spin_box = m_bt_up.m_spin_box = this;\n\t\tm_bt_up.connect(m_parent, ID_BT_ARROW_UP, \"+\", (rect.m_left + rect.width() * 2 / 3), rect.m_top, (rect.width() / 3), (rect.height() / 2));\n\t\tm_bt_down.connect(m_parent, ID_BT_ARROW_DOWN, \"-\", (rect.m_left + rect.width() * 2 / 3), (rect.m_top + rect.height() / 2), (rect.width() / 3), (rect.height() / 2));\n\t}\n\tvoid on_arrow_up_bt_click()\n\t{\n\t\tif (m_cur_value + m_step > m_max)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tm_cur_value += m_step;\n\t\tif(on_change)\n\t\t{\n\t\t\t(m_parent->*(on_change))(m_id, m_cur_value);\n\t\t}\n\t\ton_paint();\n\t}\n\tvoid on_arrow_down_bt_click()\n\t{\n\t\tif (m_cur_value - m_step < m_min)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tm_cur_value -= m_step;\n\t\tif(on_change)\n\t\t{\n\t\t\t(m_parent->*(on_change))(m_id, m_cur_value);\n\t\t}\n\t\ton_paint();\n\t}\n\n\tshort\t\t\tm_cur_value;\n\tshort\t\t\tm_value;\n\tshort\t\t\tm_step;\n\tshort\t\t\tm_max;\n\tshort\t\t\tm_min;\n\tshort\t\t\tm_digit;\n\tc_spin_button  \tm_bt_up;\n\tc_spin_button  \tm_bt_down;\n\tWND_CALLBACK \ton_change;\n};\n\ninline void c_spin_button::on_touch(int x, int y, TOUCH_ACTION action)\n{\n\tif (action == TOUCH_UP)\n\t{\n\t\t(m_id == ID_BT_ARROW_UP) ? m_spin_box->on_arrow_up_bt_click() : m_spin_box->on_arrow_down_bt_click();\n\t}\n\tc_button::on_touch(x, y, action);\n}\n"
  },
  {
    "path": "src/widgets/table.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/resource.h\"\n#include \"../core/word.h\"\n#include \"../core/display.h\"\n#include \"../core/theme.h\"\n#include \"../core/wnd.h\"\n\n#define  MAX_COL_NUM  30\n#define  MAX_ROW_NUM  30\n\nclass c_table: public c_wnd\n{\npublic:\n\tvoid set_sheet_align(unsigned int align_type){ m_align_type = align_type;}\n\tvoid set_row_num(unsigned int row_num){ m_row_num = row_num;}\n\tvoid set_col_num(unsigned int col_num){ m_col_num = col_num;}\n\tvoid set_row_height(unsigned int height)\n\t{\n\t\tfor (unsigned int i = 0; i < m_row_num; i++)\n\t\t{\n\t\t\tm_row_height[i] = height;\n\t\t}\n\t}\n\tvoid set_col_width(unsigned int width)\n\t{\n\t\tfor (unsigned int i = 0; i < m_col_num; i++)\n\t\t{\n\t\t\tm_col_width[i] = width;\n\t\t}\n\t}\n\tint set_row_height(unsigned int index, unsigned int height)\n\t{\n\t\tif (m_row_num > index)\n\t\t{\n\t\t\tm_row_height[index] = height;\n\t\t\treturn index;\n\t\t}\n\t\treturn -1;\n\t}\n\tint set_col_width(unsigned int index, unsigned int width)\n\t{\n\t\tif (m_col_num > index)\n\t\t{\n\t\t\tm_col_width[index] = width;\n\t\t\treturn index;\n\t\t}\n\t\treturn -1;\n\t}\n\tvoid set_item(int row, int col, char* str, unsigned int color)\n\t{\n\t\tdraw_item(row, col, str, color);\n\t}\n\n\tunsigned int get_row_num(){ return m_row_num;}\n\tunsigned int get_col_num(){ return m_col_num;}\n\tc_rect get_item_rect(int row, int col)\n\t{\n\t\tstatic c_rect rect;\n\t\tif (row >= MAX_ROW_NUM || col >= MAX_COL_NUM)\n\t\t{\n\t\t\treturn rect;\n\t\t}\n\n\t\tunsigned int width = 0;\n\t\tunsigned int height = 0;\n\t\tfor (int i = 0; i < col; i++)\n\t\t{\n\t\t\twidth += m_col_width[i];\n\t\t}\n\t\tfor (int j = 0; j < row; j++)\n\t\t{\n\t\t\theight += m_row_height[j];\n\t\t}\n\n\t\tc_rect wRect;\n\t\tget_screen_rect(wRect);\n\n\t\trect.m_left = wRect.m_left + width;\n\t\trect.m_right = rect.m_left + m_col_width[col];\n\t\tif (rect.m_right > wRect.m_right)\n\t\t{\n\t\t\trect.m_right = wRect.m_right;\n\t\t}\n\t\trect.m_top = wRect.m_top + height;\n\t\trect.m_bottom = rect.m_top + m_row_height[row];\n\t\tif (rect.m_bottom > wRect.m_bottom)\n\t\t{\n\t\t\trect.m_bottom = wRect.m_bottom;\n\t\t}\n\t\treturn rect;\n\t}\nprotected:\n\tvirtual void pre_create_wnd()\n\t{\n\t\tm_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE);\n\t\tm_font = c_theme::get_font(FONT_DEFAULT);\n\t\tm_font_color = c_theme::get_color(COLOR_WND_FONT);\n\t}\n\tvoid draw_item(int row, int col, const char* str, unsigned int color)\n\t{\n\t\tc_rect rect = get_item_rect(row, col);\n\t\tm_surface->fill_rect(rect.m_left + 1, rect.m_top + 1, rect.m_right - 1, rect.m_bottom - 1, color, m_z_order);\n\t\tc_word::draw_string_in_rect(m_surface, m_z_order, str, rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_align_type);\n\t}\n\n\tunsigned int m_align_type;\t\n\tunsigned int m_row_num;\n\tunsigned int m_col_num;\n\tunsigned int m_row_height[MAX_ROW_NUM];\n\tunsigned int m_col_width[MAX_COL_NUM];\n};\n"
  },
  {
    "path": "src/widgets/wave_buffer.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include <string.h>\n#include <stdio.h>\n\n#define WAVE_BUFFER_LEN\t1024\n#define WAVE_READ_CACHE_LEN\t8\n#define BUFFER_EMPTY\t-1111\n#define BUFFER_FULL\t\t-2222;\n\nclass c_wave_buffer\n{\npublic:\n\tc_wave_buffer()\n\t{\n\t\tm_head = m_tail = m_min_old = m_max_old =\n\t\t\tm_min_older = m_max_older = m_last_data = m_read_cache_sum = m_refresh_sequence = 0;\n\t\tmemset(m_wave_buf, 0, sizeof(m_wave_buf));\n\t\tmemset(m_read_cache_min, 0, sizeof(m_read_cache_min));\n\t\tmemset(m_read_cache_mid, 0, sizeof(m_read_cache_mid));\n\t\tmemset(m_read_cache_max, 0, sizeof(m_read_cache_max));\n\t}\n\tint write_wave_data(short data)\n\t{\n\t\tif ((m_tail + 1) % WAVE_BUFFER_LEN == m_head)\n\t\t{//full\n\t\t\t//log_out(\"wave buf full\\n\");\n\t\t\treturn BUFFER_FULL;\n\t\t}\n\t\tm_wave_buf[m_tail] = data;\n\t\tm_tail = (m_tail + 1) % WAVE_BUFFER_LEN;\n\t\treturn 1;\n\t}\n\tint read_wave_data_by_frame(short &max, short &min, short frame_len, unsigned int sequence, short offset)\n\t{\n\t\tif (m_refresh_sequence != sequence)\n\t\t{\n\t\t\tm_refresh_sequence = sequence;\n\t\t\tm_read_cache_sum = 0;\n\t\t}\n\t\telse if (offset < m_read_cache_sum)//(m_refresh_sequence == sequence && offset < m_fb_sum)\n\t\t{\n\t\t\tmax = m_read_cache_max[offset];\n\t\t\tmin = m_read_cache_min[offset];\n\t\t\treturn m_read_cache_mid[offset];\n\t\t}\n\n\t\tm_read_cache_sum++;\n\t\tASSERT(m_read_cache_sum <= WAVE_READ_CACHE_LEN);\n\t\tint i, data;\n\t\tint tmp_min = m_last_data;\n\t\tint tmp_max = m_last_data;\n\t\tint mid = (m_min_old + m_max_old) >> 1;\n\n\t\ti = 0;\n\t\twhile (i++ < frame_len)\n\t\t{\n\t\t\tdata = read_data();\n\t\t\tif (BUFFER_EMPTY == data)\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tm_last_data = data;\n\n\t\t\tif (data < tmp_min) { tmp_min = data; }\n\t\t\tif (data > tmp_max) { tmp_max = data; }\n\t\t}\n\n\t\tmin = m_read_cache_min[offset] = MIN(m_min_old, MIN(tmp_min, m_min_older));\n\t\tmax = m_read_cache_max[offset] = MAX(m_max_old, MAX(tmp_max, m_max_older));\n\n\t\tm_min_older = m_min_old;\n\t\tm_max_older = m_max_old;\n\t\tm_min_old = tmp_min;\n\t\tm_max_old = tmp_max;\n\t\treturn (m_read_cache_mid[offset] = mid);\n\t}\n\tvoid reset()\n\t{\n\t\tm_head = m_tail;\n\t}\n\n\tvoid clear_data()\n\t{\n\t\tm_head = m_tail = 0;\n\t\tmemset(m_wave_buf, 0, sizeof(m_wave_buf));\n\t}\n\tshort get_cnt()\n\t{\n\t\treturn (m_tail >= m_head) ? (m_tail - m_head) : (m_tail - m_head + WAVE_BUFFER_LEN);\n\t}\nprivate:\n\tint read_data()\n\t{\n\t\tif (m_head == m_tail)\n\t\t{//empty\n\t\t\t//log_out(\"wave buf empty\\n\");\n\t\t\treturn BUFFER_EMPTY;\n\t\t}\n\t\tint ret = m_wave_buf[m_head];\n\t\tm_head = (m_head + 1) % WAVE_BUFFER_LEN;\n\t\treturn ret;\n\t}\n\tshort m_wave_buf[WAVE_BUFFER_LEN];\n\tshort m_head;\n\tshort m_tail;\n\n\tint m_min_old;\n\tint m_max_old;\n\tint m_min_older;\n\tint m_max_older;\n\tint m_last_data;\n\n\tshort \tm_read_cache_min[WAVE_READ_CACHE_LEN];\n\tshort \tm_read_cache_mid[WAVE_READ_CACHE_LEN];\n\tshort \tm_read_cache_max[WAVE_READ_CACHE_LEN];\n\tshort\tm_read_cache_sum;\n\tunsigned int m_refresh_sequence;\n};\n"
  },
  {
    "path": "src/widgets/wave_ctrl.h",
    "content": "#pragma once\n\n#include \"../core/api.h\"\n#include \"../core/wnd.h\"\n#include \"../core/display.h\"\n#include \"../core/resource.h\"\n#include \"../core/word.h\"\n#include \"../widgets/wave_buffer.h\"\n#include <stdlib.h>\n#include <string.h>\n\n#define CORRECT(x, high_limit, low_limit)\t{\\\n\tx = (x > high_limit) ? high_limit : x;\\\n\tx = (x < low_limit) ? low_limit : x;\\\n}while(0)\n\n#define WAVE_CURSOR_WIDTH\t\t8\n#define\tWAVE_LINE_WIDTH\t\t\t1\n#define\tWAVE_MARGIN\t\t\t\t5\n\ntypedef enum\n{\n\tFILL_MODE,\n\tSCAN_MODE\n}E_WAVE_DRAW_MODE;\n\nclass c_wave_buffer;\nclass c_wave_ctrl : public c_wnd\n{\npublic:\n\tc_wave_ctrl()\n\t{\n\t\tm_wave = 0;\n\t\tm_bg_fb = 0;\n\t\tm_wave_name_font = m_wave_unit_font = 0;\n\t\tm_wave_name = m_wave_unit = 0;\n\t\tm_max_data = 500;\n\t\tm_min_data = 0;\n\t\tm_wave_speed = 1;\n\t\tm_wave_data_rate = 0;\n\t\tm_wave_refresh_rate = 1000;\n\t\tm_frame_len_map_index = 0;\n\n\t\tm_wave_name_color = m_wave_unit_color = m_wave_color = GL_RGB(255, 0, 0);\n\t\tm_back_color = GL_RGB(0, 0, 0);\n\t}\n\tvirtual void on_init_children()//should be pre_create\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\n\t\tm_wave_left = rect.m_left + WAVE_MARGIN;\n\t\tm_wave_right = rect.m_right - WAVE_MARGIN;\n\t\tm_wave_top = rect.m_top + WAVE_MARGIN;\n\t\tm_wave_bottom = rect.m_bottom - WAVE_MARGIN;\n\t\tm_wave_cursor = m_wave_left;\n\n\t\tm_bg_fb = (unsigned int*)calloc(rect.width() * rect.height(), 4);\n\t}\n\tvirtual void on_paint()\n\t{\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tm_surface->fill_rect(rect, m_back_color, m_z_order);\n\n\t\t//show name\n\t\tc_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));\n\t\t//show unit\n\t\tc_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));\n\n\t\tsave_background();\n\t}\n\tvoid set_wave_name(char* wave_name){ m_wave_name = wave_name;}\n\tvoid set_wave_unit(char* wave_unit){ m_wave_unit = wave_unit;}\n\n\tvoid set_wave_name_font(const LATTICE_FONT_INFO* wave_name_font_type){ m_wave_name_font = wave_name_font_type;}\n\tvoid set_wave_unit_font(const LATTICE_FONT_INFO* wave_unit_font_type){ m_wave_unit_font = wave_unit_font_type;}\n\n\tvoid set_wave_name_color(unsigned int wave_name_color){ m_wave_name_color = wave_name_color;}\n\tvoid set_wave_unit_color(unsigned int wave_unit_color){ m_wave_unit_color = wave_unit_color;}\n\tvoid set_wave_color(unsigned int color){ m_wave_color = color;}\n\tvoid set_wave_in_out_rate(unsigned int data_rate, unsigned int refresh_rate)\n\t{\n\t\tm_wave_data_rate = data_rate;\n\t\tm_wave_refresh_rate = refresh_rate;\n\t\tint read_times_per_second = m_wave_speed * 1000 / m_wave_refresh_rate;\n\n\t\tmemset(m_frame_len_map, 0, sizeof(m_frame_len_map));\n\t\tfor (unsigned int i = 1; i < sizeof(m_frame_len_map) + 1; i++)\n\t\t{\n\t\t\tm_frame_len_map[i - 1] = data_rate * i / read_times_per_second - data_rate * (i - 1) / read_times_per_second;\n\t\t}\n\t\tm_frame_len_map_index = 0;\n\t}\n\tvoid set_wave_speed(unsigned int speed)\n\t{\n\t\tm_wave_speed = speed;\n\t\tset_wave_in_out_rate(m_wave_data_rate, m_wave_refresh_rate);\n\t}\n\tvoid set_max_min(short max_data, short min_data)\n\t{\n\t\tm_max_data = max_data;\n\t\tm_min_data = min_data;\n\t}\n\tvoid set_wave(c_wave_buffer* wave){m_wave = wave;}\n\tc_wave_buffer* get_wave(){return m_wave;}\n\tvoid clear_data()\n\t{\n\t\tif (m_wave == 0)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn;\n\t\t}\n\t\tm_wave->clear_data();\n\t}\n\tbool is_data_enough()\n\t{\n\t\tif (m_wave == 0)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn false;\n\t\t}\n\t\treturn (m_wave->get_cnt() - m_frame_len_map[m_frame_len_map_index] * m_wave_speed);\n\t}\n\tvoid refresh_wave(unsigned char frame)\n\t{\n\t\tif (m_wave == 0)\n\t\t{\n\t\t\tASSERT(false);\n\t\t\treturn;\n\t\t}\n\n\t\tshort max, min, mid;\n\t\tfor (short offset = 0; offset < m_wave_speed; offset++)\n\t\t{\n\t\t\t//get wave value\n\t\t\tmid = m_wave->read_wave_data_by_frame(max, min,\n\t\t\t\tm_frame_len_map[m_frame_len_map_index++],\n\t\t\t\tframe, offset);\n\t\t\tm_frame_len_map_index %= sizeof(m_frame_len_map);\n\n\t\t\t//map to wave ctrl\n\t\t\tint y_min, y_max;\n\t\t\tif (m_max_data == m_min_data)\n\t\t\t{\n\t\t\t\tASSERT(false);\n\t\t\t}\n\t\t\ty_max = m_wave_bottom + WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top) * (min - m_min_data) / (m_max_data - m_min_data);\n\t\t\ty_min = m_wave_bottom - WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top) * (max - m_min_data) / (m_max_data - m_min_data);\n\t\t\tmid = m_wave_bottom - (m_wave_bottom - m_wave_top) * (mid - m_min_data) / (m_max_data - m_min_data);\n\n\t\t\tCORRECT(y_min, m_wave_bottom, m_wave_top);\n\t\t\tCORRECT(y_max, m_wave_bottom, m_wave_top);\n\t\t\tCORRECT(mid, m_wave_bottom, m_wave_top);\n\n\t\t\tif (m_wave_cursor > m_wave_right)\n\t\t\t{\n\t\t\t\tm_wave_cursor = m_wave_left;\n\t\t\t}\n\t\t\tdraw_smooth_vline(y_min, y_max, mid, m_wave_color);\n\t\t\trestore_background();\n\t\t\tm_wave_cursor++;\n\t\t}\n\t}\n\tvoid clear_wave()\n\t{\n\t\tm_surface->fill_rect(m_wave_left, m_wave_top, m_wave_right, m_wave_bottom, m_back_color, m_z_order);\n\t\tm_wave_cursor = m_wave_left;\n\t}\t\nprotected:\n\tvoid draw_smooth_vline(int y_min, int y_max, int mid, unsigned int rgb)\n\t{\n\t\tint dy = y_max - y_min;\n\t\tshort r = GL_RGB_R(rgb);\n\t\tshort g = GL_RGB_G(rgb);\n\t\tshort b = GL_RGB_B(rgb);\n\t\tint  index = (dy >> 1) + 2;\n\t\tint  y;\n\n\t\tm_surface->draw_pixel(m_wave_cursor, mid, rgb, m_z_order);\n\n\t\tif (dy < 1)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tunsigned char cur_r, cur_g, cur_b;\n\t\tunsigned int cur_rgb;\n\t\tfor (int i = 1; i <= (dy >> 1) + 1; ++i)\n\t\t{\n\t\t\tif ((mid + i) <= y_max)\n\t\t\t{\n\t\t\t\ty = mid + i;\n\t\t\t\tcur_r = r * (index - i) / index;\n\t\t\t\tcur_g = g * (index - i) / index;\n\t\t\t\tcur_b = b * (index - i) / index;\n\t\t\t\tcur_rgb = GL_RGB(cur_r, cur_g, cur_b);\n\t\t\t\tm_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order);\n\t\t\t}\n\t\t\tif ((mid - i) >= y_min)\n\t\t\t{\n\t\t\t\ty = mid - i;\n\t\t\t\tcur_r = r * (index - i) / index;\n\t\t\t\tcur_g = g * (index - i) / index;\n\t\t\t\tcur_b = b * (index - i) / index;\n\t\t\t\tcur_rgb = GL_RGB(cur_r, cur_g, cur_b);\n\t\t\t\tm_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order);\n\t\t\t}\n\t\t}\n\t}\n\tvoid restore_background()\n\t{\n\t\tint  x = m_wave_cursor + WAVE_CURSOR_WIDTH;\n\t\tif (x > m_wave_right)\n\t\t{\n\t\t\tx -= (m_wave_right - m_wave_left + 1);\n\t\t}\n\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\t\tint width = rect.width();\n\t\tint top = rect.m_top;\n\t\tint left = rect.m_left;\n\t\tfor (int y_pos = (m_wave_top - 1); y_pos <= (m_wave_bottom + 1); y_pos++)\n\t\t{\n\t\t\t(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);\n\t\t}\n\t}\n\tvoid save_background()\n\t{\n\t\tif (!m_bg_fb)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tc_rect rect;\n\t\tget_screen_rect(rect);\n\n\t\tunsigned int* p_des = m_bg_fb;\n\t\tfor (int y = rect.m_top; y <= rect.m_bottom; y++)\n\t\t{\n\t\t\tfor (int x = rect.m_left; x <= rect.m_right; x++)\n\t\t\t{\n\t\t\t\t*p_des++ = m_surface->get_pixel(x, y, m_z_order);\n\t\t\t}\n\t\t}\n\t}\n\n\n\tchar* m_wave_name;\n\tchar* m_wave_unit;\n\n\tconst LATTICE_FONT_INFO* m_wave_name_font;\n\tconst LATTICE_FONT_INFO* m_wave_unit_font;\n\n\tunsigned int m_wave_name_color;\n\tunsigned int m_wave_unit_color;\n\n\tunsigned int m_wave_color;\n\tunsigned int m_back_color;\n\n\tint m_wave_left;\n\tint m_wave_right;\n\tint m_wave_top;\n\tint m_wave_bottom;\n\n\tshort m_max_data;\n\tshort m_min_data;\n\t\nprivate:\n\tc_wave_buffer*\tm_wave;\n\tunsigned int*\tm_bg_fb;\t\t\t//background frame buffer, could be used to draw scale line.\n\tint \t\t\tm_wave_cursor;\n\tint \t\t\tm_wave_speed;\t\t//pixels per refresh\n\tunsigned int\tm_wave_data_rate;\t//data sample rate\n\tunsigned int\tm_wave_refresh_rate;//refresh cycle in millisecond\n\tunsigned char \tm_frame_len_map[64];\n\tunsigned char \tm_frame_len_map_index;\n};\n"
  },
  {
    "path": "src/widgets/widgets.cpp",
    "content": "#include \"../widgets/button.h\"\n#include \"../widgets/dialog.h\"\n#include \"../widgets/keyboard.h\"\n#include \"../widgets/label.h\"\n#include \"../widgets/list_box.h\"\n#include \"../widgets/slide_group.h\"\n#include \"../widgets/spinbox.h\"\n#include \"../widgets/table.h\"\n#include \"../widgets/wave_buffer.h\"\n#include \"../widgets/wave_ctrl.h\"\n#include \"../widgets/edit.h\"\n\n#ifdef GUILITE_ON\nDIALOG_ARRAY c_dialog::ms_the_dialogs[SURFACE_CNT_MAX];\nc_keyboard  c_edit::s_keyboard;\n\nstatic c_keyboard_button s_key_0, s_key_1, s_key_2, s_key_3, s_key_4, s_key_5, s_key_6, s_key_7, s_key_8, s_key_9;\nstatic c_keyboard_button s_key_A, s_key_B, s_key_C, s_key_D, s_key_E, s_key_F, s_key_G, s_key_H, s_key_I, s_key_J;\nstatic c_keyboard_button s_key_K, s_key_L, s_key_M, s_key_N, s_key_O, s_key_P, s_key_Q, s_key_R, s_key_S, s_key_T;\nstatic c_keyboard_button s_key_U, s_key_V, s_key_W, s_key_X, s_key_Y, s_key_Z;\nstatic c_keyboard_button s_key_dot, s_key_caps, s_key_space, s_key_enter, s_key_del, s_key_esc, s_key_num_switch;\n\nWND_TREE g_key_board_children[] =\n{\n\t//Row 1\n\t{&s_key_Q, 'Q', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_W, 'W', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_E, 'E', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_R, 'R', 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_T, 'T', 0, POS_X(4), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_Y, 'Y', 0, POS_X(5), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_U, 'U', 0, POS_X(6), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_I, 'I', 0, POS_X(7), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_O, 'O', 0, POS_X(8), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_P, 'P', 0, POS_X(9), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t//Row 2 \n\t{&s_key_A, 'A', 0, ((KEY_WIDTH / 2) + POS_X(0)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_S, 'S', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_D, 'D', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_F, 'F', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_G, 'G', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_H, 'H', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_J, 'J', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_K, 'K', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_L, 'L', 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t//Row 3\n\t{&s_key_caps, 0x14,\t0, POS_X(0),\t\t\t\t\t\tPOS_Y(2), CAPS_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_Z,\t'Z',\t0, ((KEY_WIDTH / 2) + POS_X(1)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_X,\t'X',\t0, ((KEY_WIDTH / 2) + POS_X(2)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_C,\t'C',\t0, ((KEY_WIDTH / 2) + POS_X(3)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_V,\t'V',\t0, ((KEY_WIDTH / 2) + POS_X(4)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_B,\t'B',\t0, ((KEY_WIDTH / 2) + POS_X(5)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_N,\t'N',\t0, ((KEY_WIDTH / 2) + POS_X(6)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_M,\t'M',\t0, ((KEY_WIDTH / 2) + POS_X(7)),\tPOS_Y(2), KEY_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_del,0x7F,\t0, ((KEY_WIDTH / 2) + POS_X(8)),\tPOS_Y(2), DEL_WIDTH,\tKEY_HEIGHT},\n\t//Row 4\n\t{&s_key_esc,\t\t0x1B,\t0, POS_X(0),\t\t\t\t\t\tPOS_Y(3), ESC_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_num_switch,\t0x90,\t0, POS_X(2),\t\t\t\t\t\tPOS_Y(3), SWITCH_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_space,\t\t' ',\t0, ((KEY_WIDTH / 2) + POS_X(3)),\tPOS_Y(3), SPACE_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_dot,\t\t'.',\t0, ((KEY_WIDTH / 2) + POS_X(6)),\tPOS_Y(3), DOT_WIDTH,\tKEY_HEIGHT},\n\t{&s_key_enter,\t\t'\\n',\t0, POS_X(8),\t\t\t\t\t\tPOS_Y(3), ENTER_WIDTH,\tKEY_HEIGHT},\n\t{0,0,0,0,0,0,0}\n};\n\nWND_TREE g_number_board_children[] =\n{\n\t{&s_key_1,\t'1',\t0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_2,\t'2',\t0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_3,\t'3',\t0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},\n\n\t{&s_key_4,\t'4',\t0, POS_X(0), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_5,\t'5',\t0, POS_X(1), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_6,\t'6',\t0, POS_X(2), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},\n\n\t{&s_key_7,\t'7',\t0, POS_X(0), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_8,\t'8',\t0, POS_X(1), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_9,\t'9',\t0, POS_X(2), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},\n\n\t{&s_key_esc,0x1B,\t0, POS_X(0), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_0,\t'0',\t0, POS_X(1), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},\n\t{&s_key_dot,'.',\t0, POS_X(2), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},\n\n\t{&s_key_del, 0x7F,\t0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT * 2 + 2},\n\t{&s_key_enter,'\\n',\t0, POS_X(3), POS_Y(2), KEY_WIDTH, KEY_HEIGHT * 2 + 2},\n\t{0,0,0,0,0,0,0}\n};\n\n#endif"
  }
]