// 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){ }