From: yu.dongliang <18588496441@163.com> Date: Tue, 19 May 2026 11:19:22 +0000 (+0800) Subject: css: support a simple scroll-bar with 'scrollbar-width' & 'scrollbar-color' as CSS... X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=0c3be46d35123d257ccd951c6cf962dbbf809e20;p=abc.git css: support a simple scroll-bar with 'scrollbar-width' & 'scrollbar-color' as CSS asked --- diff --git a/examples/overflow.html b/examples/overflow.html index 89fb8f7..55fcd84 100644 --- a/examples/overflow.html +++ b/examples/overflow.html @@ -4,11 +4,18 @@ diff --git a/html/abc_css_border.c b/html/abc_css_border.c index 47b8f9a..ab68fb4 100644 --- a/html/abc_css_border.c +++ b/html/abc_css_border.c @@ -100,7 +100,7 @@ int abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_o } else if (p) { if (i > 1) - abc_css_color(r, g, b, p); + abc_css_color(r, g, b, p, -1); else if (1 == i) __css_border_type(type, p, (size_t)(str - p)); diff --git a/html/abc_css_color.c b/html/abc_css_color.c index 330474f..3783bc3 100644 --- a/html/abc_css_color.c +++ b/html/abc_css_color.c @@ -319,17 +319,21 @@ static css_color_t css_colors[] = {css_YellowGreen, 0x9acd32}, }; -int abc_css_color(double* r, double* g, double* b, const uint8_t* str) +int abc_css_color(double* r, double* g, double* b, const uint8_t* str, size_t len) { *r = 0.0; *g = 0.0; *b = 0.0; + if (!str || 0 == len) + return 0; + if ('#' == *str) { uint64_t value = 0; + long i; - while (*++str) { - int c = *str; + for (i = 1; i < len && str[i]; i++) { + int c = str[i]; if ('0' <= c && '9' >= c) { value <<= 4; @@ -349,24 +353,29 @@ int abc_css_color(double* r, double* g, double* b, const uint8_t* str) *b = ( value & 0xff) / 255.0; } else if (!__html_strncmp(str, "rgb(", 4)) { - const uint8_t* p = str + 4; - - str = p; - while (*str && ',' != *str) - str++; - *r = atof(p) / 255.0; - - if (*str) { - p = ++str; - while (*str && ',' != *str) - str++; - *g = atof(p) / 255.0; - - if (*str) { - p = ++str; - while (*str && ')' != *str) - str++; - *b = atof(p) / 255.0; + long i; + long j = 4; + int k = 0; + + for (i = 4; i < len && str[i]; i++) { + int c = str[i]; + + if (',' == c || ')' == c) { + switch (k) { + case 0: + *r = atof(str + j) / 255.0; + break; + case 1: + *g = atof(str + j) / 255.0; + break; + case 2: + *b = atof(str + j) / 255.0; + break; + }; + + if (++k > 2) + break; + j = i + 1; } } } else { @@ -376,7 +385,7 @@ int abc_css_color(double* r, double* g, double* b, const uint8_t* str) int j; for (j = 0; c->names[j]; j++) { - if (!__html_strcmp(c->names[j], str)) { + if (!__html_strncmp(c->names[j], str, len)) { *r = ((c->color >> 16) & 0xff) / 255.0; *g = ((c->color >> 8) & 0xff) / 255.0; *b = ( c->color & 0xff) / 255.0; @@ -390,3 +399,50 @@ int abc_css_color(double* r, double* g, double* b, const uint8_t* str) return 0; } + +int abc_css_scrollbar_color(double thumb[3], double track[3], const uint8_t* str) +{ + thumb[0] = 0.0; + thumb[1] = 0.0; + thumb[2] = 0.0; + + track[0] = 0.0; + track[1] = 0.0; + track[2] = 0.0; + + if (!str) + return 0; + + int c; + int c0 = ' '; + int k = 0; + long i = 0; + long j = 0; + + do { + c = str[i++]; + + if (' ' == c0) { + if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) + continue; + + c0 = c; + j = i - 1; + + } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) { + + if (0 == k) { + abc_css_color(thumb, thumb + 1, thumb + 2, str + j, i - 1 - j); + k = 1; + } else { + abc_css_color(track, track + 1, track + 2, str + j, i - 1 - j); + break; + } + + c0 = ' '; + j = i; + } + } while (c); + + return 0; +} diff --git a/html/abc_css_position.c b/html/abc_css_position.c index bd82a81..0c06da7 100644 --- a/html/abc_css_position.c +++ b/html/abc_css_position.c @@ -135,3 +135,42 @@ int abc_css_position(const uint8_t* str) return ABC_POSITION_STATIC; } + +int abc_css_overflow(const uint8_t* str) +{ + if (!__html_strcmp(str, "hidden")) + return ABC_OVERFLOW_HIDDEN; + + else if (!__html_strcmp(str, "scroll")) + return ABC_OVERFLOW_SCROLL; + + else if (!__html_strcmp(str, "auto")) + return ABC_OVERFLOW_SCROLL; + + return ABC_OVERFLOW_VISIBLE; +} + +void abc_overflow_show(int* x, int* y, int* w, int* h, int mask_x, int mask_y, int mask_w, int mask_h) +{ +#define CSS_OVERFLOW_SHOW(px, pw, x2, x3) \ + do { \ + int x1 = *px + *pw; \ + \ + if (*px > x3) \ + *pw = 0; \ + else if (x1 < x2) \ + *pw = 0; \ + else { \ + if (*px < x2) \ + *px = x2; \ + \ + if (x1 > x3) \ + *pw = x3 - *px; \ + else \ + *pw = x1 - *px; \ + } \ + } while (0) + + CSS_OVERFLOW_SHOW(x, w, mask_x, mask_x + mask_w); + CSS_OVERFLOW_SHOW(y, h, mask_y, mask_y + mask_h); +} diff --git a/html/abc_html.c b/html/abc_html.c index bd87a4f..f10fb09 100644 --- a/html/abc_html.c +++ b/html/abc_html.c @@ -11,8 +11,6 @@ static char* margin_keys[] = {"margin", "外边距", NULL}; static char* border_keys[] = {"border", "边框", NULL}; static char* padding_keys[] = {"padding", "内边距", NULL}; -static char* overflow_keys[] = {"overflow", NULL}; - static char* position_keys[] = {"position", "定位", NULL}; static char* top_keys[] = {"top", "上", NULL}; static char* bottom_keys[] = {"bottom", "下", NULL}; @@ -37,6 +35,10 @@ static char* bg_image_keys[] = {"background-image", "背景图片", static char* bg_repeat_keys[] = {"background-repeat", "背景重复", NULL}; static char* bg_position_keys[] = {"background-position", "背景位置", NULL}; +static char* overflow_keys[] = {"overflow", "内容溢出", NULL}; +static char* scroll_width_keys[] = {"scrollbar-width", "滚动条宽度", NULL}; +static char* scroll_color_keys[] = {"scrollbar-color", "滚动条颜色", NULL}; + static char* list_style_keys[] = {"list-style", "列表风格", NULL}; static char* list_style_type_keys[] = {"list-style-type", "列表标记", NULL}; static char* list_style_image_keys[] = {"list-style-image", "列表标记图片", NULL}; @@ -145,38 +147,40 @@ static html_attr_t meta_attrs[] = static html_attr_t body_attrs[] = { #define ABC_CSS_BOX(margin, border, padding) \ - {margin_keys, #margin, ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, \ - {border_keys, #border, ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, \ - {padding_keys, #padding, ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, \ + {margin_keys, #margin, ABC_HTML_ATTR_MARGIN, ABC_HTML_FLAG_SHOW}, \ + {border_keys, #border, ABC_HTML_ATTR_BORDER, ABC_HTML_FLAG_SHOW}, \ + {padding_keys, #padding, ABC_HTML_ATTR_PADDING, ABC_HTML_FLAG_SHOW}, \ \ - {overflow_keys, "", ABC_HTML_ATTR_OVERFLOW, ABC_HTML_FLAG_SHOW}, \ + {overflow_keys, "", ABC_CSS_OVERFLOW, ABC_HTML_FLAG_SHOW}, \ + {scroll_width_keys, "", ABC_CSS_SCROLLBAR_WIDTH, ABC_HTML_FLAG_SHOW}, \ + {scroll_color_keys, "", ABC_CSS_SCROLLBAR_COLOR, ABC_HTML_FLAG_SHOW}, \ \ - {position_keys, "", ABC_HTML_ATTR_POSITION, ABC_HTML_FLAG_SHOW}, \ - {top_keys, "", ABC_HTML_ATTR_TOP, ABC_HTML_FLAG_SHOW}, \ - {bottom_keys, "", ABC_HTML_ATTR_BOTTOM, ABC_HTML_FLAG_SHOW}, \ - {left_keys, "", ABC_HTML_ATTR_LEFT, ABC_HTML_FLAG_SHOW}, \ - {right_keys, "", ABC_HTML_ATTR_RIGHT, ABC_HTML_FLAG_SHOW}, \ + {position_keys, "", ABC_CSS_POSITION, ABC_HTML_FLAG_SHOW}, \ + {top_keys, "", ABC_CSS_TOP, ABC_HTML_FLAG_SHOW}, \ + {bottom_keys, "", ABC_CSS_BOTTOM, ABC_HTML_FLAG_SHOW}, \ + {left_keys, "", ABC_CSS_LEFT, ABC_HTML_FLAG_SHOW}, \ + {right_keys, "", ABC_CSS_RIGHT, ABC_HTML_FLAG_SHOW}, \ \ - {width_keys, "", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW}, \ - {height_keys, "", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW}, + {width_keys, "", ABC_HTML_ATTR_WIDTH, ABC_HTML_FLAG_SHOW}, \ + {height_keys, "", ABC_HTML_ATTR_HEIGHT, ABC_HTML_FLAG_SHOW}, #define ABC_CSS_SELECTOR() \ - {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, \ - {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, \ - {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, + {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW}, \ + {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW}, \ + {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW}, #define ABC_CSS_BACK_GROUND(color) \ - {bg_keys, "", ABC_HTML_ATTR_BG, ABC_HTML_FLAG_SHOW}, \ - {bg_color_keys, #color, ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, \ - {bg_image_keys, "", ABC_HTML_ATTR_BG_IMAGE, ABC_HTML_FLAG_SHOW}, \ - {bg_repeat_keys, "", ABC_HTML_ATTR_BG_REPEAT, ABC_HTML_FLAG_SHOW}, \ - {bg_position_keys, "", ABC_HTML_ATTR_BG_POSITION, ABC_HTML_FLAG_SHOW}, + {bg_keys, "", ABC_HTML_ATTR_BG, ABC_HTML_FLAG_SHOW}, \ + {bg_color_keys, #color, ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW}, \ + {bg_image_keys, "", ABC_HTML_ATTR_BG_IMAGE, ABC_HTML_FLAG_SHOW}, \ + {bg_repeat_keys, "", ABC_HTML_ATTR_BG_REPEAT, ABC_HTML_FLAG_SHOW}, \ + {bg_position_keys, "", ABC_HTML_ATTR_BG_POSITION, ABC_HTML_FLAG_SHOW}, #define ABC_CSS_FONT(font, size, color, style) \ - {font_keys, #font, ABC_HTML_ATTR_FONT, 0}, \ - {font_size_keys, #size, ABC_HTML_ATTR_FONT_SIZE, 0}, \ - {font_color_keys, #color, ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, \ - {font_style_keys, #style, ABC_HTML_ATTR_FONT_STYLE, 0}, + {font_keys, #font, ABC_HTML_ATTR_FONT, 0}, \ + {font_size_keys, #size, ABC_HTML_ATTR_FONT_SIZE, 0}, \ + {font_color_keys, #color, ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW}, \ + {font_style_keys, #style, ABC_HTML_ATTR_FONT_STYLE, 0}, #define ABC_CSS_TEXT(align, underline) \ {text_align_keys, #align, ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW}, \ diff --git a/html/abc_html.h b/html/abc_html.h index 617cff4..4180674 100644 --- a/html/abc_html.h +++ b/html/abc_html.h @@ -57,7 +57,7 @@ int abc_css_active(abc_obj_t* obj); int abc_css_bg_position(float* x, float* y, float w, float h, abc_obj_t* obj, const uint8_t* str); -int abc_css_color (double* r, double* g, double* b, const uint8_t* str); +int abc_css_color (double* r, double* g, double* b, const uint8_t* str, size_t len); int abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_obj_t* obj, const uint8_t* str); int abc_css_margin(abc_obj_t* obj); int abc_css_length(abc_obj_t* obj, const uint8_t* str, int len); @@ -66,5 +66,8 @@ int abc_css_width (abc_obj_t* obj, int width, int margin); int abc_css_height(abc_obj_t* obj, int height, int margin); int abc_css_position(const uint8_t* str); +int abc_css_overflow(const uint8_t* str); + +void abc_overflow_show(int* x, int* y, int* w, int* h, int mask_x, int mask_y, int mask_w, int mask_h); #endif diff --git a/html/abc_obj.c b/html/abc_obj.c index b455357..ea0c89a 100644 --- a/html/abc_obj.c +++ b/html/abc_obj.c @@ -64,6 +64,21 @@ void abc_obj_free(abc_obj_t* obj) } } +void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy) +{ + scf_list_t* l; + abc_obj_t* obj; + + for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) { + obj = scf_list_data(l, abc_obj_t, list); + + obj->x += dx; + obj->y += dy; + + abc_dfs_update_xy(obj, dx, dy); + } +} + abc_obj_t* abc_obj_find(abc_obj_t* root, int x, int y) { scf_list_t* l; diff --git a/html/abc_obj.h b/html/abc_obj.h index c63fb66..f2d5715 100644 --- a/html/abc_obj.h +++ b/html/abc_obj.h @@ -113,14 +113,6 @@ enum abc_objs ABC_HTML_ATTR_BORDER, ABC_HTML_ATTR_PADDING, - ABC_HTML_ATTR_POSITION, - ABC_HTML_ATTR_TOP, - ABC_HTML_ATTR_BOTTOM, - ABC_HTML_ATTR_LEFT, - ABC_HTML_ATTR_RIGHT, - - ABC_HTML_ATTR_OVERFLOW, - ABC_HTML_ATTR_XMLNS, ABC_HTML_ATTR_XMLANG, ABC_HTML_ATTR_LANG, @@ -141,6 +133,16 @@ enum abc_objs ABC_CSS_BORDER_COLLAPSE, + ABC_CSS_POSITION, + ABC_CSS_TOP, + ABC_CSS_BOTTOM, + ABC_CSS_LEFT, + ABC_CSS_RIGHT, + + ABC_CSS_OVERFLOW, + ABC_CSS_SCROLLBAR_WIDTH, + ABC_CSS_SCROLLBAR_COLOR, + // css pse class (element) ABC_CSS_FIRST_CHILD, @@ -163,8 +165,6 @@ enum abc_objs // css selectors from html attrs above ABC_CSS_ID = ABC_HTML_ATTR_ID, ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS, - ABC_CSS_POSITION = ABC_HTML_ATTR_POSITION, - ABC_CSS_OVERFLOW = ABC_HTML_ATTR_OVERFLOW, }; enum abc_border_style @@ -174,6 +174,14 @@ enum abc_border_style ABC_BORDER_DASHED, }; +enum abc_line_style +{ + ABC_LINE_NONE, + ABC_LINE_UNDER, + ABC_LINE_OVER, + ABC_LINE_THROUGH, +}; + enum abc_position_style { ABC_POSITION_STATIC, @@ -183,12 +191,12 @@ enum abc_position_style ABC_POSITION_STICKY, }; -enum abc_line_style +enum abc_overflow_style { - ABC_LINE_NONE, - ABC_LINE_UNDER, - ABC_LINE_OVER, - ABC_LINE_THROUGH, + ABC_OVERFLOW_VISIBLE, + ABC_OVERFLOW_HIDDEN, + ABC_OVERFLOW_SCROLL, + ABC_OVERFLOW_AUTO, }; struct abc_text_s @@ -255,6 +263,23 @@ struct abc_obj_s int w; int h; + int overflow_type; + // view area that object can see + int view_x; + int view_y; + int view_w; + int view_h; + + int mouse_down_x; + int mouse_down_y; + int mouse_move_x; + int mouse_move_y; + + int scroll_x; + int scroll_y; + int content_w; + int content_h; + double y_bearing; int margin; int padding; @@ -298,11 +323,12 @@ abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key); abc_obj_t* abc_obj_find_type(abc_obj_t* root, int type); +void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy); + scf_string_t* abc_obj_to_string(abc_obj_t* obj); scf_string_t* abc_ol_list_style(abc_obj_t* obj, int num); - static inline abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key) { if (key < ABC_HTML_ATTR_ID || key >= ABC_HTML_CSS_NB) diff --git a/ui/Makefile b/ui/Makefile index 78042e2..e7567f9 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -1,9 +1,6 @@ CFILES += main.c CFILES += abc_layout.c -CFILES += abc_layout_html.c -CFILES += abc_layout_title.c -CFILES += abc_layout_head.c CFILES += abc_layout_body.c CFILES += abc_layout_div.c @@ -21,9 +18,6 @@ CFILES += abc_layout_video.c CFILES += abc_layout_audio.c CFILES += abc_render.c -CFILES += abc_render_html.c -CFILES += abc_render_title.c -CFILES += abc_render_head.c CFILES += abc_render_body.c CFILES += __render_border.c diff --git a/ui/__render_bg_image.c b/ui/__render_bg_image.c index 84375ce..eab0589 100644 --- a/ui/__render_bg_image.c +++ b/ui/__render_bg_image.c @@ -102,7 +102,7 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt double b = 0.0; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); if (attr) - abc_css_color(&r, &g, &b, attr->value->data); + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); if (0 == program) __init_program(&program, vert_shader, frag_shader); @@ -210,6 +210,9 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update); + glBindBuffer (GL_ARRAY_BUFFER, buffers[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_array), texture_array); + glBindVertexArray(vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); diff --git a/ui/__render_border.c b/ui/__render_border.c index e52787a..125d9d8 100644 --- a/ui/__render_border.c +++ b/ui/__render_border.c @@ -19,13 +19,43 @@ static const char* frag_shader = "uniform float y_border; \n" "uniform vec4 color; \n" "uniform vec4 bgColor; \n" + "\n" + "uniform vec4 thumbColor; \n" + "uniform vec4 trackColor; \n" + "uniform vec2 wh; \n" + "uniform float w_scroll; \n" + "uniform float scroll_y; \n" + "uniform float scroll_h; \n" + "vec4 yScrollColor(float center, float L, float R, float dR, float y, float dx) { \n" + " if (y < center - L + R) { \n" + " float dy = center - L + R - y; \n" + " float r = sqrt(dx * dx + dy * dy); \n" + " float beta = smoothstep(R - dR, R + dR, r); \n" + " return mix(thumbColor, trackColor, beta); \n" + " } else if (y > center + L - R) { \n" + " float dy = center + L - R - y; \n" + " float r = sqrt(dx * dx + dy * dy); \n" + " float beta = smoothstep(R - dR, R + dR, r); \n" + " return mix(thumbColor, trackColor, beta); \n" + " } else { \n" + " return thumbColor; \n" + " } \n" + " return trackColor; \n" + "} \n" "void main() { \n" " float x = v_texCoord.x; \n" " float y = v_texCoord.y; \n" + " float aspect = wh.x / wh.y; \n" " if ((x >= 0.0 && x <= x_border) || (x >= 1.0 - x_border && x <= 1.0)) { \n" " outputColor = color; \n" " } else if ((y >= 0.0 && y <= y_border) || (y >= 1.0 - y_border && y <= 1.0)) { \n" " outputColor = color; \n" + " } else if (x > 1.0 - x_border - w_scroll && x < 1.0 - x_border) { \n" + " float R = w_scroll / 2.0; \n" + " float L = scroll_h / 2.0; \n" + " float dx = 1.0 - x_border - x - R; \n" + " float dR = 1.0 / wh.y; \n" + " outputColor = yScrollColor(scroll_y, L, R * aspect, dR, y, dx * aspect); \n" " } else { \n" " outputColor = bgColor; \n" " } \n" @@ -43,6 +73,13 @@ static GLuint uniform_y_border; static GLuint uniform_color; static GLuint uniform_bgColor; +static GLuint uniform_thumbColor; +static GLuint uniform_trackColor; + +static GLuint uniform_wh; +static GLuint uniform_w_scroll; +static GLuint uniform_scroll_y; +static GLuint uniform_scroll_h; static int __render_fini_border(abc_render_t* render) { @@ -61,32 +98,26 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width, int border = 0; int border_type = ABC_BORDER_SOLID; - double r0 = 0.0; - double g0 = 0.0; - double b0 = 0.0; - - double r1 = 0.0; - double g1 = 0.0; - double b1 = 0.0; - double a1 = 0.0; + double fgColor[3] = {0.0, 0.0, 0.0}; + double bgColor[4] = {0.0, 0.0, 0.0, 0.0}; abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR); if (attr && attr->value->len > 0) { - a1 = 1.0; - abc_css_color(&r1, &g1, &b1, attr->value->data); + bgColor[4] = 1.0; + abc_css_color(bgColor, bgColor + 1, bgColor + 2, attr->value->data, attr->value->len); } - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN); + attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_MARGIN); if (attr) margin = atoi(attr->value->data); - attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER); + attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BORDER); if (attr) - abc_css_border(&r0, &g0, &b0, &border, &border_type, obj, attr->value->data); + abc_css_border(fgColor, fgColor + 1, fgColor + 2, &border, &border_type, obj, attr->value->data); else { attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); if (attr) - abc_css_color(&r0, &g0, &b0, attr->value->data); + abc_css_color(fgColor, fgColor + 1, fgColor + 2, attr->value->data, attr->value->len); } int x = obj->x + margin; @@ -94,27 +125,165 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width, int w = obj->w - margin * 2; int h = obj->h - margin * 2; + obj->view_x = x; + obj->view_y = y; + obj->view_w = w; + obj->view_h = h; + + abc_obj_t* parent = obj->parent; + + if (parent && (x < parent->view_x + || y < parent->view_y + || x + w > parent->view_x + parent->view_w + || y + h > parent->view_y + parent->view_h)) { + + attr = abc_obj_find_attr(obj, ABC_CSS_OVERFLOW); + if (attr) + obj->overflow_type = abc_css_overflow(attr->value->data); + + switch (obj->overflow_type) + { + case ABC_OVERFLOW_HIDDEN: + abc_overflow_show(&obj->view_x, &obj->view_y, &obj->view_w, &obj->view_h, + parent->view_x, + parent->view_y, parent->view_w, parent->view_h); + + scf_logw("x: %d, y: %d, w: %d, h: %d, obj: x: %d, y: %d, w: %d, h: %d, parent: x: %d, y: %d, w: %d, h: %d\n", + x, y, w, h, + obj->view_x, obj->view_y, obj->view_w, obj->view_h, + parent->view_x, parent->view_y, parent->view_w, parent->view_h); + break; + case ABC_OVERFLOW_SCROLL: + break; + default: + break; + }; + } + float mvp[16]; __compute_mvp(mvp, 0, 0, 0); GLfloat vert_update[] = { - 2.0 * x / (float)width - 1.0, - -2.0 * (y + h) / (float)height + 1.0, + 2.0 * obj->view_x / (float)width - 1.0, + -2.0 * (obj->view_y + obj->view_h) / (float)height + 1.0, - 2.0 * (x + w) / (float)width - 1.0, - -2.0 * (y + h) / (float)height + 1.0, + 2.0 * (obj->view_x + obj->view_w) / (float)width - 1.0, + -2.0 * (obj->view_y + obj->view_h) / (float)height + 1.0, - 2.0 * x / (float)width - 1.0, - -2.0 * y / (float)height + 1.0, + 2.0 * obj->view_x / (float)width - 1.0, + -2.0 * obj->view_y / (float)height + 1.0, - 2.0 * (x + w) / (float)width - 1.0, - -2.0 * y / (float)height + 1.0, + 2.0 * (obj->view_x + obj->view_w) / (float)width - 1.0, + -2.0 * obj->view_y / (float)height + 1.0, + }; + + GLfloat texture_update[] = + { + (obj->view_x - x) / (float)w, + (obj->view_y + obj->view_h - y) / (float)h, + + (obj->view_x + obj->view_w - x) / (float)w, + (obj->view_y + obj->view_h - y) / (float)h, + + (obj->view_x - x) / (float)w, + (obj->view_y - y) / (float)h, + + (obj->view_x + obj->view_w - x) / (float)w, + (obj->view_y - y) / (float)h, }; GLfloat x_border = border / (float)w; GLfloat y_border = border / (float)h; + if (ABC_OVERFLOW_HIDDEN == obj->overflow_type) { + for (int i = 0; i < sizeof(texture_update) / sizeof(texture_update[0]) / 2; i++) + scf_logi("%lg, %lg\n", texture_update[2 * i], texture_update[2 * i + 1]); + + printf(" x_border: %lg, y_border: %lg\n\n", x_border, y_border); + } + + GLfloat aspect = w / (float)h; + GLfloat w_scroll = 0.0; + GLfloat scroll_y = 0.0; + GLfloat scroll_h = 0.0; + + double thumbColor[4] = {bgColor[0], bgColor[1], bgColor[2], bgColor[3]}; + double trackColor[4] = {bgColor[0], bgColor[1], bgColor[2], bgColor[3]}; + + if (obj->content_h > obj->h) + { + float percent = h / (float)obj->content_h; + int len = h * percent; + int range = h - len; + int min = len / 2; + int max = h - min; + + if (obj->scroll_y < min) + obj->scroll_y = min; + if (obj->scroll_y > max) + obj->scroll_y = max; + + w_scroll = 25.0; + + attr = abc_obj_get_attr(obj, ABC_CSS_SCROLLBAR_WIDTH); + if (attr && attr->value->len > 0) + w_scroll = atof(attr->value->data); + + attr = abc_obj_get_attr(obj, ABC_CSS_SCROLLBAR_COLOR); + if (attr && attr->value->len > 0) { + thumbColor[3] = 1.0; + trackColor[3] = 1.0; + abc_css_scrollbar_color(thumbColor, trackColor, attr->value->data); + } else { + thumbColor[0] = 1.0; + thumbColor[1] = 0.27; + thumbColor[2] = 0.0; + thumbColor[3] = 1.0; + } + + scf_logi("obj mouse_down_x: %d, mouse_down_y: %d, mouse_move_x: %d, mouse_move_y: %d, x: %d, y: %d, x+w: %d, y+h: %d\n", + obj->mouse_down_x, + obj->mouse_down_x, obj->mouse_move_x, obj->mouse_move_y, + x, y, x + w, y + h); + + int dy = 0; + if (obj->mouse_move_x > x + w - w_scroll + && obj->mouse_move_x < x + w + && obj->mouse_move_y > y + && obj->mouse_move_y < y + h) { + + if (obj->mouse_down_x > x + w - w_scroll + && obj->mouse_down_x < x + w + && obj->mouse_down_y > y + && obj->mouse_down_y < y + h) { + + dy = obj->mouse_move_y - obj->mouse_down_y; + if (dy < min - obj->scroll_y) + dy = min - obj->scroll_y; + if (dy > max - obj->scroll_y) + dy = max - obj->scroll_y; + + assert(dy >= -range && dy <= range); + + obj->scroll_y += dy; + } + } + + dy = -(obj->scroll_y - min) * (obj->content_h - obj->h) / range; + + abc_dfs_update_xy(obj, 0, dy); + + scroll_h = percent; + scroll_y = obj->scroll_y / (float)h; + + w_scroll /= (float)w; + if (w_scroll > scroll_h / aspect) + w_scroll = scroll_h / aspect; + + scf_logi("aspect: %lg, w_scroll: %lg, scroll_y: %lg, scroll_h: %lg\n\n", aspect, w_scroll, scroll_y, scroll_h); + } + glUseProgram(program); uniform_mvp = glGetUniformLocation(program, "mvp"); uniform_x_border = glGetUniformLocation(program, "x_border"); @@ -122,17 +291,36 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width, uniform_color = glGetUniformLocation(program, "color"); uniform_bgColor = glGetUniformLocation(program, "bgColor"); + uniform_thumbColor = glGetUniformLocation(program, "thumbColor"); + uniform_trackColor = glGetUniformLocation(program, "trackColor"); + + uniform_wh = glGetUniformLocation(program, "wh"); + uniform_scroll_y = glGetUniformLocation(program, "scroll_y"); + uniform_scroll_h = glGetUniformLocation(program, "scroll_h"); + uniform_w_scroll = glGetUniformLocation(program, "w_scroll"); + glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp); glUniform1f(uniform_x_border, x_border); glUniform1f(uniform_y_border, y_border); - glUniform4f(uniform_color, r0, g0, b0, 1.0); - glUniform4f(uniform_bgColor, r1, g1, b1, a1); + glUniform4f(uniform_color, fgColor[0], fgColor[1], fgColor[2], 1.0); + glUniform4f(uniform_bgColor, bgColor[0], bgColor[1], bgColor[2], bgColor[3]); + + glUniform4f(uniform_thumbColor, thumbColor[0], thumbColor[1], thumbColor[2], thumbColor[3]); + glUniform4f(uniform_trackColor, trackColor[0], trackColor[1], trackColor[2], trackColor[3]); + + glUniform2f(uniform_wh, (GLfloat)w, (GLfloat)h); + glUniform1f(uniform_scroll_y, scroll_y); + glUniform1f(uniform_scroll_h, scroll_h); + glUniform1f(uniform_w_scroll, w_scroll); // draw glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update); + glBindBuffer (GL_ARRAY_BUFFER, buffers[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update); + glBindVertexArray(vao); glEnable(GL_BLEND); diff --git a/ui/__render_text.c b/ui/__render_text.c index 609e4bc..ee2514a 100644 --- a/ui/__render_text.c +++ b/ui/__render_text.c @@ -108,7 +108,7 @@ int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag) attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); if (attr) - abc_css_color(&r, &g, &b, attr->value->data); + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); cairo_set_font_size (cr, size); cairo_set_source_rgba(cr, r, g, b, 1.0); @@ -175,7 +175,7 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i if (obj->w <= 0 || obj->h <= 0) return 0; - int d = abc_css_margin(obj); + int d = obj->d; int x = obj->x + d; int y = obj->y + d; int w = obj->w - d * 2; @@ -205,7 +205,7 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i double b = 0.0; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); if (attr) - abc_css_color(&r, &g, &b, attr->value->data); + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w, h, w * 4); cr = cairo_create(surface); @@ -225,6 +225,22 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i surface = NULL; cr = NULL; + int view_x = x; + int view_y = y; + int view_w = w; + int view_h = h; + + switch (obj->overflow_type) + { + case ABC_OVERFLOW_HIDDEN: + abc_overflow_show(&view_x, &view_y, &view_w, &view_h, + obj->view_x, + obj->view_y, obj->view_w, obj->view_h); + break; + default: + break; + }; + float mvp[16]; __compute_mvp(mvp, 0, 0, 0); @@ -232,17 +248,32 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i GLfloat vert_update[] = { - 2.0 * x / (float)width - 1.0, - -2.0 * (y + h) / (float)height + 1.0, + 2.0 * view_x / (float)width - 1.0, + -2.0 * (view_y + view_h) / (float)height + 1.0, - 2.0 * (x + w) / (float)width - 1.0, - -2.0 * (y + h) / (float)height + 1.0, + 2.0 * (view_x + view_w) / (float)width - 1.0, + -2.0 * (view_y + view_h) / (float)height + 1.0, - 2.0 * x / (float)width - 1.0, - -2.0 * y / (float)height + 1.0, + 2.0 * view_x / (float)width - 1.0, + -2.0 * view_y / (float)height + 1.0, - 2.0 * (x + w) / (float)width - 1.0, - -2.0 * y / (float)height + 1.0, + 2.0 * (view_x + view_w) / (float)width - 1.0, + -2.0 * view_y / (float)height + 1.0, + }; + + GLfloat texture_update[] = + { + (view_x - x) / (float)w, + (view_y + view_h - y) / (float)h, + + (view_x + view_w - x) / (float)w, + (view_y + view_h - y) / (float)h, + + (view_x - x) / (float)w, + (view_y - y) / (float)h, + + (view_x + view_w - x) / (float)w, + (view_y - y) / (float)h, }; glUseProgram(program); @@ -261,6 +292,9 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update); + glBindBuffer (GL_ARRAY_BUFFER, buffers[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update); + glBindVertexArray(vao); glEnable(GL_BLEND); diff --git a/ui/abc_layout.c b/ui/abc_layout.c index 3528b78..de78ad1 100644 --- a/ui/abc_layout.c +++ b/ui/abc_layout.c @@ -1,8 +1,5 @@ #include"abc.h" -int abc_layout_html (abc_layout_t* layout, abc_obj_t* obj, int width, int height); -int abc_layout_title(abc_layout_t* layout, abc_obj_t* obj, int width, int height); -int abc_layout_head (abc_layout_t* layout, abc_obj_t* obj, int width, int height); int abc_layout_body (abc_layout_t* layout, abc_obj_t* obj, int width, int height); int abc_layout_text(abc_layout_t* layout, abc_obj_t* obj, int width, int height); @@ -28,10 +25,10 @@ int abc_layout_empty(abc_layout_t* layout, abc_obj_t* obj, int width, int height static abc_layout_pt abc_layouts[ABC_HTML_NB] = { - [ABC_HTML] = abc_layout_html, - [ABC_HTML_TITLE] = abc_layout_title, + [ABC_HTML] = abc_layout_empty, + [ABC_HTML_TITLE] = abc_layout_empty, [ABC_HTML_META] = abc_layout_empty, - [ABC_HTML_HEAD] = abc_layout_head, + [ABC_HTML_HEAD] = abc_layout_empty, [ABC_HTML_BODY] = abc_layout_body, [ABC_HTML_DIV] = abc_layout_div, @@ -89,21 +86,6 @@ int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height) return f(layout, obj, width, height); } -void abc_css_update_xy(abc_obj_t* root, int dx, int dy) -{ - scf_list_t* l; - abc_obj_t* obj; - - for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) { - obj = scf_list_data(l, abc_obj_t, list); - - obj->x += dx; - obj->y += dy; - - abc_css_update_xy(obj, dx, dy); - } -} - #define LAYOUT_POS_FIXED(X, W, SET, L, R) \ do { \ if (!obj->SET) { \ @@ -132,7 +114,7 @@ void abc_css_update_xy(abc_obj_t* root, int dx, int dy) do { \ abc_obj_t* tmp = parent; \ while (tmp && ABC_HTML != tmp->type) { \ - abc_obj_t* attr = abc_obj_get_attr(tmp, ABC_HTML_ATTR_POSITION); \ + abc_obj_t* attr = abc_obj_get_attr(tmp, ABC_CSS_POSITION); \ \ if (attr && attr->value->len > 0 \ && __html_strcmp(attr->value->data, "static")) \ @@ -175,10 +157,10 @@ int abc_layout_css(abc_obj_t* obj) else if (!__html_strcmp(attr->value->data, "right")) obj->x = parent->x + parent->w - obj->w - 8; - abc_css_update_xy(obj, obj->x - x, 0); + abc_dfs_update_xy(obj, obj->x - x, 0); } - attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_POSITION); + attr = abc_obj_get_attr(obj, ABC_CSS_POSITION); if (!attr || 0 == attr->value->len) return 0; @@ -191,19 +173,19 @@ int abc_layout_css(abc_obj_t* obj) int left = 0; int right = 0; - attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TOP); + attr = abc_obj_get_attr(obj, ABC_CSS_TOP); if (attr) top = abc_css_length(obj, attr->value->data, obj->h); - attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BOTTOM); + attr = abc_obj_get_attr(obj, ABC_CSS_BOTTOM); if (attr) bottom = abc_css_length(obj, attr->value->data, obj->h); - attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_LEFT); + attr = abc_obj_get_attr(obj, ABC_CSS_LEFT); if (attr) left = abc_css_length(obj, attr->value->data, obj->w); - attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_RIGHT); + attr = abc_obj_get_attr(obj, ABC_CSS_RIGHT); if (attr) right = abc_css_length(obj, attr->value->data, obj->w); @@ -231,7 +213,7 @@ int abc_layout_css(abc_obj_t* obj) break; }; - abc_css_update_xy(obj, obj->x - x, obj->y - y); + abc_dfs_update_xy(obj, obj->x - x, obj->y - y); return pos_type; } @@ -291,6 +273,8 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) break; }; + root->overflow_type = ABC_OVERFLOW_VISIBLE; + scf_list_t* l; abc_obj_t* child; @@ -419,15 +403,19 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height) if (root->h < Y - root->y) root->h = Y - root->y; + root->content_w = root->w; + root->content_h = root->h; + int ret = abc_layout_obj(NULL, root, width, height); if (ret < 0) return ret; #if 0 if (root->keys) scf_logw("key: %s, ", root->keys[0]); - if (root->text) - printf("%s, ", root->text->data); - printf("x: %d, y: %d, w: %d, h: %d\n", root->x, root->y, root->w, root->h); +// if (root->text) +// printf("%s, ", root->text->data); + printf("x: %d, y: %d, w: %d, h: %d, content_w: %d, content_h: %d: %d\n", + root->x, root->y, root->w, root->h, root->content_w, root->content_h, root->content_h - root->d * 2); #endif return 0; } diff --git a/ui/abc_layout_head.c b/ui/abc_layout_head.c deleted file mode 100644 index cb4d6c2..0000000 --- a/ui/abc_layout_head.c +++ /dev/null @@ -1,6 +0,0 @@ -#include"abc.h" - -int abc_layout_head(abc_layout_t* layout, abc_obj_t* obj, int width, int height) -{ - return 0; -} diff --git a/ui/abc_layout_html.c b/ui/abc_layout_html.c deleted file mode 100644 index 4615d4a..0000000 --- a/ui/abc_layout_html.c +++ /dev/null @@ -1,6 +0,0 @@ -#include"abc.h" - -int abc_layout_html(abc_layout_t* layout, abc_obj_t* obj, int width, int height) -{ - return 0; -} diff --git a/ui/abc_layout_table.c b/ui/abc_layout_table.c index e240c6b..23a727e 100644 --- a/ui/abc_layout_table.c +++ b/ui/abc_layout_table.c @@ -10,7 +10,7 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height int collapse = 0; - attr = abc_obj_find_attr(obj, ABC_CSS_BORDER_COLLAPSE); + attr = abc_obj_get_attr(obj, ABC_CSS_BORDER_COLLAPSE); if (attr) { if (!__html_strcmp(attr->value->data, "collapse")) { collapse = 1; @@ -18,7 +18,7 @@ int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height } } - int d = abc_css_margin(obj); + int d = obj->d; int w_set = abc_css_width (obj, width, d); int h_set = abc_css_height(obj, height, d); diff --git a/ui/abc_layout_title.c b/ui/abc_layout_title.c deleted file mode 100644 index 35e1965..0000000 --- a/ui/abc_layout_title.c +++ /dev/null @@ -1,6 +0,0 @@ -#include"abc.h" - -int abc_layout_title(abc_layout_t* layout, abc_obj_t* obj, int width, int height) -{ - return 0; -} diff --git a/ui/abc_render.c b/ui/abc_render.c index 961f059..a8e375c 100644 --- a/ui/abc_render.c +++ b/ui/abc_render.c @@ -1,8 +1,5 @@ #include"abc.h" -extern abc_render_t abc_render_html; -extern abc_render_t abc_render_title; -extern abc_render_t abc_render_head; extern abc_render_t abc_render_body; extern abc_render_t abc_render_text; @@ -30,7 +27,7 @@ static abc_render_t* abc_renders[ABC_HTML_NB] = [ABC_HTML] = &abc_render_empty, [ABC_HTML_HEAD] = &abc_render_empty, [ABC_HTML_META] = &abc_render_empty, - [ABC_HTML_TITLE] = &abc_render_title, + [ABC_HTML_TITLE] = &abc_render_empty, [ABC_HTML_BODY] = &abc_render_body, [ABC_HTML_DIV] = &abc_render_body, diff --git a/ui/abc_render_div.c b/ui/abc_render_div.c deleted file mode 100644 index 5768b28..0000000 --- a/ui/abc_render_div.c +++ /dev/null @@ -1,19 +0,0 @@ -#include"abc.h" - -static int _render_fini_div(abc_render_t* render) -{ - return 0; -} - -static int _render_draw_div(abc_render_t* render, abc_obj_t* obj, int width, int height) -{ - return 0; -} - -abc_render_t abc_render_div = -{ - .type = ABC_HTML_H1, - - .draw = _render_draw_div, - .fini = _render_fini_div, -}; diff --git a/ui/abc_render_head.c b/ui/abc_render_head.c deleted file mode 100644 index cef9af5..0000000 --- a/ui/abc_render_head.c +++ /dev/null @@ -1,19 +0,0 @@ -#include"abc.h" - -static int _render_fini_head(abc_render_t* render) -{ - return 0; -} - -static int _render_draw_head(abc_render_t* render, abc_obj_t* obj, int width, int height) -{ - return 0; -} - -abc_render_t abc_render_head = -{ - .type = ABC_HTML_H1, - - .draw = _render_draw_head, - .fini = _render_fini_head, -}; diff --git a/ui/abc_render_html.c b/ui/abc_render_html.c deleted file mode 100644 index 37f13ec..0000000 --- a/ui/abc_render_html.c +++ /dev/null @@ -1,19 +0,0 @@ -#include"abc.h" - -static int _render_fini_html(abc_render_t* render) -{ - return 0; -} - -static int _render_draw_html(abc_render_t* render, abc_obj_t* obj, int width, int height) -{ - return 0; -} - -abc_render_t abc_render_html = -{ - .type = ABC_HTML_H1, - - .draw = _render_draw_html, - .fini = _render_fini_html, -}; diff --git a/ui/abc_render_li.c b/ui/abc_render_li.c index 138f4af..ae56b27 100644 --- a/ui/abc_render_li.c +++ b/ui/abc_render_li.c @@ -71,7 +71,7 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); if (attr) - abc_css_color(&r, &g, &b, attr->value->data); + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4); cr = cairo_create(surface); @@ -139,7 +139,7 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int b = 0.0; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); if (attr) - abc_css_color(&r, &g, &b, attr->value->data); + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); cairo_set_source_rgb(cr, r, g, b); diff --git a/ui/abc_render_td.c b/ui/abc_render_td.c index c9a8840..07d9136 100644 --- a/ui/abc_render_td.c +++ b/ui/abc_render_td.c @@ -96,7 +96,7 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int double b = 1.0; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); if (attr) - abc_css_color(&r, &g, &b, attr->value->data); + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); cairo_set_source_rgb(cr, r, g, b); cairo_rectangle(cr, 0, 0, w, h); @@ -109,7 +109,7 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int b = 0.0; attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); if (attr) - abc_css_color(&r, &g, &b, attr->value->data); + abc_css_color(&r, &g, &b, attr->value->data, attr->value->len); cairo_set_source_rgb(cr, r, g, b); diff --git a/ui/abc_render_text.c b/ui/abc_render_text.c index 5c77f91..dae5e77 100644 --- a/ui/abc_render_text.c +++ b/ui/abc_render_text.c @@ -109,6 +109,9 @@ static int _draw_text_line(abc_obj_t* obj, const char* text, glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update); + glBindBuffer (GL_ARRAY_BUFFER, buffers[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_array), texture_array); + glBindVertexArray(vao); glEnable(GL_BLEND); @@ -150,11 +153,11 @@ static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, in attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR); if (attr) - abc_css_color(bcolor, bcolor + 1, bcolor + 2, attr->value->data); + abc_css_color(bcolor, bcolor + 1, bcolor + 2, attr->value->data, attr->value->len); attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR); if (attr) - abc_css_color(fcolor, fcolor + 1, fcolor + 2, attr->value->data); + abc_css_color(fcolor, fcolor + 1, fcolor + 2, attr->value->data, attr->value->len); attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE); if (attr) diff --git a/ui/abc_render_title.c b/ui/abc_render_title.c deleted file mode 100644 index 3c53e7a..0000000 --- a/ui/abc_render_title.c +++ /dev/null @@ -1,19 +0,0 @@ -#include"abc.h" - -static int _render_fini_title(abc_render_t* render) -{ - return 0; -} - -static int _render_draw_title(abc_render_t* render, abc_obj_t* obj, int width, int height) -{ - return 0; -} - -abc_render_t abc_render_title = -{ - .type = ABC_HTML_H1, - - .draw = _render_draw_title, - .fini = _render_fini_title, -}; diff --git a/ui/main.c b/ui/main.c index 2c2f4d3..104eeca 100644 --- a/ui/main.c +++ b/ui/main.c @@ -89,6 +89,18 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y) abc_css_active(prev); + prev->mouse_down_x = -1; + prev->mouse_down_y = -1; + prev->mouse_move_x = -1; + prev->mouse_move_y = -1; + + if (ABC_HTML_DIV == prev->type) + scf_logw("prev: %p mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", prev, + prev->mouse_down_x, + prev->mouse_down_y, + prev->mouse_move_x, + prev->mouse_move_y); + prev->clicked = 0; ret = 1; } @@ -97,6 +109,8 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y) scf_logd("obj: %s, type: %d, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n", obj->keys[0], obj->type, obj->x, obj->y, obj->w, obj->h, x, y); + int scroll_width = 25; + switch (obj->type) { case ABC_HTML_A: @@ -125,10 +139,31 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y) } } break; + + case ABC_HTML_DIV: + attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TYPE); + + if (attr && attr->value->len > 0) + scroll_width = atoi(attr->value->data); + + if (obj->x + obj->w > scroll_width + && obj->mouse_move_x > obj->x + obj->w - scroll_width + && obj->mouse_move_x < obj->x + obj->w + && obj->mouse_move_y > obj->y + && obj->mouse_move_y < obj->y + obj->h) + ret = 1; + break; default: break; }; + if (ABC_HTML_DIV == obj->type) + scf_logw("obj: %p, mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", obj, + obj->mouse_down_x, + obj->mouse_down_y, + obj->mouse_move_x, + obj->mouse_move_y); + obj->css_pse_type = ABC_CSS_HOVER; ret |= abc_css_active(obj); @@ -184,6 +219,11 @@ static int __do_button_release(abc_ctx_t* ctx, int x, int y) if (!obj) return __do_button_move(ctx, x, y); + obj->mouse_down_x = -1; + obj->mouse_down_y = -1; + obj->mouse_move_x = -1; + obj->mouse_move_y = -1; + obj->visited = 1; obj->css_pse_type = ABC_CSS_VISITED; @@ -341,6 +381,16 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin abc_obj_t* css; if (obj) { + obj->mouse_down_x = event->x; + obj->mouse_down_y = event->y; + + if (ABC_HTML_DIV == obj->type) + scf_logw("obj: %p mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", obj, + obj->mouse_down_x, + obj->mouse_down_y, + obj->mouse_move_x, + obj->mouse_move_y); + obj->css_pse_type = ABC_CSS_ACTIVE; if (abc_css_active(obj) > 0) @@ -405,7 +455,17 @@ static gboolean key_press_event(GtkWidget* self, GdkEventKey* event, gpointer us static gboolean button_move_event(GtkWidget* self, GdkEventMotion* event, gpointer user_data) { - abc_ctx_t* ctx = user_data; + abc_ctx_t* ctx = user_data; + abc_obj_t* obj; + + if (ctx->current->io.download && ctx->current->root) + { + obj = abc_obj_find(ctx->current->root, event->x, event->y); + if (obj) { + obj->mouse_move_x = event->x; + obj->mouse_move_y = event->y; + } + } int ret = __do_button_move(ctx, event->x, event->y); if (ret > 0) @@ -582,8 +642,8 @@ int main(int argc, char *argv[]) g_signal_connect(window, "button-release-event", G_CALLBACK(button_release_event), &ctx); g_signal_connect(window, "button-press-event", G_CALLBACK(button_press_event), &ctx); - g_signal_connect(window, "key-press-event", G_CALLBACK(key_press_event), &ctx); - g_signal_connect(gl_area, "motion-notify-event", G_CALLBACK(button_move_event), &ctx); + g_signal_connect(gl_area, "key-press-event", G_CALLBACK(key_press_event), &ctx); + g_signal_connect(window, "motion-notify-event", G_CALLBACK(button_move_event), &ctx); g_timeout_add(1, timer_handler, &ctx);