335 lines
9.1 KiB
C
335 lines
9.1 KiB
C
// micro grid library
|
|
#include <sys/ksys.h>
|
|
|
|
//#include <string.h>
|
|
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){
|
|
|
|
} |