diff --git a/BUILD.SH b/BUILD.SH new file mode 100644 index 0000000..05bddc2 --- /dev/null +++ b/BUILD.SH @@ -0,0 +1,12 @@ +#SHS + +cd /usbhd0/3//table +/sys/develop/fasm asm_func.asm,asm_func.o,/usbhd0/3/table/system/ +waitfor +/kolibrios/develop/tcc/tcc -Iincludes -Llib table.c config.c window.c modules.c grid.c table_lib.c system/gui.c system/utf8.c system/proc_lib.c system/asm_func.o -o table -Werror -lini -lbox_lib -ldialog -ltable_lib + +/sys/develop/fasm display.asm,display,/usbhd0/3/table/modules/ +/sys/develop/fasm display_d.asm,display_d,/usbhd0/3/table/modules/ +/sys/develop/fasm display_w.asm,display_w,/usbhd0/3/table/modules/ + +exit diff --git a/CONFIG.C b/CONFIG.C new file mode 100644 index 0000000..7090e29 --- /dev/null +++ b/CONFIG.C @@ -0,0 +1,92 @@ + +#include +#include +#include + +#include "system/libini.h" +#include "modules.h" + +#include "config.h" + +config_data_t config_data; + +static char* config_section_table = "table"; +static char* config_section_modules = "table_modules"; + +static char* config_key_doc_f = "doc_formula"; +static char* config_key_doc_g = "doc_graph"; +static char* config_key_doc_k = "doc_hotkeys"; +static char* config_key_doc_d = "doc_modules"; + +static char* config_key_mdules_dir = "modules_dir"; +//static char* config_key_table = "table_lib"; + +static config_error = -1; + +static int __stdcall ini_callback(char* f_name, char* sec_name, char* key_name, char* key_value){ + char* cmdline = strchr(key_value, ','); + if (cmdline != NULL) { + cmdline[0] = 0; + cmdline++; + }; + + if (key_value[0] != '/') { + char dll_name [4096]; + strcpy(dll_name, config_data.modules_dir); + strcat(dll_name, "/"); + strcat(dll_name, key_value); + config_error = module_init(dll_name, cmdline, key_name); + free(dll_name); + }else + config_error = module_init(key_value, cmdline, key_name); + return !config_error; +} + + +int config_load(const char* path){ + _ksys_debug_puts("table: config >"); + _ksys_debug_puts(path); + _ksys_debug_puts("\n"); + + config_data.config_path = path; + + // alloc buffer on 5 path to file of documetation + char* buff = malloc(INI_VALUE_LEN*5); + if (buff == 0) return -1; + + if (ini_get_str(path, config_section_table, config_key_doc_f, buff, INI_VALUE_LEN, 0) == 0) + config_data.doc_formulas = buff; + else config_data.doc_formulas = NULL; + + if (ini_get_str(path, config_section_table, config_key_doc_g, buff + INI_VALUE_LEN*1, INI_VALUE_LEN, 0) == 0) + config_data.doc_graph = buff + INI_VALUE_LEN*1; + else config_data.doc_graph = NULL; + + if (ini_get_str(path, config_section_table, config_key_doc_k, buff + INI_VALUE_LEN*2, INI_VALUE_LEN, 0) == 0) + config_data.doc_hotkeys = buff + INI_VALUE_LEN*2; + else config_data.doc_hotkeys = NULL; + + if (ini_get_str(path, config_section_table, config_key_doc_d, buff + INI_VALUE_LEN*3, INI_VALUE_LEN, 0) == 0) + config_data.doc_module_api = buff + INI_VALUE_LEN*3; + else config_data.doc_module_api = NULL; + + ini_get_str(path, config_section_table, config_key_mdules_dir, buff + INI_VALUE_LEN*4, INI_VALUE_LEN, 0); + config_data.modules_dir = buff + INI_VALUE_LEN*4; + + // loading modules + ini_enum_keys(path, config_section_modules, &ini_callback); + + if (config_error != 0) { + _ksys_debug_puts("table: error config\n"); + return -1; + } else { + _ksys_debug_puts("table: good config\n"); + return 0; + }; +} + + +void config_save(){ + + return ; +} \ No newline at end of file diff --git a/GRID.C b/GRID.C new file mode 100644 index 0000000..c40ba44 --- /dev/null +++ b/GRID.C @@ -0,0 +1,335 @@ +// micro grid library +#include + +//#include +void* __memcpy(void* _dest, const void* _src, size_t _n) +{ + int d0, d1, d2; + __asm__ __volatile__( + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c"(d0), "=&D"(d1), "=&S"(d2) + : "0"(_n / 4), "q"(_n), "1"((long)_dest), "2"((long)_src) + : "memory"); + return (_dest); +} + +#include "table_lib.h" +#include "grid.h" + +void grid_get_border_line(GRID_BORDER_LINE_FORMAT* this, ksys_color_t* buff, + ksys_color_t color_line, ksys_color_t color_bg, + uint32_t count, uint32_t fix_count){ + uint8_t default_pattern = 0; + switch(this -> format) { + case GRID_BORDER_TYPE_PATTERN: + default_pattern = this -> pattern; + break; + case GRID_BORDER_TYPE_PATTERN_BEGIN_1: + default_pattern = 0xFF; + break; + case GRID_BORDER_TYPE_PATTERN_BEGIN_0: + default_pattern = 0; + break; + case GRID_BORDER_TYPE_PATTERN_END_1: + default_pattern = 0xFF; + break; + case GRID_BORDER_TYPE_PATTERN_END_0: + default_pattern = 0; + break; + } + uint32_t counter = 0; + while (counter < fix_count) { + if (default_pattern & 1 << (counter & 0b111)) + buff[counter] = color_line; + else buff[counter] = color_bg; + counter++; + } + counter = 0; + switch(this -> format) { + case GRID_BORDER_TYPE_PATTERN_BEGIN_1: + case GRID_BORDER_TYPE_PATTERN_BEGIN_0: + while (counter < 8 && (counter < fix_count)) { + if (this ->pattern & 1 << (counter & 0b111)) + buff[counter] = color_line; + else buff[counter] = color_bg; + counter++; + } + break; + case GRID_BORDER_TYPE_PATTERN_END_1: + case GRID_BORDER_TYPE_PATTERN_END_0: + while (counter < 8 && (count - 8 + counter < fix_count)) { + if (this ->pattern & 1 << (counter & 0b111)) + buff[count - 8 + counter] = color_line; + else buff[count - 8 + counter] = color_bg; + counter++; + } + break; + } + return; +} + +void grid_draw_cell_border(GRID* rthis, GRID_CELL_FORMAT* this, + uint32_t x, uint32_t y, + uint32_t fix_width, uint32_t fix_height) { + + ksys_color_t* buff = NULL; + size_t i; + + if ((this -> border_bitmask & 0xffff) == 0) goto skip; + buff = _ksys_alloc(sizeof(ksys_color_t)*fix_height); + if (buff == NULL) goto error; + // check bitmask + if (this -> border_bitmask_l != 0) { + // draw + for(i = 0; i < 4; i++) { + if ((this -> border_bitmask_l & 1 << i) && + (i <= fix_width)) { + + grid_get_border_line(&(this -> border_l.line[i]), buff, this -> border_l.color, + this -> bg_color, this -> height, fix_height); + // draw line + rthis -> draw_image(rthis, x + i, y, 1, fix_height, buff); + } + } + } + if (this -> border_bitmask_r != 0) { + // draw + for(i = 0; i < 4; i++) { + if ((this -> border_bitmask_r & 1 << i) && + (i >= this -> width - fix_width)) { + + grid_get_border_line(&(this -> border_r.line[i]), buff, this -> border_r.color, + this -> bg_color, this -> height, fix_height); + // draw line + rthis -> draw_image(rthis, x + this -> width - 1 - i, y, 1, fix_height, buff); + + } + } + } + _ksys_free(buff); + +skip: + + if ((this -> border_bitmask & 0xffff0000) == 0) goto error; + buff = _ksys_alloc(sizeof(ksys_color_t)*fix_width); + if (buff == NULL) goto error; + + if (this -> border_bitmask_t != 0) { + // draw + for(i = 0; i < 4; i++) { + if ((this -> border_bitmask_t & 1 << i) && + (i <= fix_height)){ + + grid_get_border_line(&(this -> border_t.line[i]), buff, this -> border_t.color, + this -> bg_color, this -> width, fix_width); + // draw line + rthis -> draw_image(rthis, x, y + i, fix_width, 1, buff); + } + } + } + if (this -> border_bitmask_b != 0) { + // draw + for(i = 0; i < 4; i++) { + if ((this -> border_bitmask_b & 1 << i) && + (i >= this -> height - fix_height)){ + + grid_get_border_line(&(this -> border_b.line[i]), buff, this -> border_b.color, + this -> bg_color, this -> width, fix_width); + // draw line + rthis -> draw_image(rthis, x, y + this -> height - 1 - i, fix_width, 1, buff); + } + } + } + _ksys_free(buff); +error: + return; +} + +void grid_draw_cell(GRID_NOSTD_CELL* this) { + // draw background + this -> rthis -> draw_bar( + this -> rthis, this -> x, this -> y, + this -> fix_width, this -> fix_height, + this -> format.bg_color); + + // get cell content + table_object* content = this -> rthis -> get_cell_value(this -> rthis, + this -> col, this -> row); + + if (content != 0) { + if (content -> type == TABLE_OBJECT_TYPE_STR) { + // draw content + this -> rthis -> draw_text(this -> rthis, + this -> x, this -> y, + this -> fix_width, this -> fix_height, + &(((table_object_str*)content) -> str), + this -> format.text_params); + }else if (content -> type == TABLE_OBJECT_TYPE_IMAGE) { + this -> rthis -> draw_image( + this -> rthis, + this -> x, + this -> y, + ((table_object_image*)content) -> width, + ((table_object_image*)content) -> height, + &(((table_object_image*)content) -> data)); + } + /* + if (this -> col == 3 && this -> row == 4) + write_text_utf8_center(this -> x, + this -> y, + this -> fix_width - 1,"=d16_2.DisplayOutStr(A1)",0); + */ + // free content buffer + this -> rthis -> free_cell_value(this -> rthis, content); + } + + if (!(this -> rthis -> flags & GRID_FLAG_CLEAN_MODE)) { + this -> rthis -> draw_bar(this -> rthis, + this -> x, this -> y, + 1, this -> fix_height, + this -> rthis -> grid_color); + this -> rthis -> draw_bar(this -> rthis, + this -> x, this -> y, + this -> fix_width, 1, + this -> rthis -> grid_color); + } + // draw border of cell + grid_draw_cell_border(this -> rthis, &(this -> format), + this -> x, this -> y, + this -> fix_width, this -> fix_height); + return; +} + + +void draw_grid(GRID* this){ + // draw border and backgraund + uint32_t fixed_width = this -> w; + uint32_t fixed_height = this -> h; + //draw_scroll + if (!(this -> flags & GRID_FLAG_NO_SCROLL)) { + // draw scroll_1 + // draw scroll_2 + }; + + // set and draw select all button + GRID_CELL_FORMAT format_col; // размер-длина столбца + GRID_CELL_FORMAT format_row; // размеры-высота строки + uint32_t first_cell_x_offset = 0; + uint32_t first_cell_y_offset = 0; + + GRID_NOSTD_CELL cell_data = { + .rthis = this, + .y = this -> y + }; + + GRID_NOSTD_CELL* stack = _ksys_alloc(sizeof(GRID_NOSTD_CELL)*1024); + uint32_t count_stack = 0; + if (!stack) return; + + // draw format and content of grid + while (first_cell_y_offset < fixed_height){ + first_cell_x_offset = 0; + cell_data.x = this -> x; + cell_data.col = 0; + + // get row format data + this -> get_cell_format(this, &format_row, 0, cell_data.row); + + while (first_cell_x_offset < fixed_width) { + + // get col format data + this -> get_cell_format(this, &format_col, cell_data.col, 0); + + // get + this -> get_cell_format(this, &cell_data.format, cell_data.col, cell_data.row); + + if (cell_data.row == 0) { + if (this -> flags & GRID_FLAG_NO_HEADER_COL) break; + }; + + // fixed width and height of cell + if ((first_cell_x_offset + cell_data.format.width) > fixed_width) + cell_data.fix_width = fixed_width - first_cell_x_offset; + else cell_data.fix_width = cell_data.format.width; + + if ((first_cell_y_offset + cell_data.format.height) > fixed_height) + cell_data.fix_height = fixed_height - first_cell_y_offset; + else cell_data.fix_height = cell_data.format.height; + + + if (format_col.width != cell_data.format.width || + format_row.height != cell_data.format.height) { + // add in array of notstd cells + if (count_stack < 1024) { + __memcpy(&stack[count_stack], &cell_data, sizeof(GRID_NOSTD_CELL)); + count_stack++; + } + // skip draw cell + goto skip_draw; + } + + if (cell_data.col != 0 || ! (this -> flags & GRID_FLAG_NO_HEADER_ROW)) { + + grid_draw_cell(&cell_data); + } +skip_draw: + if (cell_data.col == 0) { + cell_data.col = this -> content_pos_col; + if (! (this -> flags & GRID_FLAG_NO_HEADER_ROW)) { + first_cell_x_offset += format_col.width; + cell_data.x += format_col.width; + } + continue; + } + + first_cell_x_offset += format_col.width; + cell_data.x += format_col.width; + cell_data.col++; + }; + + if (cell_data.row == 0) { + cell_data.row = this -> content_pos_row; + if (! (this -> flags & GRID_FLAG_NO_HEADER_COL)) { + first_cell_y_offset += format_row.height; + cell_data.y += format_row.height; + } + continue; + } + first_cell_y_offset += format_row.height; + cell_data.y += format_row.height; + cell_data.row++; + }; + while (count_stack > 0) { + grid_draw_cell(&stack[count_stack-1]); + count_stack--; + } + _ksys_free(stack); + + // draw selected cell + + return ; +} + +void grid_key(GRID* this, ksys_oskey_t ch) { + if (ch.ctrl_key == KSYS_SCANCODE_EXT_UP && this -> selected_cell_row > 1) this -> selected_cell_row--; + else if (ch.ctrl_key == KSYS_SCANCODE_EXT_DOWN) this -> selected_cell_row++; + else if (ch.ctrl_key == KSYS_SCANCODE_EXT_LEFT && this -> selected_cell_col > 1 ) this -> selected_cell_col--; + else if (ch.ctrl_key == KSYS_SCANCODE_EXT_RIGHT) this -> selected_cell_col++; + else { + //callback + this -> event_cell_key(this, 0, 0, ch); + } + draw_grid(this); + return; +} + +void grid_mouse(GRID* this){ + +} \ No newline at end of file diff --git a/LIB/table_lib.DEF b/LIB/table_lib.DEF new file mode 100644 index 0000000..9b98748 --- /dev/null +++ b/LIB/table_lib.DEF @@ -0,0 +1,5 @@ +LIBRARY table_lib.obj + +EXPORTS +create_table_object +destruct_table_object diff --git a/MODULES.C b/MODULES.C new file mode 100644 index 0000000..c3b47b6 --- /dev/null +++ b/MODULES.C @@ -0,0 +1,127 @@ +/* this file description of the modules API and included functions for +loading, initializing, closing and calling functions of modules. + +Файл - Реализация загрузки всех модулей, их инициалиазция. +Данный файл обеспечивает загрузку модулей и вызов функций проверки и +инициализации модулей формул и форматов. + +Описание поведения программы при работе с модулями: +После загрузки конфигурации программа провеяет наличие в параметрах +командной строки пути к файлу таблицчного документа. + Если такого файла нет, то создаётся новый объект table_DOM и доступны +к использованию формулы из всех модулей. + Если файл является табличным документом и загружается каким-либо модулем, +то всплывает окно с выбором доступных данному документу формул модулей. + + +Каждый документ должен предоставить информацию об использованных модулях. +Если это евозможно ввиду особенностей формата(csv), то всплывает окно с +выбором модулей формул. + +;----------------------------------------------------------------------------- + + - Для расширения функционала() + +;----------------------------------------------------------------------------- +Для формул модуль должен предоставить таблицу описания формулы + + +*/ +#include +#include +#include +#include + +#include "modules.h" + +static table_exports_t table_exports = { + .version = 0x0102, // 0.1.2 +}; + +static module_t* modules_list = NULL; + +int module_init(char* dll_name, char* cmdline, char* namespace){ + + module_t* this = (module_t*)malloc(sizeof(module_t)); + if (!this) + return ENOMEM; + // clear flags + this -> flags = 0; + // copy dll name + this -> dll_path = strdup(dll_name); + // copy namespae + strncpy(this -> namespace, namespace, sizeof(this -> namespace) - 1); + this -> namespace[sizeof(this -> namespace) - 1] = '\0'; + // load dll + this -> dll = _ksys_dlopen(dll_name); + if (this -> dll == NULL) + return -1;// not load dll + + this -> fn_init = _ksys_dlsym(this -> dll, "tmodule_init"); + this -> fn_close = _ksys_dlsym(this -> dll, "tmodule_close"); + // call 'tmodule_init' + if (!(this -> fn_init || this -> fn_close)) + return -1;// not found standarted function + this -> pdata = this -> fn_init(&table_exports, cmdline, namespace); + if (this -> pdata == NULL) + return -1; // not init module + + // call formats_init + import_format_t* __stdcall (*module_get_formats)(uint32_t); + module_get_formats = _ksys_dlsym(this -> dll, "tmodule_formats"); + if (module_get_formats) + this -> formats = module_get_formats(this -> pdata); + else + this -> formats = NULL; + + // call formulas_init + import_formula_t* __stdcall (*module_get_formulas)(uint32_t); + module_get_formulas = _ksys_dlsym(this -> dll, "tmodule_formulas"); + if (module_get_formulas) + this -> formulas = module_get_formulas(this -> pdata); + else + this -> formulas = NULL; + + // add_list_item this + this -> next = modules_list; + modules_list = this; + return 0; +} + +void modules_exit(){ + module_t* this = modules_list; + while (modules_list == NULL ) { + this -> fn_close(this -> pdata); + // del_list_item this + modules_list = this -> next; + + if (this -> flags & MODULE_FLAG_EMMBEDED == NULL){ + // free module_t.dll_path + free(this -> dll_path); + // free this + free(this); + }; + }; + return; +} + + +module_t* find_module_namespace(const char* namespace, uint32_t len){ + return NULL; +} + +int call_module_formula(module_t* this, const char* func_name, uint32_t len){ + + return 0; +} + + +int modules_save_file(char* path){ + + return; +} + +int modules_load_file(char* path){ + + return; +} \ No newline at end of file diff --git a/SYSTEM/ASM_FUNC.ASM b/SYSTEM/ASM_FUNC.ASM new file mode 100644 index 0000000..4a153c4 --- /dev/null +++ b/SYSTEM/ASM_FUNC.ASM @@ -0,0 +1,98 @@ + +format ELF + + +;============================== +;public argc as '__argc' - no needed for tiny app +public num2cell_num as 'num2cell_num' +public cell_num2num as 'cell_num2num' +public cell_num_chars as 'cell_num_chars' + +section '.text' + +; IN: arg0 = num +; arg1 - ptr buffer(12 chars) +; OUT: - +num2cell_num: +; 26 = 11010b = Z +; AA = 27 = 11011b +; +; dec: 11010b = AA +; 11010b*26 = 1010100100b = AAA +; X2 = 10101001000b = ABA +; X3 = 11111101100b = ACA +; X4 = 101010010000b = ADA +; = 110100110100b = AEA +; +; ;dec num +;.loop: +; +; ; copy stack in buffer +; + push ebx edi ebp + mov ebp, esp + + mov eax, dword [esp + 4*3 + 4] + dec eax +.cycle: + xor ecx, ecx + mov edx, 1 shl 27 + mov ebx, 26 shl 27 + +.shift: + cmp eax, ebx + jb @F + sub eax, ebx + or ecx, edx +@@: + shr ebx, 1 + shr edx, 1 + jnz .shift + + add al,'A' + dec esp + mov byte [esp],al + + mov eax,ecx + test eax,eax + lea eax,[eax-1] + jnz .cycle + + mov edi, [ebp + 4*3 + 8] +@@: + cmp esp, ebp + je @f + + mov al, byte[esp] + stosb + inc esp + jmp @b +@@: + xor eax, eax + stosb + pop ebp edi ebx + ret 8 + +; IN: arg0 = ptr to string of number +; OUT: eax - number or null +cell_num2num: + +.loop: + + ;cmp , 0 + ;jne .loop + ;inc old + ; mul 26 + + ret 4 + +; AA = (1*26 + 0 ) + 1 -1 + +; AAA = +; A = 1 + +;section '.data' +; dec 01234567890123456789012345 +; 12345678901234567890123456 +cell_num_chars: db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +.size = $ - cell_num_chars \ No newline at end of file diff --git a/SYSTEM/ASM_FUNC.O b/SYSTEM/ASM_FUNC.O new file mode 100644 index 0000000..1ac218c Binary files /dev/null and b/SYSTEM/ASM_FUNC.O differ diff --git a/SYSTEM/ENV.H b/SYSTEM/ENV.H new file mode 100644 index 0000000..adf6004 --- /dev/null +++ b/SYSTEM/ENV.H @@ -0,0 +1,12 @@ + +// return errno vanue +int get_env(const char* key, char* buff, size_t len){ + return -1; +} +int get_env_info(const char* key, uint32_t* len_data){ + return -1; +} +int set_env(const char* key, char* buff, size_t len){ + return -1; +} + diff --git a/SYSTEM/OTHER.C b/SYSTEM/OTHER.C new file mode 100644 index 0000000..e69de29 diff --git a/SYSTEM/PROC_LIB.C b/SYSTEM/PROC_LIB.C new file mode 100644 index 0000000..2e2e87c --- /dev/null +++ b/SYSTEM/PROC_LIB.C @@ -0,0 +1,42 @@ + +#include +#include + +char sz_com_area_name[] = "FFFFFFFF_open_dialog"; +char sz_dir_default_path[] = "/sys"; +char sz_start_path[] = "/sys/File managers/opendial"; + +void fake_on_redraw(void) { } + +open_dialog* kolibri_new_open_dialog(unsigned int mode, unsigned short tlx, unsigned short tly, unsigned short x_size, unsigned short y_size) +{ + open_dialog* new_opendialog = (open_dialog*)malloc(sizeof(open_dialog)); + od_filter* new_od_filter = (od_filter*)malloc(sizeof(od_filter)); + char* plugin_path = (char*)calloc(4096, sizeof(char)); + char* openfile_path = (char*)calloc(4096, sizeof(char)); + char* proc_info = (char*)calloc(1024, sizeof(char)); + char* filename_area = (char*)calloc(256, sizeof(char)); + + new_od_filter->size = 0; + new_od_filter->end = 0; + + new_opendialog->mode = mode; + new_opendialog->procinfo = proc_info; + new_opendialog->com_area_name = sz_com_area_name; + new_opendialog->com_area = 0; + new_opendialog->opendir_path = plugin_path; + new_opendialog->dir_default_path = sz_dir_default_path; + new_opendialog->start_path = sz_start_path; + new_opendialog->draw_window = &fake_on_redraw; + new_opendialog->status = 0; + new_opendialog->openfile_path = openfile_path; + new_opendialog->filename_area = filename_area; + new_opendialog->filter_area = new_od_filter; + new_opendialog->x_size = x_size; + new_opendialog->x_start = tlx; + new_opendialog->y_size = y_size; + new_opendialog->y_start = tly; + return new_opendialog; +} + + diff --git a/SYSTEM/UTF8.C b/SYSTEM/UTF8.C new file mode 100644 index 0000000..246a317 --- /dev/null +++ b/SYSTEM/UTF8.C @@ -0,0 +1,15 @@ + +#include + +size_t utf8len(char* s) { + size_t tmp = 0; + while (*s != 0) { + tmp++; + if ((*s & 0x80) == 0) s++; + else if ((*s & 0x20) == 0) s += 2; + else if ((*s & 0x10) == 0) s += 3; + else s += 4; + continue; + }; + return tmp; +}; \ No newline at end of file diff --git a/SYSTEM/gui.c b/SYSTEM/gui.c new file mode 100644 index 0000000..465e292 --- /dev/null +++ b/SYSTEM/gui.c @@ -0,0 +1,191 @@ +/* + +:dword MixColors(dword _base, _overlying, dword a) +{ + _rgb rgb1, rgb2, rgb_final; + dword n_a; + + rgb1.DwordToRgb(_base); + rgb2.DwordToRgb(_overlying); + + n_a = 255 - a; + + rgb_final.b = calc(rgb1.b*a/255) + calc(rgb2.b*n_a/255); + rgb_final.g = calc(rgb1.g*a/255) + calc(rgb2.g*n_a/255); + rgb_final.r = calc(rgb1.r*a/255) + calc(rgb2.r*n_a/255); + + return rgb_final.RgbToDword(); +} + +:bool skin_is_dark() +{ + ESI = #sc.work; + + EDI = DSBYTE[ESI]*DSBYTE[ESI]; + EDI += DSBYTE[ESI+1]*DSBYTE[ESI+1]; + EDI += DSBYTE[ESI+2]*DSBYTE[ESI+2]; + + if (sqrt(EDI) / 3 < 65) { + return true; + } else { + return false; + } +} + +unsigned int DrawTopPanelButton(dword _button_id, _x, _y, signed int _icon_n, bool pressed) +{ + #define TSZE 25 + static dword lightest, i16_mem, old_work_light; + + dword i16_size; + if (!lightest) || (old_work_light != sc.light) { + old_work_light = sc.light; + lightest = MixColors(sc.light, 0xFFFfff, skin_is_dark()*155 + 20); + if (ESI = memopen("ICONS18", NULL, SHM_READ)) { + i16_size = EDX; + i16_mem = malloc(i16_size); + memmov(i16_mem, ESI, i16_size); + replace_2cols(i16_mem, i16_size, 0xffFFFfff, sc.light, 0xffCACBD6, sc.dark); + } + } + DrawWideRectangle(_x+1, _y+1, TSZE, TSZE, 5, sc.light); + DefineHiddenButton(_x, _y, TSZE+1, TSZE+1, _button_id); + if (_icon_n==-1) { + DrawBar(_x+6, _y+5, 16, 16, sc.light); + DrawBar(_x+6, _y+7, 15, 3, sc.line); + + $add ecx,5*65536 + $int 64 + + $add ecx,5*65536 + $int 64 + } else { + if (i16_mem) PutPaletteImage(18*18*4*_icon_n + i16_mem, + 18, 18, TSZE/2-9+2+_x, TSZE/2-9+1+_y+pressed, 32, 0); + } + + if (!pressed) { + DrawOvalBorder(_x, _y, TSZE, TSZE, lightest, sc.line, sc.light, sc.work); + } else { + DrawOvalBorder(_x, _y, TSZE, TSZE, sc.line, sc.light, sc.dark, sc.work); + PutShadow(_x+1, _y+1, TSZE, TSZE, true, 2); + } + + return _x; +} + +*/ +#include +#include +#include +#include + +#include + +#define TSZE 25 + +extern ksys_colors_table_t color_table; + +void replace_2cols(ksys_color_t* buff, uint32_t size, ksys_color_t col_in1, ksys_color_t col_out1, + ksys_color_t col_in2, ksys_color_t col_out2){ + uint32_t end_ptr = size + (uint32_t)buff; + while ((uint32_t)buff < (uint32_t)end_ptr) { + if (*buff == col_in1) *buff = col_out1; + else if (*buff == col_in2) *buff = col_out1; + buff++; + }; + return; +} + +#define BT_HIDE 0x40000000 +static void DefineHiddenButton(uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h, uint32_t _id) +{ + _ksys_delete_button(_id); + _ksys_define_button(_x, _y, _w, _h, _id + BT_HIDE, 0); + return; +} + +static void DrawWideRectangle(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t boder, ksys_color_t color1) { + _ksys_draw_bar(x, y, w, boder, color1); + _ksys_draw_bar(x, y+h-boder, w, boder, color1); + _ksys_draw_bar(x, y+boder, boder, h-boder-boder, color1); + _ksys_draw_bar(x+w-boder, y+boder, boder, h-boder-boder, color1); + return; +} + +static void DrawOvalBorder(uint32_t x, uint32_t y, uint32_t w, uint32_t h, + ksys_color_t light, ksys_color_t dark, + ksys_color_t right, ksys_color_t dots) { + _ksys_draw_bar(x+1, y, w, 1, light); + _ksys_draw_bar(x+1, y+h+1, w, 1, dark); + _ksys_draw_bar(x, y+1, 1, h-1, light); + _ksys_draw_bar(x+w+1, y+2, 1, h-2, right); + + _ksys_draw_pixel(x, y, dots); + _ksys_draw_pixel(x+w+1, y+h+1, dots); + _ksys_draw_pixel(x, y+h+1, dots); + _ksys_draw_pixel(x+w+1, y, dots); + + _ksys_draw_pixel(x, y+h, dark); + _ksys_draw_pixel(x+w+1, y+1, light); + _ksys_draw_pixel(x+w+1, y+h, dark); + return; +} + +ksys_color_t lightest = 0; +void* i16_mem = NULL; + +void gui_draw_button_icon18(uint32_t button_id, uint16_t x, uint16_t y, uint32_t id_icon, int pressed){ + + uint32_t i16_size; + + if ((!lightest) || (lightest != color_table.grab_button_text)) { + //old_work_light = sc.grab_button_text; + lightest = color_table.grab_button_text;//MixColors(sc.light, 0xFFFfff, skin_is_dark()*155 + 20); + void* buffer; + int shm_size = _ksys_shm_open("ICONS18", KSYS_SHM_READ, 0, (char**)&buffer); + if (shm_size) { + i16_size = shm_size; + if (i16_mem != 0) free(i16_mem); + i16_mem = malloc(i16_size); + memmove(i16_mem, buffer, i16_size); + replace_2cols(i16_mem, i16_size, 0xffFFFfff, color_table.grab_button_text, 0xffCACBD6, + color_table.grab_bar_button); + } + } + + DrawWideRectangle(x+1, y+1, TSZE, TSZE, 5, color_table.grab_button_text); + DefineHiddenButton(x, y, TSZE+1, TSZE+1, button_id); + if (id_icon == -1) { + _ksys_draw_bar(x+6, y+5, 16, 16, color_table.grab_button_text); + + _ksys_draw_bar(x+6, y+7, 15, 3, color_table.work_graph); + _ksys_draw_bar(x+6, y+7+5, 15, 3, color_table.work_graph); + _ksys_draw_bar(x+6, y+7+10, 15, 3, color_table.work_graph); + } else { + if (i16_mem) + ksys_draw_bitmap_palette(i16_mem + 18*18*4*id_icon, TSZE/2-9+2+x, TSZE/2-9+1+y+pressed, 18, 18, + 32, NULL, 0); + } + + if (!pressed) { + DrawOvalBorder(x, y, TSZE, TSZE, lightest, color_table.work_graph, + color_table.grab_button_text, + color_table.work_area); + } else { + DrawOvalBorder(x, y, TSZE, TSZE, color_table.work_graph, + color_table.grab_button_text, + color_table.grab_bar_button, + color_table.work_area); + //PutShadow(x+1, y+1, TSZE, TSZE, true, 2); + }; + return ; +} + + +void write_text_utf8_center(uint32_t x, uint32_t y, int32_t w, const char* text, int32_t SSS) { + int32_t tmp = w - utf8len(text)*8*(SSS+1); + if (tmp < 0) tmp = 0; + _ksys_draw_text(text, x+tmp/2, y, 0, ((0xB0 + SSS)<< 24)+ color_table.work_text); + return; +} diff --git a/TABLE b/TABLE new file mode 100644 index 0000000..d52d35f Binary files /dev/null and b/TABLE differ diff --git a/TABLE.INI b/TABLE.INI new file mode 100644 index 0000000..2998992 --- /dev/null +++ b/TABLE.INI @@ -0,0 +1,63 @@ +[table] +winX=0 +winY=0 +;winW=0 +;winH=0 +work_dir=/sys/tmodules +doc_formula=/usbhd0/3/server_data/gost.pdf +;doc_graph= +;doc_hotkeys= +doc_modules=/usbhd0/3/table/modules/display.asm + +modules_dir=/usbhd0/3/table/modules + + +;interface=/usbhd0/3/table_lib/gui.obj, cmdline + +[table_modules] +;std=/sys/lib/std_table.obj, cmdline +display=/usbhd0/3/table/modules/display, module cmdline +d16_2=/usbhd0/3/table/modules/display, test 2 +;d16_2=display, test 3 +;xlsx=/usbhd0/3/table_lib/xlsx.obj + +; namespace = path, cmdline +; абсолютный или от папки расположения бинарника table + +; Если програма нашла один модуль интерфейса, то другие модули интерфейса игнорируются + + +; system.env +; documents=/sd0/4/data +; temp=/tmp0/1/.temp +; table_config=/sys/sqlite_viewer.ini + +; cmd args +; table -config +; table -config +; table +; table + +; Приоритеты конфигураций: +; 0 - конфигурация в параметре, параметр "-config" должен идти первым аргументом +; 1 - конфигурация, прописанная в переменных окружения +; 2 - дефолтная конфигурация "/sys/settings/table.ini" +; + + +; API moduoles + + +; table_module_export* table_api_exports(uint32_t pdata) + +; API для модулей подержки интерфейсов +; uint32_t table_api_preload(uint32_t pdata) + +; void table_api_get_key(ksys_oskey_t key, uint32_t pdata) +; void table_api_get_button(uint32_t button_id, uint32_t pdata) +; void table_api_get_mouse(uint32_t pdata) + + + + + diff --git a/api.md b/api.md new file mode 100644 index 0000000..6e7a2dc --- /dev/null +++ b/api.md @@ -0,0 +1,361 @@ +# Экспорты модулей + + ## Обязательные экспорты + + ### Инициализация модуля + Для распознования библиотеки как модуля, она должна экспортировать функцияю "table_api_init", в которую будет передаваться таблица импорта функция программы и параметры из файла конфигураци. + + ```C + uint32_t table_api_init(IMPORT_DATA* list_functions, char* cmdline); + ``` + + ### Завершение работы модуля + При завершении работы программы, она должна вызвать у каждого модуля функцию "table_api_exit" для сохранения результата работы этого модуля. Программа завершит исполнение только когда все модули вернут управление +из этой функции. + + ```C + void table_api_exit(uint32_t pdata); + ``` + + ### Передача таблицы экспорта + + + ```C + void* table_api_export(uint32_t pdata); + ``` + + ## Экспорты для модулей форматов файлов + + table_DOM* table_api_file_open(char* path, uint32_t pdata); + + uint32_t table_api_file_save(table_DOM* src, char* path, uint32_t pdata); + + + ## Экспорты для модулей расширенных формул + + void* table_api_formulas_list(uint32_t pdata); + + ## Экспорты для модулей интерфейса + + +# Импорты для модулей + ## Функции работы с табличным документом + table_DOM* create_table_dom(); + + void destruct_table_dom(table_DOM* ptr); + + ### Работа с страницами документа + + uint32_t add_page_table_dom(table_DOM* ptr, char* name, uint32_t length); + // return index page or -1 for error + + uint32_t del_page_table_dom(table_DOM* ptr, uint32_t index_page); + + uint32_t get_count_page_table_dom(table_DOM* ptr); + // return max index. min index=1, index++ + + uint32_t get_name_page_table_dom(table_DOM* ptr, uint32_t index_page); + // return index page or -1 for error + + uint32_t rename_page_table_dom(table_DOM* ptr, uint32_t index_page, char* name, uint32_t length); + + table_area_dom* get_area_table_dom(table_DOM* ptr, uint32_t index_page); + + + ### Работа с табличной частью страницы + + table_area_dom* create_table_area(table_DOM* ptr); + + void destruct_table_area(table_area_dom* ptr); + + uint32_t set_cell(table_area_dom* ptr, uint32_t row, uint32_t col, char* str, uint32_t length); + + char* get_cell(table_area_dom* ptr, uint32_t row, uint32_t col); + + void* get_result_cell(table_area_dom* ptr, uint32_t row, uint32_t col); + + + + ### Работа с оформлением табличной части + + Оформление ячеек(или групп ячеек) хранится отдельно от содержимого ячейки. + + + Для установки границ ячейки нужно установить необходимые биты в структуре. Каждый из 4 битов соответствует линии пикселей, + младший это самая нижняя или самая правая линия, старший бит это самая верхняя или самая левая линия. + + Значение по умолчанию можно установить и получить по индексу ноль. + + В зависимости от применения используемые поля могут отличаться. При применении к строке(0,2:23-1) не используется поле width. + При применении к столбцу не используется поле height. + + Граница применяется к группе ячеек + + typedef struct { + uint16_t width; + uint16_t height; + rgba bg_color; + rgba text_color; + uint16_t border_type; //bits 0-3 left, 4-7 right, 8-11 top, 12-15 bottom + // bits description: + // 0000 - default full line + // 0001 - штриховка, частая + // 0010 - штрифовка, средняя + // 0011 - штриховка, редкая + // 0100 - углы + uint8_t border_l_r; // bits 0-3 - border left, bits 4-7 - border right + uint8_t border_t_b; // bits 0-3 - border top, bits 4-7 - border bottom + }table_appearance; + + uint32_t add_appearance_table(table_appearance* buff); + // return index, -1 - error + + uint32_t del_appearance_table(uint32_t index); + // return status + + uint32_t update_appearance_table(table_appearance* buff, uint32_t index); + // return status + + uint32_t get_appearance_table(table_appearance* buff); + // return status + + uint32_t set_appearance_cell_area_dom(table_area_dom* ptr, uint32_t row, uint32_t col, table_appearance* appearance); + // return status + + uint32_t get_appearance_cell_area_dom(table_area_dom* ptr, uint32_t row, uint32_t col); + // return index, -1 - error + + + ### Работа с встраиваемыми объектами + + + ## Функции работы с построителем графика + + ## Функции работы с печатью табличного документа + ### Выбор принтера + + ### Выбор параметров принтера + + ### Печать документа + + + ## Функции работы с интерфейсом + + Так как программа имеет возможность использования модулей, модули интерфейса просто необходимы. Как пример использования модулей интерфейса - программа учёта. + Хоть учёт можно вести в табличном редакторе и без дополнительных модулей, возможность автоматизации некоторых действий и более удобный интерфейс для этого + упростит множество операций, таких как добавления нового элемента справочника товаров или нового документа расходов и приходов. + + ### Работа с параметрами окна(заголовок, размер, цвет элементов, ...) + + ```C + typedef struct { + uint16_t min_height; + uint16_t min_width; + uint16_t max_height; + uint16_t max_width; + char* caption; // UTF-8 + //SC* colors; + + // work area + uint16_t wa_pos_x; + uint16_t wa_pos_y; + uint16_t wa_width; + uint16_t wa_height; + // + button_panel* tool_bar; + menu_panel* menu; + tab_panel* tabs; + + }interface_data; + ``` + + ### Работа с рабочей областью + + Относительно рабочей области можно создать некоторое кол-во объектов, помогающих в организации интерфейса. + + + typedef struct { + + }work_area_params; + + work_area_params* __stdcall get_work_area_params(); + + + #### Встроенные кнопки + + Кнопки: в них можно задать текст и иконку к тексту(или за место него) Что текст что иконка всегда выравниавются по центру. + ```C + typedef struct { + uint16_t pos_x; + uint16_t pos_y; + uint16_t width; + uint16_t height; + rgba color; + pgba* icon; // 18x18 pixel + char* text; + uint32_t callback_data; + void* button_click; //void __stdcall button_click(uint32_t callback_data,uint8_t mouse_key); + }work_button; + + uint32_t __stdcall create_button(work_button* new_button); + // return handle or zero for error + void __stdcall delete_button(uint32_t handle); + + ``` + TODO + + #### Table + + ### Работа с панелью функций (верхнаяя панель с иконками) + + Работа с панелью функций сводится к получению события нажатия на кнопку. + + select_button указывает на выделенную как вкладку кнопку, если установлен флаг selected. + + Флаг selected устанавливается автоматически(xor пердыдущего состояния, если select_button не изменился) + + У кнопки можно настроить флаги отображения, например использовать режим вкладки или просто кнопка, + рисовать рамку окна или нет, + + ```C + typedef struct { + uint32_t flags; // 0bBX X : 0=not tab mode 1=tab mode + // B : 0=draw button border 1=not draw border + // + pgba* icon; // 18x18 pixel + uint32_t callback_data; + void* button_click; //void __stdcall button_click(uint32_t callback_data,uint8_t mouse_key); + }button_item; + + typedef struct { + uint8_t flags; // 0bSV S : 1=selected 0 - not selected + // V : 1=visible 0 - unvisible + uint8_t count_left; + uint8_t count_right; + uint8_t select_button; //index + button_item [] buttons; + }button_panel; + + + void __stdcall update_button_panel(button_panel* ptr); + + button_panel* __stdcall get_button_panel(); + ``` + + ### Работа с меню выбора функции(небольшой список слева с кнопочками, для выбора содержимого рабочей области) + + Работа с этим меню схожа с работой над остальными панелями. Модуль должен предоставить программе структуру содержащую описание кнопок интерфейса. + + Так как я ленивый и считаю что интерфейс должен быть попроще, то никакой прокрутки нету, так что много кнопок размещать не надо. + + Из предыдущего тезиса также вытекает отсутствие возможности создания кастомного такого поля. Ну нельзя будет добавить в панель строку поиска + или там иерархическую структуру, это же не особо то и нужно. + + Если имеются кнопки в режиме вкладки, то фокус устанавливается на первую попавшуюся или же на выбранную при обновлениии структуры. + При нажатии на кнопку без режима вкладки выбранный элемент не переключается + + Если нажата кнопка в режиме вкладки, то фокус меняется на неё. Отключить фокус невозможно, разве что только использовать обычные кнопки. + + ```C + typedef struct { + uint16_t flags; // 0bBX X : 0=not tab mode 1=tab mode + // B : 0=draw button border 1=not draw border + // + uint16_t height; // 0=default + pgba* icon; // 18x18 pixel + char* text; + uint32_t callback_data; + void* item_click; //void __stdcall item_click(uint32_t callback_data,uint8_t mouse_key); + }menu_item; + + typedef struct { + uint8_t flags; // 0bV V : 1=visible 0 - unvisible + uint8_t count_item; + uint8_t selected_button; //index + menu_item [] buttons; + }menu_panel; + + void __stdcall update_menu_panel(menu_panel* ptr); + + menu_panel* __stdcall get_menu_panel(); + ``` + + ### Работа с панелью вкладок + + Работа с панелью вкладок простая и не затейливая: Пользователь нажимает на вкладку - код получает вызов callback функции. + Поле selected_tab заполнается автоматически. + + Вызовв функции update_tab_panel приводит к перерисовке области вкладок (и удалению или добавлению нужных системных кнопок). + При этом, если selected_tab выходит за границы(больше или равно count_tab), то selected_tab = 0. + + + typedef struct { + rgba* icon; //18x18 or 12x12 + char* text; + uint32_t callback_data; + void* tab_click; //void __stdcall tab_click(uint32_t callback_data,uint8_t mouse_key); + }tab_item; + + typedef struct { + uint16_t flags; // 0bV V : 1=visible 0 - unvisible + uint8_t count_tab; + uint8_t selected_tab; //index + tab_item [] buttons; + }tab_panel; + + void __stdcall update_tab_panel(tab_panel* ptr); + + tab_panel* __stdcall get_tab_panel(); + + + + + + ### Вид интерфеййса +``` ++-----------------------------------------------------------------------------+ +| Table 1.2 | _ | x | +|-----------------------------------------------------------------------------+ +||[ ]\ [ ] [ ] [ ] Панель функций [ ] | +||[__] \[__] [__] [__] [__] | +||---------------------------------------------------------------------------+| +|| || +|| || +|| || +|| Рабочая область || +|| || +|| || +|| || +|| || +|| || +|| || +|| || +|| || +|| || +||___________________________________________________________________________|| +||____________/+/ | <- Панель вкладок ++-----------------------------------------------------------------------------+ + + ++-----------------------------------------------------------------------------+ +| Table 1.2 | _ | x | +|-----------------------------------------------------------------------------+ +||[ ]\ [ ] [ ] [ ] Панель функций [ ] | +||[__] \[__] [__] [__] [__] | +||---------------------------------------------------------------------------+| +|| | || +|| | || +|| | || +|| | Рабочая область || +|| | || +|| | || +|| | || +|| меню | || +|| выбора | || +|| | || +|| | || +|| | || +|| | || +||________________|__________________________________________________________|| ++-----------------------------------------------------------------------------+ +``` \ No newline at end of file diff --git a/doc.html b/doc.html new file mode 100644 index 0000000..b2ba6b0 --- /dev/null +++ b/doc.html @@ -0,0 +1,37 @@ +Общее описание системы модулей: +Система модулей представляет из себя файл конфигурации и некоторое количество DLL библиотек. + + +Модули форматов: +Данные модули необходимы для поддержки работы с внешними форматами табличных документов, например +для работы с документами в формате xlsx. + +Таблица экспорта функций: +список форматов, функция загрузки, вункция выгрузки, ? +0 + +Модули формул: +Данные модули предназначены для расширения возможностей формульного движка. +Основная идея заключается в экспорте модулем функций обработки данных таблицы. +Для описания параметров функций предполагается использовать дполнение к имени +Например: sum$d$ed +, где sum - название функции + $d - описание типа возвращаемого значения + $ed - описание типа аргумента или агрументов + +Для хорошего описания функций планируется использовать следующии символы: + d - (double) Числовое или булевое значение + s - Строковое значение, строка кодируется в UTF-8 + t - (date and time) Значение времени + i - (image) Значение представляющее собой 32 битное RAW изображение с + указанием размера и выравнивания линий. Может быть использовано + для вывода графика, но это не точно. + + + uint32_t tmodule_init(char* cmdline); + import_format_t* tmodule_get_formats(uint32_t pdata); + import_formula_t* tmodule_get_formulas(uint32_t pdata); + void tmodule_exit(uint32_t pdata) + + + diff --git a/draw_data.c b/draw_data.c new file mode 100644 index 0000000..679046f --- /dev/null +++ b/draw_data.c @@ -0,0 +1,8 @@ +/* +Для отображения неизвестного формата файлов необхдим модуль, преобразующий +эти данные в битмап. Для более точного создания данного изображения +в функцию передаются размеры области отображения. В целях упрощения, +буфер для битмапа передаётся вызывающей стороной, для уменьшения аллокаций +памяти. + +*/ \ No newline at end of file diff --git a/formats.c b/formats.c new file mode 100644 index 0000000..52a9007 --- /dev/null +++ b/formats.c @@ -0,0 +1,41 @@ +/* +Файл - Реализация загрузки моделей форматов и вызова функций из этих мдулей. + +Краткое описание системы модулей форматов. + Модули форматов представляют из себя днамическую библиотеку, +имеющую специальную функцию экспорта таблицы функций для загрузки и +выгрузки таблиц во внешние форматы. + +Запись о функциях представлет из себя небольшую структуру, содержащую +указатели на функции загрузки и сохранения модели табличного докуента, +указатель на массив, ассоциированных с данным форматом расширений, и +указатель на описание дополнительных параметров + +Описание формата дополнительных параметров: + +Как вариант можно сделать json или xml описание. +TODO!!! + +cvs: + load_cvs + save_cvs + & dd 4, 'cvs',0 + & '{"-export":["raw","result"]}',0 + + + +#include "modules.h" + + +int formats_init(module_t* this) { + // check and call 'tmodule_formulas' function + import_format_t* (*module_get_formats)(uint32_t); + module_get_formats = _ksys_dlsym(this -> dll, "tmodule_formats"); + if (!module_get_formats) return 0; + + this -> formats = module_get_formats(this -> pdata); + + return 0; +} + +*/ diff --git a/formulas.c b/formulas.c new file mode 100644 index 0000000..1e8e1a2 --- /dev/null +++ b/formulas.c @@ -0,0 +1,92 @@ +/* +Файл - Реализация загрузки модулей формул и вызова функций их этих модулей. + +Краткое описание системы модулей формул + Модели формул представляют из себя динамическую библиотеку, +имеющую специальную функцию экспорта таблицы функций для формульного +движка. + Данная Функция экспортирует в программу таблицу с указателями на +функции и наименование конкретной функции. + + Наменования функций записаны в виде UTF-8 строки заканчивающейся +нуль-терминатором. Строка не должна начинаться с символов цифр, и не +должна включать в себя следующие символы "!","<","=",">","^","(",")", +"*","&",""", управляющих ASCII символов и других служебных символов. + +Символ "$" считается разделителем между названием функции, описанием +выходных значений и описанием аргументов. + +Пример: + "sum$d$eed" + \___/| \_/ + название / | \описание аргументов функции - перечисление значений/ячеек + функции | типа double + | + Описание типа выходного значения - значение типа double + + Примером вызова данной функции может быть следующая запись: + "=sum({3,4,5,6:9},A1,A2:C4,1,2,0)" + + Типы аргументов и выходного значения имеют одинаковый вид записи, +в виде символа-обозначения типа: + d - double - Числовой и булевый тип. Булевые значения кодируются + в виде чисел, где: 1.0 соответствует значению TRUE + а 0.0 соответствет значению FALSE + s - string - Строковый тип данных, представляет из себя UTF-8 + строку завершающуюся нуль-терминатором. Кроме этого, + строки в ячейках начинающиеся с символа "=" не + подпадают под данный тип, их тип вычисляется + формульным движком. + t - time - Тип представляющий собой дату и время + i - image - Значение представляющее собой 32 битное RAW изображение + с указанием размера и выравнивания линий. Может быть + использовано для вывода графика, но это не точно. + + c - cell - Специальный тип - ячейка. Данный тип представляет собой + специальный ID, который указывает на "ячейку"(в том + числе виртуальную для константных занчений) у которой + можно узнать тип во время исполнения агоритма работы + функции. Запись в ячейки данного типа также позволяет + выбрать тип возвращаемого значения. + eX - enum - Специальный тип, представляющий из себя набор значений + типа X. Данный тип описывает перечесление значений + только в рамках одной записи, что позволяет получать + несколько таких перечеслений. + eeX - enums - Специальный тип - перечисление перечислений. Может быть + записан только один раз в конце названия. Все парамеры + которые идут далее и под этот тип будут неявно + преобразованы под тип enum. + b - button - Специальный тип - Кнопка. Данный тип нужен для создания + интерактивной кнопки, позволяющей + + +Так как у формул количество аргументов может быть достаточно большое, то в +функцию передаётся указатель на массив идентификаторов. +stdcall int (*formula)(uint32_t input_id, uint32_t* output_ids); + +*/ +#include "modules.h" + + +int formulas_init(module_t* this) { + //check and call 'tmodule_formulas' function + import_formula_t* (*module_get_formulas)(uint32_t); + module_get_formulas = _ksys_dlsym(this -> dll, "tmodule_formulas"); + if (module_get_formulas) return 0; + this -> formulas = module_get_formulas(this -> pdata); + return 0 +} + + + +/* +https://senior-sigan.notion.site/e371029e51bf4748ab04f0c904f9fc0d + +тип (*имя_указателя) (типы_параметров); +Например: +void (*message) (void); + +тип (*имя_массива[размер]) (параметры) +Например: +double (*actions[]) (int, int) +*/ \ No newline at end of file diff --git a/includes/CONFIG.H b/includes/CONFIG.H new file mode 100644 index 0000000..2eb2967 --- /dev/null +++ b/includes/CONFIG.H @@ -0,0 +1,18 @@ +#ifndef CONFIG_H +#define CONFIG_H + +typedef struct config_data_t { + const char* config_path; + char* modules_dir; + char* doc_formulas; + char* doc_graph; + char* doc_hotkeys; + char* doc_module_api; + + +} config_data_t; + +extern config_data_t config_data; + +extern int config_load(const char* path); +#endif \ No newline at end of file diff --git a/includes/GRID.H b/includes/GRID.H new file mode 100644 index 0000000..75c3ced --- /dev/null +++ b/includes/GRID.H @@ -0,0 +1,157 @@ +#ifndef GRID_H +#define GRID_H + +#include +// flags +#define GRID_FLAG_NO_HEADER_ROW 0b1 // для использования для списков например +#define GRID_FLAG_NO_HEADER_COL 0b10 // для использования для списков например +#define GRID_FLAG_NO_SCROLL 0b100 // для использования там где данных излишне много +#define GRID_FLAG_CLEAN_MODE 0b1000 // без вывода сетки, например для печати +#define GRID_FLAG_EDIT_DATA 0x80000000 // Выставляется для вывода editbox + +// border_type_ - Описание формата каждой линии границы +//#define GRID_BORDER_TYPE_NORMAL 0b0 // 0000 - default full line +//#define GRID_BORDER_TYPE_HATCHING_FREQUENT 0b1 // 0001 - штриховка, частая +//#define GRID_BORDER_TYPE_HATCHING_MEDIUM 0b10 // 0010 - штрифовка, средняя +//#define GRID_BORDER_TYPE_HATCHING_RARE 0b11 // 0011 - штриховка, редкая +//#define GRID_BORDER_TYPE_CORNERS 0b100 // 0100 - углы + +#define GRID_BORDER_TYPE_PATTERN 0b1000 +#define GRID_BORDER_TYPE_PATTERN_BEGIN_0 0b1001 +#define GRID_BORDER_TYPE_PATTERN_BEGIN_1 0b1101 +#define GRID_BORDER_TYPE_PATTERN_END_0 0b1011 +#define GRID_BORDER_TYPE_PATTERN_END_1 0b1111 + +// расчитываются от внешних границ ячейки +#define GRID_BORDER_BITMASK_LINE1 0b0001 +#define GRID_BORDER_BITMASK_LINE2 0b0010 +#define GRID_BORDER_BITMASK_LINE3 0b0100 +#define GRID_BORDER_BITMASK_LINE4 0b1000 + +// text align - составная переменная +#define GRID_TEXT_ALIGN_LEFT 0b00 +#define GRID_TEXT_ALIGN_CENTER 0b10 +#define GRID_TEXT_ALIGN_RIGHT 0b01 + +#define GRID_TEXT_ALIGN_TOP 0b0000 +#define GRID_TEXT_ALIGN_MEDIUM 0b1000 +#define GRID_TEXT_ALIGN_BOTTOM 0b0100 + +#define GRID_TEXT_STYLE_NORMAL 0b000000 + + +#define GRID_WIDTH_DEFAUT 0 +#define GRID_HEIDHT_DEFAULT 0 + +#define TABLE_CELL_DEFAULT_WIDTH 81 +#define TABLE_CELL_DEFAULT_HEIGHT 21 + +#define GRID_VALUE_TYPE_TEXT 0 +#define GRID_VALUE_TYPE_IMAGE 1 + +typedef struct GRID_BORDER_LINE_FORMAT { + uint8_t format; + uint8_t pattern; // bitmask +}GRID_BORDER_LINE_FORMAT; + +typedef struct GRID_BORDER_FORMAT { + GRID_BORDER_LINE_FORMAT line [4]; + ksys_color_t color; +}GRID_BORDER_FORMAT; + +typedef struct GRID_CELL_FORMAT { + uint32_t width; + uint32_t height; + ksys_color_t bg_color; + ksys_color_t text_color; + uint64_t text_params; + GRID_BORDER_FORMAT border_l; + GRID_BORDER_FORMAT border_r; + GRID_BORDER_FORMAT border_t; + GRID_BORDER_FORMAT border_b; + union { + uint64_t border_bitmask; + struct { + uint8_t border_bitmask_l; + uint8_t border_bitmask_r; + uint8_t border_bitmask_t; + uint8_t border_bitmask_b; + }; + }; +} GRID_CELL_FORMAT; + +typedef struct GRID_CELL_CONTENT { + uint32_t type; + uint32_t size_data; +} GRID_CELL_CONTENT; + +typedef struct GRID_CELL_CONTENT_TEXT { + GRID_CELL_CONTENT type; + char text; +} GRID_CELL_CONTENT_TEXT; + +typedef struct GRID_CELL_CONTENT_IMAGE { + GRID_CELL_CONTENT type; + uint32_t width; + uint32_t height; + ksys_color_t image; +} GRID_CELL_CONTENT_IMAGE; + +typedef struct GRID { + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; + + uint32_t flags; + uint32_t pdata; //for callback functions + + uint32_t grid_color; + + uint32_t content_pos_col; // позиция первой верхней левой ячейки + uint32_t content_pos_row; // если есть заголовок строки/столбца + // то 1..max + // это диапазон выделенных значений - жирная оконтовка вокруг диапазона + uint32_t selected_cell_col; + uint32_t selected_cell_row; + uint32_t selected_cell_w; + uint32_t selected_cell_h; + // чтобы знать куда edit_box рисовать + uint32_t current_cell_x; + uint32_t current_cell_y; + uint32_t current_cell_w; + uint32_t current_cell_h; + //calbacks + void __stdcall (*get_cell_format)(struct GRID* this, GRID_CELL_FORMAT* buff, uint32_t col, uint32_t row); // получить формат ячейки + table_object* __stdcall (*get_cell_value)(struct GRID* this, uint32_t col, uint32_t row); // получить данные для вывода в обычном режиме + void __stdcall (*free_cell_value)(struct GRID* this, table_object* buff); + void __stdcall (*event_cell_mouse)(struct GRID* this, uint32_t col, uint32_t row); + void __stdcall (*event_cell_key)(struct GRID* this, uint32_t col, uint32_t row, ksys_oskey_t ch); + // callbacks for draw + void __stdcall (*draw_text)(struct GRID* this, uint32_t x, uint32_t y, uint32_t w, uint32_t h, char* text, uint64_t text_params); + void __stdcall (*draw_image)(struct GRID* this, uint32_t x, uint32_t y, uint32_t w, uint32_t h, ksys_color_t* data); + void __stdcall (*draw_bar)(struct GRID* this, uint32_t x, uint32_t y, uint32_t w, uint32_t h, ksys_color_t color); + //other items of grid + scrollbar scroll_row; + scrollbar scroll_col; + +} GRID; + +typedef struct GRID_NOSTD_CELL { + GRID* rthis; + GRID_CELL_FORMAT format; + uint32_t col; + uint32_t row; + uint32_t x; + uint32_t y; + uint32_t fix_width; + uint32_t fix_height; +} GRID_NOSTD_CELL; + +extern void draw_grid(GRID* this); + +extern void grid_mouse(GRID* this); + +extern void grid_key(GRID* this, ksys_oskey_t ch); + +#endif \ No newline at end of file diff --git a/includes/MODULES.H b/includes/MODULES.H new file mode 100644 index 0000000..4afef5d --- /dev/null +++ b/includes/MODULES.H @@ -0,0 +1,43 @@ +#ifndef MODULES_H +#define MODULES_H + +#include "formulas.h" +#include "formats.h" + + +/* +㫨 㦠 table_lib ᠬ +㫨 ଠ⮢ ᯫ ⮫쪮 ⥪, ᯮ 㦥 +㫨 ᯮ ᯮ ਫ +(ਬ, ࠡ⪥ ᫥ ) +*/ +typedef struct { + uint32_t version; + // functions for formulas + int (*get_obj_str)(); +} table_exports_t; + + +typedef struct module_t { + struct module_t* next; + uint32_t flags; // bitflag 0 - not using this module; 1 - using + ksys_dll_t* dll; + uint32_t pdata; // module context + + import_format_t* formats; + import_formula_t* formulas; + // callbacks + uint32_t __stdcall (*fn_init)(table_exports_t*, char*, char*); + void __stdcall (*fn_close)(uint32_t); + char namespace [64]; + char* dll_path; +} module_t; + +#define MODULE_FLAG_EMMBEDED 0x80000000 +#define MODULE_FLAG_BLOCKED 0x00000001 + + +extern int module_init(char* dll_name, char* cmdline, char* namespace); +extern void modules_exit(); + +#endif \ No newline at end of file diff --git a/includes/SYSTEM/GUI.H b/includes/SYSTEM/GUI.H new file mode 100644 index 0000000..1ec9d04 --- /dev/null +++ b/includes/SYSTEM/GUI.H @@ -0,0 +1,8 @@ +#ifndef SYSTEM_GUI_H +#define SYSTEM_GUI_H + +extern void write_text_utf8_center(uint32_t x, uint32_t y, int32_t w, const char* text, int32_t SSS); + +extern void gui_draw_button_icon18(uint32_t button_id, uint16_t x, uint16_t y, uint32_t id_icon, int pressed); + +#endif diff --git a/includes/SYSTEM/LIBINI.H b/includes/SYSTEM/LIBINI.H new file mode 100644 index 0000000..b45f6bf --- /dev/null +++ b/includes/SYSTEM/LIBINI.H @@ -0,0 +1,24 @@ +#ifndef KOLIBRI_LIBINI_H +#define KOLIBRI_LIBINI_H + +#include +#include + +#define INI_OK 0 +#define INI_ERROR -1 +#define INI_SECTION_NOT_FOUND 1 + +#define INI_MAX_NAME_LEN 1024 +#define INI_VALUE_LEN 4096 + +DLLAPI int __stdcall ini_enum_section(const char* f_name, void (__stdcall *callback)(char*, char*)); +DLLAPI int __stdcall ini_enum_keys(const char* f_name, const char* sec_name, int (__stdcall *callback)(char*, char*, char*, char*)); +DLLAPI int __stdcall ini_get_str(const char* f_name, const char* sec_name, const char* key_name, char* buff, uint32_t len, char* def_val); +DLLAPI int32_t __stdcall ini_get_int(const char* f_name, const char* sec_name, const char* key_name, int32_t def_val); +DLLAPI ksys_color_t __stdcall ini_get_color(const char* f_name, const char* sec_name, const char* key_name, ksys_color_t def_val); +DLLAPI int __stdcall ini_set_str(const char* f_name, const char* sec_name, const char* key_name, char* buff, uint32_t len); +DLLAPI int __stdcall ini_set_int(const char* f_name, const char* sec_name, const char* key_name, int32_t val); +DLLAPI int __stdcall ini_set_color(const char* f_name, const char* sec_name, const char* key_name, ksys_color_t val); +DLLAPI int __stdcall ini_del_section(const char* f_name, const char* sec_name); + +#endif \ No newline at end of file diff --git a/includes/SYSTEM/PROC_LIB.H b/includes/SYSTEM/PROC_LIB.H new file mode 100644 index 0000000..0a54b96 --- /dev/null +++ b/includes/SYSTEM/PROC_LIB.H @@ -0,0 +1,43 @@ +#ifndef SYSTEM_PROC_LIB_H +#define SYSTEM_PROC_LIB_H + +#define PROC_LIB_NOT_SUCCESS 0 +#define PROC_LIB_SUCCESS 1 + +enum open_dialog_mode { + PROC_LIB_OPEN, + PROC_LIB_SAVE, + PROC_LIB_SELECT +}; + +typedef struct { + unsigned int size; + unsigned char end; +} od_filter __attribute__((__packed__)); + +typedef struct { + unsigned int mode; + char* procinfo; + char* com_area_name; + unsigned int com_area; + char* opendir_path; + char* dir_default_path; + char* start_path; + void (*draw_window)(); + unsigned int status; + char* openfile_path; + char* filename_area; + od_filter* filter_area; + unsigned short x_size; + unsigned short x_start; + unsigned short y_size; + unsigned short y_start; +} open_dialog __attribute__((__packed__)); + +extern open_dialog* kolibri_new_open_dialog(unsigned int mode, unsigned short tlx, unsigned short tly, unsigned short x_size, unsigned short y_size); + + +DLLAPI void __stdcall OpenDialog_init(open_dialog*); +DLLAPI void __stdcall OpenDialog_start(open_dialog*); + +#endif \ No newline at end of file diff --git a/includes/SYSTEM/UTF8.H b/includes/SYSTEM/UTF8.H new file mode 100644 index 0000000..6cd750c --- /dev/null +++ b/includes/SYSTEM/UTF8.H @@ -0,0 +1,6 @@ +#ifndef SYSTEM_UTF8_H +#define SYSTEM_UTF8_H + +size_t utf8len(const char* s); + +#endif \ No newline at end of file diff --git a/includes/WINDOW.H b/includes/WINDOW.H new file mode 100644 index 0000000..ce62cd6 --- /dev/null +++ b/includes/WINDOW.H @@ -0,0 +1,67 @@ +#ifndef WINDOW_H +#define WINDOW_H + +#include + +extern ksys_colors_table_t color_table; //for all graphic functions +extern void draw_window(); +extern bool window_event_key(ksys_oskey_t key); +extern bool window_event_mouse(); +extern bool window_event_button(uint32_t pressed_button); + +#define MIN_WIDTH 430 +#define MIN_HEIGHT 250 + +// initial window sizes +#define WND_W 718 +#define WND_H 505 //без высоты заголовка + +#define MENU_PANEL_HEIGHT 40 + +enum BUTTONS // Кнопки в интрефейсе +{ + BTN_QUIT=1, //Выход + + BTN_OTHER = 100, + BTN_NEW = 101, //Новый + BTN_LOAD = 102, //Загрузить + BTN_SAVE = 103, //Сохранить + BTN_SAVE_AS = 104, + BTN_ABOUT = 105, + + BTN_ABOUT_FORMULS = 106, // Юзер мануал, описание использования формул + BTN_ABOUT_GRAPH = 107, // Юзер мануал, описание генерации графиков + BTN_ABOUT_HOTKEYS = 108, // Юзер мануал, описание комбинаций клавишь + BTN_ABOUT_DEVS = 109, // мануал разработчикам модулей + + BTN_OTHER_INFO = 110, + BTN_OTHER_GRAPH = 111, + BTN_OTHER_PRINT = 112, + BTN_OTHER_SETTING = 113, + + BTN_OTHER_GRAPH_CREATE = 114, + BTN_OTHER_GRAPH_ADD = 115, + BTN_OTHER_GRAPH_DEL = 116, + + BTN_OTHER_SETTING_OPEN_CONFIG = 117 +}; + +enum SCREEN_MODE { + SCREEN_BASE = 0, // full + SCREEN_ABOUT = 0x40,// no mouse event, key event for esc + SCREEN_INFO = 0x80, //no mouse event, key event for esc + SCREEN_GRAPH = 0x81, // full + SCREEN_PRINT = 0x82, // full or no mouse + SCREEN_SETTING = 0x83, // full or no mouse +}; + +#define SCREEN_ALL_TABS (SCREEN_ABOUT | SCREEN_INFO ) + +extern uint32_t selected_screen; + +extern char* sys_open_app; +extern char* sys_notify_app; +#define run_file(path) _ksys_exec(sys_open_app, path) +#define notify(path) _ksys_exec(sys_notify_app, path) + +#endif \ No newline at end of file diff --git a/includes/formats.h b/includes/formats.h new file mode 100644 index 0000000..d6dc8e9 --- /dev/null +++ b/includes/formats.h @@ -0,0 +1,15 @@ +#ifndef FORMATS_H +#define FORMATS_H + +#include "table_lib.h" + +typedef struct import_format_t { + int (*load)(uint32_t, char*, table_dom_t**, char*); + int (*save)(uint32_t, char*, table_dom_t**, char*);// pdata, path, table_dom, params + void* assoc; + char* params; +} import_format_t; + + + +#endif \ No newline at end of file diff --git a/includes/formulas.h b/includes/formulas.h new file mode 100644 index 0000000..ce9f690 --- /dev/null +++ b/includes/formulas.h @@ -0,0 +1,9 @@ +#ifndef FORMULAS_H +#define FORMULAS_H + +typedef struct import_formula_t { + int (*callfunc)(uint32_t, uint32_t, uint32_t*);//pdata, return id, array of args id + char* name; +}import_formula_t; + +#endif \ No newline at end of file diff --git a/includes/table_lib.h b/includes/table_lib.h new file mode 100644 index 0000000..d0dfc45 --- /dev/null +++ b/includes/table_lib.h @@ -0,0 +1,63 @@ +#ifndef TABLE_LIB_H +#define TABLE_LIB_H + +#include + +#define table_dom_t uint32_t + +#define TABLE_DIR_TYPE_DATA 0x1 +#define TABLE_DIR_TYPE_FORMAT 0x2 + +#define TABLE_OBJECT_TYPE_STR 0x01 +#define TABLE_OBJECT_TYPE_IMAGE 0x05 +#define TABLE_OBJECT_TYPE_NULL 0x00 + +typedef struct table_object { + uint8_t type; + uint16_t size; + uint8_t ext_size; +} table_object; + +typedef struct table_object_str { + uint8_t type; + uint16_t size; + uint8_t __zero; + uint16_t str_len; + char str; + +} table_object_str; + +typedef struct table_object_image { + uint8_t type; + uint16_t size; + uint8_t __zero; + uint16_t width; + uint16_t height; + uint32_t data; + +} table_object_image; + +typedef union table_addr{ + struct { + uint32_t lo; + uint32_t hi; + }; + struct { + uint16_t type; + uint8_t index_w [3]; + uint8_t index_h [3]; + }; +}table_addr; + +/* +DLLAPI int __stdcall create_table_dom(table_dot_t* ptr); +DLLAPI void __stdcall destruct_table_dom(table_dom_t ptr); + +DLLAPI table_object* __stdcall get_table_value(table_dom_t ptr, table_addr* addr); +DLLAPI int __stdcall set_table_value(table_dom_t ptr, table_addr* addr,table_object* tobj); +*/ + +DLLAPI table_object* __stdcall create_table_object(uint32_t size); +DLLAPI void __stdcall destruct_table_object(table_object* ptr); + +#endif \ No newline at end of file diff --git a/modules/CSV.C b/modules/CSV.C new file mode 100644 index 0000000..e69de29 diff --git a/modules/DISPLAY b/modules/DISPLAY new file mode 100644 index 0000000..a889330 Binary files /dev/null and b/modules/DISPLAY differ diff --git a/modules/DISPLAY.ASM b/modules/DISPLAY.ASM new file mode 100644 index 0000000..99b8b0b --- /dev/null +++ b/modules/DISPLAY.ASM @@ -0,0 +1,195 @@ +; +; Тестовый модуль для вывода на "дисплей" + +format MS COFF +public @EXPORT as 'EXPORTS' + +include "macros.inc" +;include "proc32.inc" + +include "modules_api.inc" + +struct MODULE_CONTEXT + display_buff dd ? + rb 64 - 4 + namespace rb 64 + cmdline rb 64 +ends + +section 'Doczom' code readable align 16 + +; Public functions + +; IN: [esp + 4] = imports +; [esp + 8] -> cmdline +; [esp + 12] -> namespace +; OUT: eax - pdata +init: + push esi edi ebx ebp + ; load table_lib.obj + ;int3 + ; table_exports_t + mov ecx, sizeof.table_exports_t/4 + mov edi, IMPORT_DATA + mov esi, [esp + 4*4 + 4] + rep movsd + ; alloc context + mcall 68, 12, sizeof.MODULE_CONTEXT + test eax, eax + jz .err_mem + mov ebp, eax + ; find display_d demon + mcall 68, 22, SHARED_NAME, 16*2, 1 + test eax, eax + jnz @f ; error open display + + mcall 68, 13, ebp + xor eax, eax + jmp .err_mem +@@: + mov [ebp + MODULE_CONTEXT.display_buff], eax + + ; copy namespace + mov esi, [esp + 4*4 + 12] + lea edi, [ebp + MODULE_CONTEXT.namespace] +@@: + movsb + cmp byte[edi - 1], 0 + jnz @b + ; copy cmdline + mov dword[ebp + MODULE_CONTEXT.cmdline],0 + cmp dword[esp + 4*4 + 8], 0 + jz .exit + + mov esi, [esp + 4*4 + 8] + lea edi, [ebp + MODULE_CONTEXT.cmdline] +@@: + movsb + cmp byte[edi - 1], 0 + jnz @b + + lea esi, [ebp + MODULE_CONTEXT.cmdline] + mov edi, [ebp + MODULE_CONTEXT.display_buff] + mov eax, ' ' + mov ecx, 8 + rep stosd + mov edi, [ebp + MODULE_CONTEXT.display_buff] + xor ecx, ecx +@@: + cmp byte[esi], 0 + je @f + movsb + jmp @b +@@: +.exit: + mov eax, ebp +.err_mem: + pop ebp ebx edi esi + ret 12 +; IN: [esp + 4] = pdata +close: + push ebx + ; free context + mcall 68, 13, [esp + 4 + 4] + pop ebx + ret 4 +; IN: [esp + 4] = pdata +; OUT: eax = import_formula_t* +formulas: + ;int3 + mov eax, formulas_list + ret 4 + +; IN: [esp + 4] = pdata +; OUT: eax = import_format_t* +formats: + ;int3 + mov eax, formats_list + ret 4 + +; IN: [esp + 4] = pdata +; [esp + 8] = id output +; [esp + 12] = ptr array is inputs +; OUT: eax = error code: 0 - good +; -1 - unknow error +display_out_num: + + ret 12 +; IN: [esp + 4] = pdata +; [esp + 8] = id output +; [esp + 12] = ptr array is inputs +; OUT: eax = error code: 0 - good +; -1 - unknow error +display_out_str: + + ret 12 + +; IN: [esp + 4] = pdata +; [esp + 8] = path to file +; [esp + 12] = table_dom* +; [esp + 16] = ptr params +; OUT: eax = error code: 0 - good +; -1 - unknow error +fdload: + ; load file + ; generate new table_dom + ret 16 + +; IN: [esp + 4] = pdata +; [esp + 8] = path to file +; [esp + 12] = table_dom* +; [esp + 16] = ptr params +; OUT: eax = error code: 0 - good +; -1 - unknow error +fdsave: + ; function not supported + or eax, -1 + ret 16 + + +; Private functions + + + +section '.data' data readable writable align 16 + +@EXPORT: +export \ + init, 'tmodule_init',\ + close, 'tmodule_close',\ + formulas, 'tmodule_formulas',\ + formats, 'tmodule_formats' + +align 16 +formulas_list: + dd display_out_num, .name_display_out_num + dd display_out_str, .name_display_out_str + dd 0, 0 +.name_display_out_num: + db 'DisplayOutNum$d$d',0 +.name_display_out_str: + db 'DisplayOutStr$d$s',0 + +align 16 +; fd- format display +formats_list: + dd fdload, fdsave, fdassocc, 0 + dd 0, 0, 0, 0 + +fdassocc: + dd .end - .start +.start: + db 'DTMODULE',0 +.end: + db 0 +;
+ +; a1 = header +; c1 = namespace.DisplayOutStr($a$1) +; a2 = input value +; c2 = namespace.DisplayOutNum($a$2) +; + +SHARED_NAME: db 'DISPLAY_16_2_D',0 + +IMPORT_DATA table_exports_t \ No newline at end of file diff --git a/modules/display_d b/modules/display_d new file mode 100644 index 0000000..d07cbe0 Binary files /dev/null and b/modules/display_d differ diff --git a/modules/display_d.asm b/modules/display_d.asm new file mode 100644 index 0000000..aa20835 --- /dev/null +++ b/modules/display_d.asm @@ -0,0 +1,83 @@ +use32 ; включить 32-битный режим ассемблера +org 0 ; адресация с нуля + db 'MENUET01' ; 8-байтный идентификатор MenuetOS + dd 1 ; версия заголовка (1 либо 2, см. док-ю) + dd START ; адрес первой команды + dd I_END ; размер программы + dd MEM ; количество памяти + dd STACKTOP ; адрес вершины стэка + dd DEF_CMDLINE ; адрес буфера для параметров + dd 0 ; под адрес на путь к файлу +include "macros.inc" +; display_d -emul +; display_d +START: + mcall 68, 11 + ; parse cmdline + cmp dword[DEF_CMDLINE], '-emu' + je start_emul + ; start demon for input in serial port + jmp exit +start_emul: + ; init shared buffer + mcall 68, 22, SHARED_NAME, 16*2, 8+1 + test edx, edx + jnz exit + test eax, eax + jz exit + mov [buff_ptr], eax + + + mcall 40, 101b ; btn + readraw +.win_draw: + mcall 12, 1 + mcall 48, 4 + mov ecx, eax + add ecx, 16*2+20 + mcall 0, 16*8+2*15, , 0x330f0f0f, 0, title; + mcall 12, 2 + +.loop: + call draw_info + mcall 23, 100 ; 1s + test eax, eax + jz .loop + + dec eax ; rdrw + jz .win_draw + + cmp eax, 3-1 ; btn + jne .loop + + mcall 17 + cmp eax, 1 + je .loop +exit: + mcall -1 + + + +draw_info: + mov edx, [buff_ptr] + mov ebx, (10 shl 16) + 10 + mcall 4, , 0x5000FFFF, , 16, 0x000000FF + + add edx, 16 + add ebx, 16 + mcall 4, , ;0x5000FFFF, , 16, 0x000000FF + ret + +title: db 3, 'Эмулятор ' +SHARED_NAME: db 'DISPLAY_16_2_D',0 +buff_ptr: dd ? + +align 16 +I_END: + +DEF_CMDLINE: + rb 256 +align 16 + rb 1024; one page +STACKTOP: +align 16 +MEM: \ No newline at end of file diff --git a/modules/display_w b/modules/display_w new file mode 100644 index 0000000..6ed175e Binary files /dev/null and b/modules/display_w differ diff --git a/modules/display_w.asm b/modules/display_w.asm new file mode 100644 index 0000000..a6a1d94 --- /dev/null +++ b/modules/display_w.asm @@ -0,0 +1,48 @@ +use32 ; 32- ० ᥬ +org 0 ; + +APP_HEADER: + db 'MENUET01' ; 8- 䨪 MenuetOS + dd 1 ; (1 2, . -) + dd START ; ࢮ + dd I_END ; ࠧ ணࠬ + dd MEM ; ⢮ + dd STACKTOP ; 設 +.cmdline: + dd DEF_CMDLINE ; ࠬ஢ + dd 0 ; 䠩 +include "macros.inc" +; display_d -emul +; display_d +START: + mcall 68, 11 + ; init shared buffer + mcall 68, 22, SHARED_NAME, 16*2, 1 + test eax, eax + jz exit + mov esi, DEF_CMDLINE + mov edi, eax + mov ecx, 16*2 +@@: + dec ecx + js exit + movsb + cmp byte[esi - 1], 0 + jne @b + mov byte[edi - 1], ' ' + jmp @b +exit: + mcall -1 + + + +SHARED_NAME: db 'DISPLAY_16_2_D',0 + +DEF_CMDLINE: + rb 256 +align 16 +I_END: + rb 1024; one page +STACKTOP: +align 16 +MEM: \ No newline at end of file diff --git a/modules/modules_api.inc b/modules/modules_api.inc new file mode 100644 index 0000000..1046df1 --- /dev/null +++ b/modules/modules_api.inc @@ -0,0 +1,14 @@ + + +;uint32_t tmodule_init(table_exports_t* imports, char* cmdline); + +;void tmodule_close(uint32_t pdata); + +;import_formula_t* tmodule_formulas(uint32_t pdata); + +;import_format_t* tmodule_formats(uint32_t pdata); + +struct table_exports_t + version dd ? + +ends diff --git a/parser.c b/parser.c new file mode 100644 index 0000000..31559d2 --- /dev/null +++ b/parser.c @@ -0,0 +1,16 @@ +/* + Этот файл используется для анализа данных в таблице и вычисления + формул, вернее для вызова функций-формул и анализа замыканий, создавая + для каждой формулы запись в раделе результатов и блокируя доступ + на время похождения одного гамильтонова пути. + */ + + +void parse_formula(){ + return ; +} + + + + + diff --git a/run_config.sh b/run_config.sh new file mode 100644 index 0000000..4f34712 --- /dev/null +++ b/run_config.sh @@ -0,0 +1,5 @@ +#SHS +cp table_lib.obj /sys/lib/table_lib.obj +waitfor +table -config /usbhd0/3/table/table.ini +exit \ No newline at end of file diff --git a/run_display.sh b/run_display.sh new file mode 100644 index 0000000..e67fcff --- /dev/null +++ b/run_display.sh @@ -0,0 +1,4 @@ +#SHS +./modules/display_d -emul +./modules/display_w +exit \ No newline at end of file diff --git a/table.c b/table.c new file mode 100644 index 0000000..44a4d6c --- /dev/null +++ b/table.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include + +#include + + +#include "system/env.h"// Временно!!! +#include "modules.h" + +#define DEFAULT_CONFIG "/sys/settings/table.ini" + +static char* env_key_config= "table_config"; + +bool table_not_saved = false; + +open_dialog* dlg_open; //для сохранить и сохранить как + +char* path_table_doc; + +table_dom_t* table_data; + +// IMPORT functions +// config.c +#include "config.h" + +// window.c +#include "window.h" + + +int main(int argc, char **argv){ + + int argv_offset = 1; + int err_code; + // load config + if (!strcmp(argv[1], "-config") && argc >= 3){ + + argv_offset = 3; + err_code = config_load(argv[2]); + // load cmdline config + if (err_code) { + // send error and return + return 0; + } + }else { + uint32_t bufflen; + // check env param + err_code = get_env_info(env_key_config, &bufflen); + if (err_code == 0) { + // get env param + char* buff = malloc(bufflen); + if (buff == 0) return 0; + err_code = get_env(env_key_config, buff, bufflen); + if (err_code) { + // send error and return + return 0; + } + // load config + err_code = config_load(buff); + if (err_code) { + // send error and return + return 0; + } + }else{ + //load default config + err_code = config_load(DEFAULT_CONFIG); + if (err_code) { + // send error and return + return 0; + } + } + } + + dlg_open = kolibri_new_open_dialog(PROC_LIB_OPEN, 10, 10, 420, 320); // create opendialog struct + dlg_open -> draw_window = &draw_window; + OpenDialog_init(dlg_open); + path_table_doc = malloc(4096); + + // check file name in cmdline + if ((argc > argv_offset) && (argc == argv_offset + 1)){ + // probe + _ksys_debug_puts("table: open \""); + _ksys_debug_puts(argv[argv_offset]); + _ksys_debug_puts("\"\n"); + // call modules for load table_dom + }else{ + // not file - new table + _ksys_debug_puts("table: not open file\n"); + // call table_lib for create default table_dom + } + + + selected_screen = SCREEN_BASE; + + _ksys_set_event_mask(KSYS_EVM_MOUSE_FILTER + + KSYS_EVM_REDRAW + + KSYS_EVM_KEY + + KSYS_EVM_BUTTON + + KSYS_EVM_MOUSE); + + bool end_loop = false; + do { + switch (_ksys_get_event()){ + case KSYS_EVENT_NONE: + break; + + case KSYS_EVENT_REDRAW: + draw_window(); + break; + + case KSYS_EVENT_MOUSE: + end_loop = window_event_mouse(); + break; + + case KSYS_EVENT_KEY: + end_loop = window_event_key(_ksys_get_key()); + break; + + case KSYS_EVENT_BUTTON: // Событие обработки кнопок + end_loop = window_event_button(_ksys_get_button());// Получение кода нажатой кнопки. + break; + } + if (end_loop && !table_not_saved) { + // check non saved file + }; + }while(!end_loop); + + modules_exit(); + return 0; +} diff --git a/table_lib.c b/table_lib.c new file mode 100644 index 0000000..33897cc --- /dev/null +++ b/table_lib.c @@ -0,0 +1,17 @@ + +#include "table_lib.h" + +void create_default_table_lib(){ + // create table_dom + + // set default bg + + // set default + + // + return ; +} + + + + diff --git a/table_lib.obj b/table_lib.obj new file mode 100644 index 0000000..4798c14 Binary files /dev/null and b/table_lib.obj differ diff --git a/window.c b/window.c new file mode 100644 index 0000000..f54235f --- /dev/null +++ b/window.c @@ -0,0 +1,611 @@ +#include +#include +#include +#include +#include +#include "system/gui.h" + +#include "window.h" +#include "config.h" +#include "table_lib.h" +#include "grid.h" + +extern open_dialog* dlg_open; +extern char* path_table_doc; + +static char* sys_open_app = "/sys/@open"; +static char* sys_notify_app = "/sys/@notify"; + +static ksys_thread_t procinfo; +static uint32_t old_header_h ; + +uint32_t selected_screen ; + +// new window size and coordinates +static int cWidth; +static int cHeight; + +edit_box editbox_cell = { + .width = 0, + .left = 0, + .top = 0, + .color = 0xFFFFFF, + .shift_color = 0x6a9480, + .focus_border_color = 0, + .blur_border_color = 0x6a9480, + .text_color = 0x10000000, //BLACK | TEXT_SIZE, + .max = 0, //ED_BUFF_LEN, + .text = NULL, //ed_buff, + .mouse_variable = NULL, + .flags = ed_focus +}; + +ksys_colors_table_t color_table; //for all graphic functions + + +extern void __stdcall num2cell_num(uint32_t num, char* buff); + +// Обработка данных ячеек таблицы для грида +void __stdcall table_grid_cell_format(struct GRID* this, GRID_CELL_FORMAT* buff, uint32_t col, uint32_t row){ + // call table_lib get_value + if (false) { // Если формат ячейки найден в таблице + // copy data + //memmove(buff, ,sizeof(GRID_CELL_FORMAT)); + }else { + if (false) { // Если для строки найден формат + + }else { + buff -> height = TABLE_CELL_DEFAULT_HEIGHT; + }; + + if (false) { // Если для столбца найден формат + + }else { + buff -> width = TABLE_CELL_DEFAULT_WIDTH; + } + + if (col == 0 || row == 0) { + buff -> bg_color = color_table.grab_bar_button; + buff -> text_color = color_table.work_text; + }else { + buff -> bg_color = 0xFFFFFF; + buff -> text_color = color_table.work_text; + } + buff -> text_params = GRID_TEXT_ALIGN_LEFT; + buff -> border_bitmask = 0; + + // test + if (col == 2 && row == 2) { + buff -> bg_color = 0xFFFF; + buff -> text_color = 0; + buff -> height = 48; + buff -> width = 120; + } + + }; + if ((row == 0 && this -> selected_cell_col <= col && + this -> selected_cell_w + this -> selected_cell_col > col) || + (col == 0 && this -> selected_cell_row <= row && + row < this -> selected_cell_h + this -> selected_cell_row)){ + buff -> bg_color -= 0x00252525; + } + + if (col == this -> selected_cell_col && row == this -> selected_cell_row){ + buff -> border_bitmask = 0x03030F03; + buff -> border_l.color = 0; + buff -> border_l.line[0].format = GRID_BORDER_TYPE_PATTERN; + buff -> border_l.line[0].pattern = 0xFF; + buff -> border_l.line[1].format = GRID_BORDER_TYPE_PATTERN; + buff -> border_l.line[1].pattern = 0xFF; + + buff -> border_r.color = 0; + buff -> border_r.line[0].format = GRID_BORDER_TYPE_PATTERN_END_1; + buff -> border_r.line[0].pattern = 0b11110111; + buff -> border_r.line[1].format = GRID_BORDER_TYPE_PATTERN_END_1; + buff -> border_r.line[1].pattern = 0b11110111; + buff -> border_r.line[2].format = GRID_BORDER_TYPE_PATTERN_END_0; + buff -> border_r.line[2].pattern = 0b11110000; + buff -> border_r.line[3].format = GRID_BORDER_TYPE_PATTERN_END_0; + buff -> border_r.line[3].pattern = 0b11110000;; + + buff -> border_t.color = 0; + buff -> border_t.line[0].format = GRID_BORDER_TYPE_PATTERN; + buff -> border_t.line[0].pattern = 0xFF; + buff -> border_t.line[1].format = GRID_BORDER_TYPE_PATTERN; + buff -> border_t.line[1].pattern = 0xFF; + + buff -> border_b.color = 0; + buff -> border_b.line[0].format = GRID_BORDER_TYPE_PATTERN_END_1; + buff -> border_b.line[0].pattern = 0b11110111; + buff -> border_b.line[1].format = GRID_BORDER_TYPE_PATTERN_END_1; + buff -> border_b.line[1].pattern = 0b11110111; + + } + + // destruct table_object + return ; +} + +table_object* __stdcall table_grid_cell_value(struct GRID* this, uint32_t col, uint32_t row){ + + table_object* buff = 0; + + char grid_line_text [12]; + memset(grid_line_text, '\0', 12); + + // call table_lib get_value + + if (buff == 0){ + + buff = create_table_object(4+2+12); + buff -> type = TABLE_OBJECT_TYPE_STR; + buff -> size = 4+2+12; + ((table_object_str*)buff) -> str_len = 12; + + if (row == 0 && col>0){ + num2cell_num(col ,grid_line_text); + memcpy( &(((table_object_str*)buff) -> str), grid_line_text, 12); + } + if (col == 0 && row > 0){ + memset(grid_line_text, '\0', 12); + itoa(row ,grid_line_text); + memcpy(&(((table_object_str*)buff) -> str), grid_line_text, 12); + } + if (col == 1 && row == 1) + memcpy(&(((table_object_str*)buff) -> str), " test 2 ", 12); + if (col == 3 && row == 11) + memcpy(&(((table_object_str*)buff) -> str), "123", 12); + return buff; + } + + // check formula + return buff; + +}; + +void __stdcall table_free_cell_value(struct GRID* this, table_object* buff){ + destruct_table_object(buff); + return; +} + +void __stdcall table_grid_cell_mouse(struct GRID* this, uint32_t col, uint32_t row){ + + return; +} + +void __stdcall table_grid_cell_key(struct GRID* this, uint32_t col, uint32_t row, ksys_oskey_t ch){ + if (ch.ctrl_key == KSYS_SCANCODE_ENTER) { + this -> flags = this -> flags ^ GRID_FLAG_EDIT_DATA; + + editbox_cell.left = this -> current_cell_x; + editbox_cell.top = this -> current_cell_y; + editbox_cell.width = this -> current_cell_w; + }; + + return; +} + + +// callbacks for draw grid data + +void __stdcall table_grid_draw_text(struct GRID* this, uint32_t x, uint32_t y, uint32_t w, uint32_t h, char* text, uint64_t text_params){ + write_text_utf8_center(x, y, w, text, 0); + return; +} + + +void __stdcall table_grid_draw_image(struct GRID* this, uint32_t x, uint32_t y, uint32_t w, uint32_t h, ksys_color_t* data){ + ksys_draw_bitmap_palette(data, x, y, w, h, 32, NULL, 0); + return; +} + +void __stdcall table_grid_draw_bar(struct GRID* this, uint32_t x, uint32_t y, uint32_t w, uint32_t h, ksys_color_t color){ + _ksys_draw_bar(x, y, w, h, color); + return; +} + +static GRID table_grid = { + .flags = 0, + .content_pos_col = 1, + .content_pos_row = 1, + + .selected_cell_col = 1, + .selected_cell_row = 1, + .selected_cell_w = 1, + .selected_cell_h = 1, + + .current_cell_x = 0, + .current_cell_y = 0, + .current_cell_w = 0, + .current_cell_h = 0, + + .get_cell_format = &table_grid_cell_format, + .get_cell_value = &table_grid_cell_value, + .event_cell_mouse = &table_grid_cell_mouse, + .free_cell_value = &table_free_cell_value, + .event_cell_key = &table_grid_cell_key, + + .draw_text = table_grid_draw_text, + .draw_bar = &table_grid_draw_bar, + .draw_image = &table_grid_draw_image +}; + + +// ОТРИСОВКА ОКНА + +void draw_main_window(){ + draw_grid(&table_grid); + + if (table_grid.flags & GRID_FLAG_EDIT_DATA) + // draw editbox + edit_box_draw(&editbox_cell); + return; +} + + +void draw_menu_bar(){ + _ksys_draw_line((procinfo.clientwidth-1)/4, MENU_PANEL_HEIGHT, + (procinfo.clientwidth-1)/4 , procinfo.clientheight-1, color_table.work_graph); + // draw background and borders + _ksys_draw_bar(1, MENU_PANEL_HEIGHT + 1, + (procinfo.clientwidth-1)/4 -1, procinfo.clientheight - MENU_PANEL_HEIGHT-2, + color_table.work_area); + switch (selected_screen) { + case SCREEN_INFO: + _ksys_draw_bar(1, MENU_PANEL_HEIGHT + 20*3 , + (procinfo.clientwidth-1)/4 -1, 24, color_table.grab_bar_button); + break; + case SCREEN_GRAPH: + _ksys_draw_bar(1, MENU_PANEL_HEIGHT + 20*3 + 24, + (procinfo.clientwidth-1)/4 -1, 24, color_table.grab_bar_button); + break; + case SCREEN_PRINT: + _ksys_draw_bar(1, MENU_PANEL_HEIGHT + 20*3 + 24*2, + (procinfo.clientwidth-1)/4 -1, 24, color_table.grab_bar_button); + break; + case SCREEN_SETTING: + _ksys_draw_bar(1, MENU_PANEL_HEIGHT + 20*3 + 24*3, + (procinfo.clientwidth-1)/4 -1, 24, color_table.grab_bar_button); + break; + }; + _ksys_draw_line( 0, MENU_PANEL_HEIGHT + 20*3, + (procinfo.clientwidth-1)/4 , MENU_PANEL_HEIGHT + 20*3, + color_table.work_graph); + _ksys_draw_line( 0, MENU_PANEL_HEIGHT + 20*3 + 24, + (procinfo.clientwidth-1)/4 , MENU_PANEL_HEIGHT + 20*3 + 24, + color_table.work_graph); + _ksys_draw_line( 0, MENU_PANEL_HEIGHT + 20*3 + 24*2, + (procinfo.clientwidth-1)/4 , MENU_PANEL_HEIGHT + 20*3 + 24*2, + color_table.work_graph); + _ksys_draw_line( 0, MENU_PANEL_HEIGHT + 20*3 + 24*3, + (procinfo.clientwidth-1)/4 , MENU_PANEL_HEIGHT + 20*3 + 24*3, + color_table.work_graph); + _ksys_draw_line( 0, MENU_PANEL_HEIGHT + 20*3 + 24*4, + (procinfo.clientwidth-1)/4 , MENU_PANEL_HEIGHT + 20*3 + 24*4, + color_table.work_graph); + // draw text + write_text_utf8_center(0, MENU_PANEL_HEIGHT + 2, + (procinfo.clientwidth-1)/4, "Save", 0); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + 20 + 2, + (procinfo.clientwidth-1)/4, "Save as", 0); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + 20*2 + 2, + (procinfo.clientwidth-1)/4, "Open", 0); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + 20*3 + 4, + (procinfo.clientwidth-1)/4, "Property", 0); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + 20*3 + 24 + 4, + (procinfo.clientwidth-1)/4, "Graph", 0); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + 20*3 + 24*2 + 4, + (procinfo.clientwidth-1)/4, "Print", 0); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + 20*3 + 24*3 + 4, + (procinfo.clientwidth-1)/4, "Settings", 0); + // define buttons + _ksys_define_button(0, MENU_PANEL_HEIGHT + 20*3, + (procinfo.clientwidth-1)/4, 24, BTN_OTHER_INFO + 0x40000000, 0); + _ksys_define_button(0, MENU_PANEL_HEIGHT + 20*3 + 24, + (procinfo.clientwidth-1)/4, 24, BTN_OTHER_GRAPH + 0x40000000, 0); + _ksys_define_button(0, MENU_PANEL_HEIGHT + 20*3 + 24*2, + (procinfo.clientwidth-1)/4, 24, BTN_OTHER_PRINT + 0x40000000, 0); + _ksys_define_button(0, MENU_PANEL_HEIGHT + 20*3 + 24*3, + (procinfo.clientwidth-1)/4, 24, BTN_OTHER_SETTING + 0x40000000, 0); + //_ksys_draw_bar(1, MENU_PANEL_HEIGHT+1 ,procinfo.clientwidth-2, + // procinfo.clientheight - MENU_PANEL_HEIGHT-2, 0x0000FF); + // set full background + // draw background from list + return; +} + +void draw_about(){ + + write_text_utf8_center(0, MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)/16, + procinfo.clientwidth, "Table for KolibriOS", 1); + // draw text info: version, simple description, authors + write_text_utf8_center(0, MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)/5, + procinfo.clientwidth, "Version: 0.1.1", 0); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)/5 + 20, + procinfo.clientwidth, "Author: Mikhail Frolov aka Doczom", 0); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)/2 - 16, + procinfo.clientwidth, "Документация", 1); + + _ksys_define_button(procinfo.clientwidth/(2*14), + MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)*3/5 - 3, + procinfo.clientwidth/2 - procinfo.clientwidth/(2*14)*2, + 32 + 6, BTN_ABOUT_FORMULS , color_table.grab_button_text); + _ksys_define_button(procinfo.clientwidth/2 + procinfo.clientwidth/(2*14), + MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)*3/5 - 3, + procinfo.clientwidth/2 - procinfo.clientwidth/(2*14)*2, + 32 + 6, BTN_ABOUT_GRAPH , color_table.grab_button_text); + _ksys_define_button(procinfo.clientwidth/(2*14), + MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)*4/5 - 3, + procinfo.clientwidth/2 - procinfo.clientwidth/(2*14)*2, + 32 + 6, BTN_ABOUT_HOTKEYS , color_table.grab_button_text); + _ksys_define_button(procinfo.clientwidth/2 + procinfo.clientwidth/(2*14), + MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)*4/5 - 3, + procinfo.clientwidth/2 - procinfo.clientwidth/(2*14)*2, + 32 + 6, BTN_ABOUT_DEVS , color_table.grab_button_text); + + write_text_utf8_center(0, MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)*3/5, + procinfo.clientwidth/2, "Формулы", 1); + write_text_utf8_center(procinfo.clientwidth/2, MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)*3/5, + procinfo.clientwidth/2, "Графики", 1); + write_text_utf8_center(0, MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)*4/5, + procinfo.clientwidth/2, "Управление", 1); + write_text_utf8_center(procinfo.clientwidth/2, MENU_PANEL_HEIGHT + (procinfo.clientheight - MENU_PANEL_HEIGHT)*4/5, + procinfo.clientwidth/2, "API модулей", 1); + // define 4 buttons for links of docs + return; +} + + +void draw_content(){ + // draw subwindow + if ((selected_screen & (SCREEN_INFO | SCREEN_ABOUT)) == SCREEN_BASE) draw_main_window(); + else if (selected_screen & SCREEN_ABOUT) draw_about(); + else { + // draw menu bar + draw_menu_bar(); + switch (selected_screen) { + case SCREEN_INFO: + + break; + case SCREEN_GRAPH: + + break; + case SCREEN_PRINT: + + break; + case SCREEN_SETTING: + + break; + }; + }; +} + +void draw_toolbar(){ + _ksys_draw_bar(0,0,procinfo.clientwidth, procinfo.clientheight , color_table.work_area); + + gui_draw_button_icon18(BTN_OTHER, 5, (40-26)/2, -1, 0); + gui_draw_button_icon18(BTN_SAVE, 5+(27+11)*1,(40-26)/2, 5, 0); + gui_draw_button_icon18(BTN_SAVE_AS, 5+(27+11)*2,(40-26)/2, 20, 0); + gui_draw_button_icon18(BTN_LOAD, 5+(27+11)*3,(40-26)/2, 0, 0); + gui_draw_button_icon18(BTN_NEW, 5+(27+11)*4,(40-26)/2, 2, 0); + gui_draw_button_icon18(BTN_ABOUT, procinfo.clientwidth - (27+5),(40-26)/2, 66, 0); + + // draw border for toolbar and subwindow + _ksys_draw_line(0, MENU_PANEL_HEIGHT, 0, procinfo.clientheight-1 , color_table.work_graph); + _ksys_draw_line(procinfo.clientwidth-1, MENU_PANEL_HEIGHT, procinfo.clientwidth-1, + procinfo.clientheight-1 , color_table.work_graph); + _ksys_draw_line(0, procinfo.clientheight-1, procinfo.clientwidth-1, + procinfo.clientheight-1 , color_table.work_graph); + switch (selected_screen & SCREEN_ALL_TABS){ + case SCREEN_INFO: + _ksys_draw_line(0, MENU_PANEL_HEIGHT, 0, 3 , color_table.work_graph); + _ksys_draw_line(0, 3, 5+27+3, 3 , color_table.work_graph); + _ksys_draw_line(5+27+3, 3, 5+27+10, MENU_PANEL_HEIGHT, color_table.work_graph); + _ksys_draw_line(5+27+10, MENU_PANEL_HEIGHT, procinfo.clientwidth-1, + MENU_PANEL_HEIGHT , color_table.work_graph); + break; + case SCREEN_ABOUT: + _ksys_draw_line(procinfo.clientwidth-1, MENU_PANEL_HEIGHT, + procinfo.clientwidth-1, 3 , color_table.work_graph); + _ksys_draw_line(procinfo.clientwidth-1, 3, + procinfo.clientwidth-1 - (5+27+3), 3 , color_table.work_graph); + _ksys_draw_line(procinfo.clientwidth-1 - (5+27+3), 3, + procinfo.clientwidth-1 - (5+27+10), MENU_PANEL_HEIGHT, color_table.work_graph); + _ksys_draw_line(0, MENU_PANEL_HEIGHT, procinfo.clientwidth-1 - (5+27+10), + MENU_PANEL_HEIGHT , color_table.work_graph); + break; + default: { + _ksys_draw_line(0, MENU_PANEL_HEIGHT, procinfo.clientwidth-1, + MENU_PANEL_HEIGHT , color_table.work_graph); + }; + }; + draw_content(); + return ; +} + +void draw_window(){ + // create window + _ksys_start_draw(); + _ksys_create_window(100, 40, WND_W, WND_H + _ksys_get_skin_height(), "Table ", 0x00FFFFFF, 0x73); + _ksys_end_draw(); + + _ksys_get_system_colors(&color_table); + // get procinfo + _ksys_thread_info(&procinfo, KSYS_THIS_SLOT); + + cWidth = procinfo.winx_size - 9; + cHeight = procinfo.winy_size - _ksys_get_skin_height() - 4; + + // check rolled-up + if (procinfo.window_state & 0b100) return; + + // check client x_size and y_size + if (cWidth < MIN_WIDTH) { + _ksys_change_window(-1,-1,MIN_WIDTH + 9,-1); + return; + }; + if (cHeight < MIN_HEIGHT) { + _ksys_change_window(-1,-1,-1,MIN_HEIGHT + _ksys_get_skin_height() + 4); + return; + }; + + // update values in all structs: grid, scrollbar, editbox + table_grid.x = 0; + table_grid.y = MENU_PANEL_HEIGHT; + table_grid.w = procinfo.clientwidth -1; + table_grid.h = procinfo.clientheight - MENU_PANEL_HEIGHT -1; + table_grid.grid_color = color_table.work_graph; + + // draw button bar + draw_toolbar(); + return; +} + +bool window_event_key(ksys_oskey_t key){ + if (key.state != 1) { + // key buffer not clean + if ((selected_screen & SCREEN_ALL_TABS) == 0){ + // event key for grid and editbox + if ((key.ctrl_key == KSYS_SCANCODE_ESC) && (table_grid.flags & GRID_FLAG_EDIT_DATA != 0)) { + table_grid.flags = table_grid.flags ^ GRID_FLAG_EDIT_DATA; + return 0; + }; + grid_key(&table_grid, key); + } else { + switch (selected_screen) { + case SCREEN_GRAPH: + break; + case SCREEN_PRINT: + break; + } + if (key.ctrl_key == KSYS_SCANCODE_ESC) { + selected_screen = selected_screen & ~SCREEN_ALL_TABS; + draw_toolbar(); + return 0; + }; + } + if (key.ctrl_key == KSYS_SCANCODE_ESC) return true; + }; + return 0; +} + +bool window_event_mouse(){ + if ((selected_screen & SCREEN_ALL_TABS) == 0){ + // event for grid + grid_mouse(&table_grid); + } else { + switch (selected_screen) { + case SCREEN_GRAPH: + break; + case SCREEN_PRINT: + break; + }; + }; + return 0; +} + +bool window_event_button(uint32_t pressed_button){ + switch (pressed_button){ // Проверка какая кнопка была нажата + case BTN_LOAD: + dlg_open -> mode = PROC_LIB_OPEN; + OpenDialog_start(dlg_open); + if (dlg_open->status == PROC_LIB_SUCCESS) { + // probe file + //dlg_open->openfile_path + } + break; + case BTN_NEW: + //reinit(); + //draw_grid(); + break; + case BTN_SAVE: + // save + break; + case BTN_SAVE_AS: + dlg_open -> mode = PROC_LIB_SAVE; + OpenDialog_start(dlg_open); + if (dlg_open->status == PROC_LIB_SUCCESS) { + // probe file + // update file name + memmove(path_table_doc, dlg_open->openfile_path, 4096); + //save + } + break; + case BTN_OTHER: + selected_screen = (selected_screen & ~SCREEN_ABOUT) ^ SCREEN_INFO; + draw_toolbar(); + break; + case BTN_ABOUT: + selected_screen = (selected_screen & ~SCREEN_INFO) ^ SCREEN_ABOUT; + draw_toolbar(); + break; + case BTN_QUIT: + return true; + + default: + // check all subwindows + if (selected_screen & SCREEN_INFO) { + + // for menu list + switch (pressed_button) { + case BTN_OTHER_INFO: + selected_screen = SCREEN_INFO; + draw_menu_bar(); + break; + case BTN_OTHER_GRAPH: + if (selected_screen != SCREEN_GRAPH){ + // set subwindow + selected_screen = SCREEN_GRAPH; + draw_menu_bar(); + }; + break; + case BTN_OTHER_PRINT: + selected_screen = SCREEN_PRINT; + draw_menu_bar(); + break; + case BTN_OTHER_SETTING: + selected_screen = SCREEN_SETTING; + draw_menu_bar(); + break; + default: + switch (selected_screen) { + case SCREEN_INFO: + break; + case SCREEN_GRAPH: + switch (pressed_button) { + case BTN_OTHER_GRAPH_CREATE: + break; + case BTN_OTHER_GRAPH_ADD: + break; + case BTN_OTHER_GRAPH_DEL: + break; + }; + break; + case SCREEN_PRINT: + break; + case SCREEN_SETTING: + break; + }; + }; + }else if (selected_screen & SCREEN_ABOUT) { + // check button for open docs + switch (pressed_button){ + case BTN_ABOUT_FORMULS: + run_file(config_data.doc_formulas); + break; + case BTN_ABOUT_GRAPH: + run_file(config_data.doc_graph); + break; + case BTN_ABOUT_HOTKEYS: + run_file(config_data.doc_hotkeys); + break; + case BTN_ABOUT_DEVS: + run_file(config_data.doc_module_api); + break; + }; + } else { + // check button main window(for tabs) + }; + }; + return 0; +}