From 0c3be46d35123d257ccd951c6cf962dbbf809e20 Mon Sep 17 00:00:00 2001
From: "yu.dongliang" <18588496441@163.com>
Date: Tue, 19 May 2026 19:19:22 +0800
Subject: [PATCH] css: support a simple scroll-bar with 'scrollbar-width' &
'scrollbar-color' as CSS asked
---
examples/overflow.html | 9 +-
html/abc_css_border.c | 2 +-
html/abc_css_color.c | 100 +++++++++++++----
html/abc_css_position.c | 39 +++++++
html/abc_html.c | 54 ++++-----
html/abc_html.h | 5 +-
html/abc_obj.c | 15 +++
html/abc_obj.h | 58 +++++++---
ui/Makefile | 6 -
ui/__render_bg_image.c | 5 +-
ui/__render_border.c | 236 ++++++++++++++++++++++++++++++++++++----
ui/__render_text.c | 56 ++++++++--
ui/abc_layout.c | 52 ++++-----
ui/abc_layout_head.c | 6 -
ui/abc_layout_html.c | 6 -
ui/abc_layout_table.c | 4 +-
ui/abc_layout_title.c | 6 -
ui/abc_render.c | 5 +-
ui/abc_render_div.c | 19 ----
ui/abc_render_head.c | 19 ----
ui/abc_render_html.c | 19 ----
ui/abc_render_li.c | 4 +-
ui/abc_render_td.c | 4 +-
ui/abc_render_text.c | 7 +-
ui/abc_render_title.c | 19 ----
ui/main.c | 66 ++++++++++-
26 files changed, 572 insertions(+), 249 deletions(-)
delete mode 100644 ui/abc_layout_head.c
delete mode 100644 ui/abc_layout_html.c
delete mode 100644 ui/abc_layout_title.c
delete mode 100644 ui/abc_render_div.c
delete mode 100644 ui/abc_render_head.c
delete mode 100644 ui/abc_render_html.c
delete mode 100644 ui/abc_render_title.c
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);
--
2.25.1