#include #include #include #include #include #include #include #include "buf.h" #include "render.h" #define APP_HEADER "Marker 0.1.0" #define FILE_PLACE "Open Markdown file to display info\n" #define ENCOD_PLACE "CP866\n" #define WIN_W_START 800 #define WIN_H_START 600 #define WIN_WMIN 400 #define WIN_HMIN 300 #define TOP_PANEL_SZ (28 + PADDING * 2) #define BOT_PANEL_SZ (16 + PADDING * 2) #define FILE_TREE_SZ 200 #define SCROLLBAR_SZ 20 char *shared_memory = NULL; char *buffer = NULL; char *data = NULL; char *file_path = NULL; void *icon_buffer = NULL; ksys_colors_table_t color_table; ksys_pos_t screen; ksys_thread_t form; open_dialog *open_dlg = NULL; uint8_t key_code; uint32_t wheels, button; int force = 50; pen_t pen = {0, .pos.x = PADDING, .pos.y = PADDING}; scrollbar hscroll; #define BUF_DRAW_X (form.clientwidth - PADDING * 2 - SCROLLBAR_SZ - 1) #define BUF_DRAW_Y (form.clientheight - TOP_PANEL_SZ - BOT_PANEL_SZ - 2) // ====================================================================== void draw_init() { int icon_16_size; int shm_size = _ksys_shm_open("ICONS18", KSYS_SHM_READ, 0, (char**)&shared_memory); if (shm_size) { icon_16_size = shm_size; if (icon_buffer != 0) { free(icon_buffer); } icon_buffer = malloc(icon_16_size); memmove(icon_buffer, shared_memory, icon_16_size); if(icon_buffer) { ksys_draw_bitmap_palette(icon_buffer + 0 * 18*18*4, 13, 13, 18, 18, 32, NULL, 0); ksys_draw_bitmap_palette(icon_buffer + 38 * 18*18*4, 57, 13, 18, 18, 32, NULL, 0); ksys_draw_bitmap_palette(icon_buffer + 3 * 18*18*4, 93, 12, 18, 18, 32, NULL, 0); // ksys_draw_bitmap_palette(icon_buffer + 66 * 18*18*4, form.clientwidth - PADDING - 23, 13, 18, 18, 32, NULL, 0); } } } void draw_top_panel() { _ksys_draw_bar(0, 0, form.clientwidth, TOP_PANEL_SZ, color_table.work_area); _ksys_define_button(8, 8, 27, 27, 11, 0x00FFFFFF); // OPEN _ksys_define_button(52, 8, 27, 27, 12, 0x00FFFFFF); // EDIT _ksys_define_button(88, 8, 27, 27, 13, 0x00FFFFFF); // REFRESH // _ksys_define_button(form.clientwidth - PADDING - 28, 8, 27, 27, 14, 0x00FFFFFF); // INFO } void draw_paddings() { // Light side paddings _ksys_draw_bar(0, TOP_PANEL_SZ, PADDING, form.clientheight - TOP_PANEL_SZ, color_table.work_area); _ksys_draw_bar(form.clientwidth - PADDING, TOP_PANEL_SZ, PADDING, form.clientheight - TOP_PANEL_SZ, color_table.work_area); _ksys_draw_bar(0, form.clientheight - PADDING, form.clientwidth, PADDING, color_table.work_area); _ksys_draw_bar(PADDING, form.clientheight - BOT_PANEL_SZ, form.clientwidth - PADDING * 2, BOT_PANEL_SZ, color_table.work_area); // Dark buffer borders _ksys_draw_bar(PADDING, TOP_PANEL_SZ, BUF_DRAW_X + 1, 1, (color_table.grab_text + color_table.grab_bar_button) / 2); _ksys_draw_bar(PADDING, TOP_PANEL_SZ + BUF_DRAW_Y + 1, BUF_DRAW_X + 1, 1, (color_table.grab_text + color_table.grab_bar_button) / 2); _ksys_draw_bar(PADDING, TOP_PANEL_SZ, 1, BUF_DRAW_Y + 1, (color_table.grab_text + color_table.grab_bar_button) / 2); } void draw_file_info() { if (file_path != NULL) { _ksys_draw_text( file_path, PADDING, form.clientheight - BOT_PANEL_SZ + PADDING, 16, color_table.work_text | 0x90000000 ); _ksys_draw_text( ENCOD_PLACE, form.clientwidth - PADDING - 8*5, form.clientheight - BOT_PANEL_SZ + PADDING, 16, color_table.work_text | 0x90000000 ); } else { _ksys_draw_text( FILE_PLACE, PADDING, form.clientheight - BOT_PANEL_SZ + PADDING, 16, color_table.work_text | 0x90000000 ); } } void draw_buffer() { drawBuffer(buffer, PADDING + 1, TOP_PANEL_SZ + 1, 0, hscroll.position, BUF_DRAW_X, BUF_DRAW_Y); } void draw_scrolls() { hscroll.max_area = gh(buffer); hscroll.all_redraw = 1; scrollbar_v_draw(&hscroll); } void draw_window() { _ksys_get_system_colors(&color_table); _ksys_start_draw(); _ksys_create_window( (_ksys_screen_size().x - WIN_W_START) / 2, (_ksys_screen_size().y - WIN_H_START) / 2, WIN_W_START, WIN_H_START, APP_HEADER, 0x121212, 0x73 ); _ksys_thread_info(&form, KSYS_THIS_SLOT); if (!(form.window_state & 4)) { _ksys_change_window(form.winx_start, form.winy_start, max(WIN_WMIN, form.winx_size), max(WIN_HMIN, form.winy_size)); hscroll.xpos = form.clientwidth - SCROLLBAR_SZ - PADDING; hscroll.ypos = TOP_PANEL_SZ; hscroll.ysize = hscroll.cur_area = BUF_DRAW_Y + 2; hscroll.position = min(hscroll.position, gh(buffer) - BUF_DRAW_Y); draw_top_panel(); draw_init(); // draw_file_tree(); draw_paddings(); draw_file_info(); draw_buffer(); draw_scrolls(); // draw_info(); //_ksys_draw_bar(BUF_DRAW_X, BUF_DRAW_Y, SCROLLBAR_SZ, SCROLLBAR_SZ, 0x121212); } _ksys_end_draw(); } // ====================================================================== int parse_calc(char *filename) { ksys_ufile_t ld = _ksys_load_file(filename); if (ld.data == NULL) { _ksys_exec("/sys/@notify", "'Marker\nFile not found or empty!' -E -t"); return -1; } int rows = 0; int row_max = (screen.x - PADDING * 8) / 8; int row_len = 0; int n = ld.size; data = ld.data; for (int i = 0; i < ld.size; i++) { // line break counter row_len += 1 * (int) pen.mul; if (row_len > row_max - 1) { rows += 1; row_len = 0; } if (data[i] == '\n') { row_len = 0; if (i < (ld.size - 1) && data[i + 1] == '\n') { if (pen.mode == header) { rows += (int) pen.mul + 1; pen.mul = 1; pen.mode = plain; } else { rows += 2; } i++; } else { if (pen.mode == header) { rows += (int) pen.mul + 1; pen.mul = 1; pen.mode = plain; } else { rows += 1; } } } else if (data[i] == '\\' && i + 1 < n) { } else if (data[i] == '*' || data[i] == '_') { if (i + 1 < n && data[i + 1] == data[i]) { i++; } else { } } else if (data[i] == '~' && i + 1 < n && data[i + 1] == '~') { i++; } else if (data[i] == '`') { } else if ((i == 0 || (i > 0 && data[i - 1] == '\n')) && data[i] == '#') { int cnt = 1; while (i + cnt < n && data[i + cnt] == '#') cnt++; if (cnt <= 6) { pen.mode = header; if (cnt >= 3) { pen.mul = 1; } else { pen.mul = cnt == 1 ? 3 : 2; } i += cnt - 1; while (i + 1 < n && data[i + 1] == ' ') i++; } } else if ((i == 0 || (i > 0 && data[i - 1] == '\n')) && data[i] == '>') { if (data[i + 1] == '\n') { rows += 1; } i++; } } // Hadle empty last row if (data[n - 1] == '\n') { rows -= 1; } free(data); return rows + 1; } void parse_draw(char *filename) { ksys_ufile_t ld = _ksys_load_file(filename); if (ld.data == NULL) { // _ksys_exec("/sys/@notify", "'Marker\nFile not found or empty!' -E -t"); return; } int n = ld.size; data = ld.data; //puts(data); for (int i = 0; i < ld.size; i++) { if (data[i] == '\n') { render_NewLn(&pen, buffer); if (pen.mode == header) { pen.mul = 1; pen.mode = plain; pen.bold = false; } if (pen.mode == quote) { pen.color = color_table.work_text; pen.mode = plain; pen.pos.x -= 16; } } else if (data[i] == '\\' && i + 1 < n) { i++; render_DrawLen(&pen, buffer, data + i, 1); } else if (data[i] == '*' || data[i] == '_') { if (i + 1 < n && data[i + 1] == data[i]) { pen.bold ^= 1; i++; } else { pen.italic ^= 1; } } else if (data[i] == '~' && i + 1 < n && data[i + 1] == '~') { pen.strike ^= 1; i++; } else if (data[i] == '`') { pen.underline ^= 1; } else if ((i == 0 || (i > 0 && data[i - 1] == '\n')) && data[i] == '#') { int cnt = 1; while (i + cnt < n && data[i + cnt] == '#') cnt++; if (cnt <= 6) { pen.mode = header; if (cnt >= 3) { pen.mul = 1; pen.bold = true; } else { pen.mul = cnt == 1 ? 3 : 2; } i += cnt - 1; while (i + 1 < n && data[i + 1] == ' ') i++; } } else if ((i == 0 || (i > 0 && data[i - 1] == '\n')) && data[i] == '>') { pen.color = color_table.grab_text; pen.mode = quote; pen.pos.x += 8; // i++; // rows += 1; } else { render_DrawLen(&pen, buffer, data + i, 1); } } // printf("Parse-rendered file!\n"); free(data); } // ====================================================================== void clean_pen() { pen.mul = 1; pen.mode = plain; pen.pos.x = PADDING; pen.pos.y = PADDING; // pen.color = color_table.work_text; // pen.italic = pen.bold = pen.underline = pen.strike = false; } char* open_file() { // printf("1\n"); OpenDialog_start(open_dlg); // printf("2\n"); // return("test.md"); if (open_dlg->status == SUCCESS) { // printf("success :)\n"); return open_dlg->openfile_path; } else { // printf("not succes :(\n"); _ksys_exec("/sys/@notify", "'Marker\nNo file selected!' -F -t"); return file_path; } } void edit_file() { if (file_path != NULL) { _ksys_exec("/sys/develop/cedit", file_path); } else { _ksys_exec("/sys/@notify", "'Marker\nOpen existing file to edit it!' -F -t"); } } void render_file() { if (file_path != NULL) { int rows = parse_calc(file_path); free(buffer); buffer = createBuffer(screen.x + 1, max(screen.y + 1, rows * 16 + PADDING * 2), color_table.grab_button_text); // printf("Created buffer...\n"); clean_pen(); hscroll.position = 0; parse_draw(file_path); // printf("Rendered file...\n"); } else { free(buffer); buffer = createBuffer(screen.x + 1, screen.y + 1, color_table.grab_button_text); } } // ====================================================================== int main(int argc, char **argv) { _ksys_set_event_mask(KSYS_EVM_REDRAW + KSYS_EVM_KEY + KSYS_EVM_BUTTON + KSYS_EVM_MOUSE + KSYS_EVM_MOUSE_FILTER); _ksys_get_system_colors(&color_table); screen = _ksys_screen_size(); open_dlg = kolibri_new_open_dialog(OPEN, 0, 0, 400, 300); OpenDialog_init(open_dlg); // clean_pen(); pen.mul = 1; pen.font_size.x = 8; pen.font_size.y = 16; pen.color = color_table.work_text; if (argc == 1) { // file_path = open_file(); render_file(); } else { file_path = argv[1]; render_file(); } hscroll.xsize = SCROLLBAR_SZ - 1; hscroll.ypos = 0; hscroll.btn_height = SCROLLBAR_SZ - 1; hscroll.type = 2; hscroll.max_area = gh(buffer); hscroll.back_color = color_table.grab_bar_button; hscroll.line_color = (color_table.grab_text + color_table.grab_bar_button) / 2; hscroll.front_color = color_table.grab_button_text; hscroll.ar_offset = force; bool isRunning = 1; int gui_event; while (isRunning) { gui_event = _ksys_get_event(); switch (gui_event) { case KSYS_EVENT_REDRAW: draw_window(); break; case KSYS_EVENT_KEY: key_code = _ksys_get_key().code; if (form.window_state & 4) break; switch (key_code) { case 184: // PgUp hscroll.position = max(0, (int)hscroll.position - form.clientheight); break; case 183: // PgDn hscroll.position = min(gh(buffer) - BUF_DRAW_Y, hscroll.position + form.clientheight); break; case 178: // Up hscroll.position = max(0, (int)hscroll.position - force); break; case 177: // Down hscroll.position = min(gh(buffer) - BUF_DRAW_Y, hscroll.position + force); break; } draw_buffer(); draw_scrolls(); break; case KSYS_EVENT_BUTTON: switch(_ksys_get_button()) { case 1: isRunning = 0; break; case 11: file_path = open_file(); render_file(); draw_buffer(); break; case 12: edit_file(); break; case 13: render_file(); draw_buffer(); break; } break; case KSYS_EVENT_MOUSE: wheels = _ksys_get_mouse_wheels(); button = _ksys_get_mouse_buttons(); if (form.window_state & 4) break; scrollbar_v_mouse(&hscroll); if (wheels & 0xFFFF) { int ctrl = _ksys_get_control_key_state(); if (!(ctrl & (KSYS_CONTROL_LSHIFT | KSYS_CONTROL_RSHIFT))) { hscroll.position = max(min((int)hscroll.position + force * (short)wheels, gh(buffer) - BUF_DRAW_Y), 0); } draw_buffer(); draw_scrolls(); } if (button) { draw_buffer(); } break; } } // free(shared_memory); free(open_dlg); free(buffer); // free(data); // free(file_path); // free(icon_buffer); return 0; }