From 5d33e3813035c803606efa055578b2ab36f3f28e Mon Sep 17 00:00:00 2001
From: "yu.dongliang" <18588496441@163.com>
Date: Fri, 17 Apr 2026 23:38:52 +0800
Subject: [PATCH] html: add
, , - for list
---
examples/list.html | 42 +++++++
examples/style.css | 10 +-
ffmpeg/abc_avio.c | 1 -
ffmpeg/abc_ffmpeg.h | 2 +
ffmpeg/abc_ffmpeg_alsa.c | 44 ++++---
ffmpeg/abc_ffmpeg_img.c | 2 +-
html/abc_css.c | 139 +++++++++++++++++++---
html/abc_css_color.c | 2 +-
html/abc_html.c | 96 +++++++++++----
html/abc_obj.h | 22 +++-
ui/Makefile | 1 +
ui/abc.h | 2 +
ui/abc_layout.c | 10 ++
ui/abc_layout_video.c | 2 +-
ui/abc_render.c | 5 +
ui/abc_render_a_href.c | 28 ++---
ui/abc_render_bg_image.c | 6 +-
ui/abc_render_h1.c | 7 +-
ui/abc_render_li.c | 249 +++++++++++++++++++++++++++++++++++++++
ui/main.c | 73 ++++++++++--
20 files changed, 637 insertions(+), 106 deletions(-)
create mode 100644 examples/list.html
create mode 100644 ui/abc_render_li.c
diff --git a/examples/list.html b/examples/list.html
new file mode 100644
index 0000000..6e12ce1
--- /dev/null
+++ b/examples/list.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
æ åºå表å®ä¾:
+
+
+ - Coffee
+ - Tea
+ - Coca Cola
+
+
+
+ - Coffee
+ - Tea
+ - Coca Cola
+
+
+æåºå表å®ä¾:
+
+
+ - Coffee
+ - Tea
+ - Coca Cola
+
+
+
+ - Coffee
+ - Tea
+ - Coca Cola
+
+
+
+
diff --git a/examples/style.css b/examples/style.css
index f853881..ddfedd4 100644
--- a/examples/style.css
+++ b/examples/style.css
@@ -1,13 +1,13 @@
body
{
background: #b0c4de url('img.png') no-repeat right top ;
-/* background-color:#b0c4de;
- background-image:url('img.png');
- background-position:right top;
- background-repeat:no-repeat; */
}
h1 {background-color:#6495ed;}
-a {text-decoration:none;}
+
+a:link {text-decoration:none; color:#000000;} /* unvisited link */
+a:visited {text-decoration:none; color:#00ff00;} /* visited link */
+a:hover {text-decoration:underline; color:#ff00ff;} /* mouse over link */
+a:active {text-decoration:underline; color:#0000ff;} /* selected link */
#a /*css comment*/
{
diff --git a/ffmpeg/abc_avio.c b/ffmpeg/abc_avio.c
index 7874fcc..1fc5729 100644
--- a/ffmpeg/abc_avio.c
+++ b/ffmpeg/abc_avio.c
@@ -78,7 +78,6 @@ int abc_avio_open(abc_avio_t** pio, const char* type, const char* in, const char
io->ops = ops;
if (ops->open) {
-
int ret = ops->open(io, in, out);
if (ret < 0) {
free(io);
diff --git a/ffmpeg/abc_ffmpeg.h b/ffmpeg/abc_ffmpeg.h
index 577020f..6843377 100644
--- a/ffmpeg/abc_ffmpeg.h
+++ b/ffmpeg/abc_ffmpeg.h
@@ -85,6 +85,8 @@ typedef struct {
int idx_out;
int nb_samples;
+
+ uint8_t write_header:1;
} abc_audio_t;
struct abc_avio_s
diff --git a/ffmpeg/abc_ffmpeg_alsa.c b/ffmpeg/abc_ffmpeg_alsa.c
index 47671a6..9eb8aae 100644
--- a/ffmpeg/abc_ffmpeg_alsa.c
+++ b/ffmpeg/abc_ffmpeg_alsa.c
@@ -90,7 +90,7 @@ end:
static int _audio_input_init(abc_audio_t* priv, const char* path)
{
- const AVInputFormat* in = av_find_input_format("alsa");
+ const AVInputFormat* in = av_find_input_format("pulse");
if (!in)
return -EINVAL;
@@ -151,7 +151,7 @@ static int _audio_input_init(abc_audio_t* priv, const char* path)
static int _audio_output_init(abc_audio_t* priv, const char* path)
{
- const AVOutputFormat* out = av_guess_format("alsa", NULL, NULL);
+ const AVOutputFormat* out = av_guess_format("pulse", NULL, NULL);
scf_logi("out: %p, path: %s\n", out, path);
@@ -163,6 +163,15 @@ static int _audio_output_init(abc_audio_t* priv, const char* path)
priv->ctx_out->flags |= AVFMT_FLAG_NONBLOCK;
+ if (priv->ctx_out->oformat->priv_class) {
+ AVDictionary* options = NULL;
+
+ av_dict_set(&options, "buffer_duration", "50", 0);
+
+ av_opt_set_dict2(priv->ctx_out->priv_data, &options, AV_OPT_SEARCH_CHILDREN);
+ av_dict_free(&options);
+ }
+
const AVCodec* c = avcodec_find_encoder(out->audio_codec);
if (!c)
return -EINVAL;
@@ -435,10 +444,8 @@ static int __output_audio(abc_avio_t* io, AVCodecContext* c, AVPacket* pkt, AVFr
av_packet_unref(pkt);
- if (ret < 0) {
- scf_loge("av_write_frame error, ret: %s\n", av_err2str(ret));
- return ret;
- }
+ if (ret < 0)
+ scf_logw("av_write_frame error, ret: %s\n", av_err2str(ret));
}
}
@@ -507,7 +514,7 @@ static void* __ffmpeg_alsa_run(void* arg)
{
abc_avio_t* io = arg;
abc_audio_t* priv = io->priv;
- scf_list_t ih;
+ scf_list_t ih;
int ret;
@@ -525,18 +532,25 @@ static void* __ffmpeg_alsa_run(void* arg)
goto end;
}
}
-
- ret = avformat_write_header(priv->ctx_out, NULL);
- if (ret < 0) {
- scf_loge("avformat_write_header error, ret: %s\n", av_err2str(ret));
- io->error = ret;
- goto end;
- }
}
while (!io->exit) {
- if (priv->ctx_out) {
+ if (priv->ctx_out)
+ {
+ if (!priv->write_header) {
+ ret = avformat_write_header(priv->ctx_out, NULL);
+ if (ret < 0) {
+ scf_loge("avformat_write_header error, ret: %s\n", av_err2str(ret));
+
+ io->error = ret;
+ usleep(100);
+ continue;
+ }
+
+ priv->write_header = 1;
+ }
+
ret = __output_audio(io, priv->codec_out, priv->opkt, priv->oframe);
if (ret < 0) {
io->error = ret;
diff --git a/ffmpeg/abc_ffmpeg_img.c b/ffmpeg/abc_ffmpeg_img.c
index 39380c8..2ff3d89 100644
--- a/ffmpeg/abc_ffmpeg_img.c
+++ b/ffmpeg/abc_ffmpeg_img.c
@@ -244,7 +244,7 @@ int abc_img_read(abc_img_t* img, uint8_t* bgra, int size)
assert(img->width == frame2->width);
assert(img->height == frame2->height);
- scf_logi("frame2->linesize[0]: %d\n", frame2->linesize[0]);
+ scf_logd("frame2->linesize[0]: %d\n", frame2->linesize[0]);
int i;
for (i = 0; i < frame2->height; i++)
diff --git a/html/abc_css.c b/html/abc_css.c
index 859e07f..1cd5527 100644
--- a/html/abc_css.c
+++ b/html/abc_css.c
@@ -85,7 +85,7 @@ static int __css_parse_value(abc_obj_t* css, abc_obj_t* attr)
css->text_pos = 0;
}
- if (';' == c->c || EOF == c->c)
+ if (';' == c->c || '}' == c->c || EOF == c->c)
break;
else
scf_string_cat_cstr_len(value, c->utf8, c->len);
@@ -249,7 +249,8 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
return -ENOMEM;
int ret;
- int dot = -1;
+ int dot = -1;
+ int colon = -1;
while (1) {
c = __io_pop_char(&css->io);
@@ -286,6 +287,9 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
if (dot < 0 && '.' == c->c)
dot = key->len;
+ if (colon < 0 && ':' == c->c)
+ colon = key->len;
+
scf_string_cat_cstr_len(key, c->utf8, c->len);
}
@@ -311,6 +315,8 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
default:
if (dot >= 0)
label = __html_find_label2(ABC_CSS_CLASS);
+ else if (colon >= 0)
+ label = __html_find_label(key->data + colon);
else
label = __html_find_label(key->data);
break;
@@ -328,15 +334,27 @@ static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
return -ENOMEM;
}
- obj->css_dot = dot;
- obj->flags = label->flags;
- obj->keys = label->names;
- obj->parent = css;
+ obj->css_dot = dot;
+ obj->css_colon = colon;
+ obj->flags = label->flags;
+ obj->keys = label->names;
+ obj->parent = css;
+
+ switch (obj->type) {
+ case ABC_CSS_ID:
+ case ABC_CSS_CLASS:
+
+ case ABC_CSS_LINK:
+ case ABC_CSS_VISITED:
+ case ABC_CSS_HOVER:
+ case ABC_CSS_ACTIVE:
+ obj->text = key;
+ break;
- if (ABC_CSS_ID == obj->type || ABC_CSS_CLASS == obj->type)
- obj->text = key;
- else
- scf_string_free(key);
+ default:
+ scf_string_free(key);
+ break;
+ };
key = NULL;
switch (tmp) {
@@ -595,6 +613,53 @@ static void __css_set_attr(abc_obj_t* obj, abc_obj_t* attr)
};
}
+static void __css_set_status(abc_obj_t* obj, abc_obj_t* status)
+{
+ scf_list_t* l;
+ abc_obj_t* attr;
+ abc_obj_t* attr2;
+ abc_obj_t* status2;
+
+ if (scf_list_empty(&status->attrs))
+ return;
+
+ status2 = abc_obj_alloc(status->file, status->line, status->pos, status->type);
+ if (!status2)
+ return;
+ status2->flags = status->flags;
+ status2->keys = status->keys;
+
+ for (l = scf_list_head(&status->attrs); l != scf_list_sentinel(&status->attrs); l = scf_list_next(l)) {
+ attr = scf_list_data(l, abc_obj_t, list);
+
+ if (attr->value && attr->value->len > 0)
+ {
+ if (ABC_CSS_LINK == status->type)
+ __css_set_attr(obj, attr);
+
+ attr2 = abc_obj_alloc(attr->file, attr->line, attr->pos, attr->type);
+ if (!attr2) {
+ abc_obj_free(status2);
+ return;
+ }
+
+ attr2->value = scf_string_clone(attr->value);
+ if (!attr2->value) {
+ abc_obj_free(attr2);
+ abc_obj_free(status2);
+ return;
+ }
+
+ attr2->keys = attr->keys;
+ attr2->flags = attr->flags;
+
+ scf_list_add_tail(&status2->attrs, &attr2->list);
+ }
+ }
+
+ scf_list_add_tail(&obj->attrs, &status2->list);
+}
+
static void __css_merge(abc_obj_t* dst, abc_obj_t* src)
{
scf_list_t* l;
@@ -646,8 +711,14 @@ int abc_css_merge(abc_html_t* html, abc_obj_t* css)
switch (dst->type) {
case ABC_CSS_ID:
case ABC_CSS_CLASS:
+
+ case ABC_CSS_LINK:
+ case ABC_CSS_VISITED:
+ case ABC_CSS_HOVER:
+ case ABC_CSS_ACTIVE:
ret = scf_string_cmp(src->text, dst->text);
break;
+
default:
ret = __html_strcmp(src->keys[0], dst->keys[0]);
break;
@@ -669,10 +740,20 @@ int abc_css_merge(abc_html_t* html, abc_obj_t* css)
src = scf_list_data(s, abc_obj_t, list);
s = scf_list_next(s);
- if (ABC_CSS_ID == src->type || ABC_CSS_CLASS == src->type) {
- scf_list_del(&src->list);
- scf_list_add_tail(&h, &src->list);
- }
+ switch (src->type) {
+ case ABC_CSS_ID:
+ case ABC_CSS_CLASS:
+
+ case ABC_CSS_LINK:
+ case ABC_CSS_VISITED:
+ case ABC_CSS_HOVER:
+ case ABC_CSS_ACTIVE:
+ scf_list_del(&src->list);
+ scf_list_add_tail(&h, &src->list);
+ break;
+ default:
+ break;
+ };
}
scf_list_mov2(&html->css->childs, &h);
@@ -690,6 +771,7 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
scf_list_t* l;
scf_list_t* l2;
abc_obj_t* css;
+ abc_obj_t* __obj;
abc_obj_t* attr;
for (l = scf_list_head(&html->css->childs); l != scf_list_sentinel(&html->css->childs); l = scf_list_next(l)) {
@@ -709,14 +791,21 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
continue;
}
- } else if (css->type != obj->type)
+ } else if (ABC_CSS_LINK == css->type
+ || ABC_CSS_VISITED == css->type
+ || ABC_CSS_HOVER == css->type
+ || ABC_CSS_ACTIVE == css->type) {
+
+ if (css->css_colon > 0) {
+ if (!__html_strncmp (obj->keys[0], css->text->data, css->css_colon))
+ __css_set_status(obj, css);
+ }
continue;
- for (l2 = scf_list_head(&css->attrs); l2 != scf_list_sentinel(&css->attrs); l2 = scf_list_next(l2)) {
- attr = scf_list_data(l2, abc_obj_t, list);
+ } else if (css->type != obj->type)
+ continue;
- __css_set_attr(obj, attr);
- }
+ abc_obj_set_css(obj, css);
}
// for inline css below
@@ -760,3 +849,15 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
return 0;
}
+
+void abc_obj_set_css(abc_obj_t* obj, abc_obj_t* css)
+{
+ scf_list_t* l;
+ abc_obj_t* attr;
+
+ for (l = scf_list_head(&css->attrs); l != scf_list_sentinel(&css->attrs); l = scf_list_next(l)) {
+ attr = scf_list_data(l, abc_obj_t, list);
+
+ __css_set_attr(obj, attr);
+ }
+}
diff --git a/html/abc_css_color.c b/html/abc_css_color.c
index 974b8ba..e2c2945 100644
--- a/html/abc_css_color.c
+++ b/html/abc_css_color.c
@@ -92,7 +92,7 @@ static char* css_Lime[] = {"Lime", NULL};
static char* css_LimeGreen[] = {"LimeGreen", NULL};
static char* css_Linen[] = {"Linen", NULL};
-static char* css_magenta[] = {"Magenta", "å红", "æ´çº¢", NULL};
+static char* css_magenta[] = {"Magenta", "å红", NULL};
static char* css_Maroon[] = {"Maroon", NULL};
static char* css_MediumAquaMarine[] = {"MediumAquaMarine", NULL};
static char* css_MediumBlue[] = {"MediumBlue", "ä¸è", NULL};
diff --git a/html/abc_html.c b/html/abc_html.c
index 3538927..10cf7ed 100644
--- a/html/abc_html.c
+++ b/html/abc_html.c
@@ -13,16 +13,21 @@ static char* font_size_keys[] = {"font-size", "åå·", NULL};
static char* font_color_keys[] = {"font-color", "åä½é¢è²", "color", "é¢è²", NULL};
static char* font_style_keys[] = {"style", "åä½é£æ ¼", NULL};
-static char* text_align_keys[] = {"text-align", "对é½", NULL};
-static char* text_decoration_keys[] = {"text-decoration", "ä¸å线", NULL};
-static char* text_transform_keys[] = {"text-transform", "大å°å", NULL};
-static char* text_indent_keys[] = {"text-transform", "缩è¿", NULL};
-
-static char* bg_keys[] = {"background", "èæ¯", NULL};
-static char* bg_color_keys[] = {"background-color", "èæ¯é¢è²", NULL};
-static char* bg_image_keys[] = {"background-image", "èæ¯å¾ç", NULL};
-static char* bg_repeat_keys[] = {"background-repeat", "èæ¯éå¤", NULL};
-static char* bg_position_keys[] = {"background-position", "èæ¯ä½ç½®", NULL};
+static char* text_align_keys[] = {"text-align", "对é½", NULL};
+static char* text_decoration_keys[] = {"text-decoration", "ä¸å线", NULL};
+static char* text_transform_keys[] = {"text-transform", "大å°å", NULL};
+static char* text_indent_keys[] = {"text-transform", "缩è¿", NULL};
+
+static char* bg_keys[] = {"background", "èæ¯", NULL};
+static char* bg_color_keys[] = {"background-color", "èæ¯é¢è²", NULL};
+static char* bg_image_keys[] = {"background-image", "èæ¯å¾ç", NULL};
+static char* bg_repeat_keys[] = {"background-repeat", "èæ¯éå¤", NULL};
+static char* bg_position_keys[] = {"background-position", "èæ¯ä½ç½®", 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};
+static char* list_style_pos_keys[] = {"list-style-position", "å表æ è®°ä½ç½®", NULL};
static char* class_keys[] = {"class", "ç±»å", NULL};
static char* type_keys[] = {"type", "ç±»å", NULL};
@@ -70,6 +75,10 @@ static char* table_keys[] = {"table", "è¡¨æ ¼", NULL};
static char* tr_keys[] = {"tr", "è¡", NULL};
static char* td_keys[] = {"td", "å", NULL};
+static char* ol_keys[] = {"ol", "æåºå表", NULL};
+static char* ul_keys[] = {"ul", "æ åºå表", NULL};
+static char* li_keys[] = {"li", "å表项", NULL};
+
static char* br_keys[] = {"br", "æ¢è¡", NULL};
static char* hr_keys[] = {"hr", "æ 颿¢è¡", NULL};
@@ -90,8 +99,13 @@ static char* progress_keys[] = {"progress", "è¿åº¦æ¡", NULL};
static char* script_keys[] = {"script", "èæ¬", NULL};
static char* style_keys[] = {"style", "æ ·å¼", NULL};
-static char* css_id_keys[] = {"#", NULL};
-static char* css_class_keys[] = {".", NULL};
+static char* css_id_keys[] = {"#", NULL};
+static char* css_class_keys[] = {".", NULL};
+
+static char* css_link_keys[] = {":link", ":æªè®¿é®", NULL};
+static char* css_visited_keys[] = {":visited", ":已访é®", NULL};
+static char* css_hover_keys[] = {":hover", ":å·²å
³æ³¨", NULL};
+static char* css_active_keys[] = {":active", ":å·²æ¿æ´»", NULL};
static html_attr_t html_attrs[] =
{
@@ -254,17 +268,22 @@ static html_attr_t p_attrs[] =
static html_attr_t css_id_attrs[] =
{
- {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
- {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
- {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
- {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0},
-
- {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW},
-
- {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
- {text_decoration_keys, "", ABC_HTML_ATTR_TEXT_DECORATION, ABC_HTML_FLAG_SHOW},
- {text_transform_keys, "", ABC_HTML_ATTR_TEXT_TRANSFORM, ABC_HTML_FLAG_SHOW},
- {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW},
+ {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+ {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
+ {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0},
+
+ {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW},
+
+ {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+ {text_decoration_keys, "", ABC_HTML_ATTR_TEXT_DECORATION, ABC_HTML_FLAG_SHOW},
+ {text_transform_keys, "", ABC_HTML_ATTR_TEXT_TRANSFORM, ABC_HTML_FLAG_SHOW},
+ {text_indent_keys, "", ABC_HTML_ATTR_TEXT_INDENT, ABC_HTML_FLAG_SHOW},
+
+ {list_style_keys, "", ABC_CSS_LIST_STYLE, ABC_HTML_FLAG_SHOW},
+ {list_style_type_keys, "", ABC_CSS_LIST_STYLE_TYPE, ABC_HTML_FLAG_SHOW},
+ {list_style_image_keys, "", ABC_CSS_LIST_STYLE_IMAGE, ABC_HTML_FLAG_SHOW},
+ {list_style_pos_keys, "", ABC_CSS_LIST_STYLE_POSITION, ABC_HTML_FLAG_SHOW},
};
static html_attr_t b_attrs[] =
@@ -303,6 +322,7 @@ static html_attr_t a_attrs[] =
{class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW},
{style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW},
{id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW},
+
{font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
{font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
{font_color_keys, "blue", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
@@ -378,6 +398,23 @@ static html_attr_t form_attrs[] =
{enctype_keys, "", ABC_HTML_ATTR_ENCTYPE, 0},
};
+static html_attr_t ol_attrs[] =
+{
+ {class_keys, "", ABC_HTML_ATTR_CLASS, ABC_HTML_FLAG_SHOW},
+ {style_keys, "", ABC_HTML_ATTR_STYLE, ABC_HTML_FLAG_SHOW},
+ {id_keys, "", ABC_HTML_ATTR_ID, ABC_HTML_FLAG_SHOW},
+ {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+ {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
+ {font_style_keys, "", ABC_HTML_ATTR_FONT_STYLE, 0},
+
+ {bg_color_keys, "", ABC_HTML_ATTR_BG_COLOR, ABC_HTML_FLAG_SHOW},
+
+ {list_style_type_keys, "", ABC_CSS_LIST_STYLE_TYPE, ABC_HTML_FLAG_SHOW},
+ {list_style_image_keys, "", ABC_CSS_LIST_STYLE_IMAGE, ABC_HTML_FLAG_SHOW},
+ {list_style_pos_keys, "", ABC_CSS_LIST_STYLE_POSITION, ABC_HTML_FLAG_SHOW},
+};
+
static html_attr_t script_attrs[] =
{
{font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
@@ -420,6 +457,10 @@ static html_label_t html_labels[] =
{tr_keys, ABC_HTML_TR, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{td_keys, ABC_HTML_TD, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {ol_keys, ABC_HTML_OL, abc_number_of(ol_attrs), ol_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {ul_keys, ABC_HTML_UL, abc_number_of(ol_attrs), ol_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {li_keys, ABC_HTML_LI, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+
{video_keys, ABC_HTML_VIDEO, abc_number_of(video_attrs), video_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{audio_keys, ABC_HTML_AUDIO, abc_number_of(audio_attrs), audio_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{source_keys, ABC_HTML_SOURCE, abc_number_of(source_attrs), source_attrs, ABC_HTML_FLAG_OPEN | ABC_HTML_FLAG_SHOW},
@@ -429,8 +470,13 @@ static html_label_t html_labels[] =
{script_keys, ABC_HTML_SCRIPT, abc_number_of(script_attrs), script_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{style_keys, ABC_HTML_STYLE, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
- {css_id_keys, ABC_CSS_ID, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
- {css_class_keys, ABC_CSS_CLASS, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {css_id_keys, ABC_CSS_ID, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {css_class_keys, ABC_CSS_CLASS, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+
+ {css_link_keys, ABC_CSS_LINK, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {css_visited_keys, ABC_CSS_VISITED, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {css_hover_keys, ABC_CSS_HOVER, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+ {css_active_keys, ABC_CSS_ACTIVE, abc_number_of(css_id_attrs), css_id_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
};
static int __html_parse_obj(abc_html_t* html, abc_char_t* c);
diff --git a/html/abc_obj.h b/html/abc_obj.h
index 49dda16..8f27334 100644
--- a/html/abc_obj.h
+++ b/html/abc_obj.h
@@ -62,6 +62,10 @@ enum abc_objs
ABC_HTML_B,
ABC_HTML_I,
+ ABC_HTML_OL,
+ ABC_HTML_UL,
+ ABC_HTML_LI,
+
ABC_HTML_NB, // total HTML objects
ABC_HTML_ATTR_ID,
@@ -112,6 +116,19 @@ enum abc_objs
ABC_HTML_ATTR_CONTROLS,
// css objects
+ ABC_CSS_LINK,
+ ABC_CSS_VISITED,
+ ABC_CSS_HOVER,
+ ABC_CSS_ACTIVE,
+
+ ABC_CSS_LIST_STYLE,
+ ABC_CSS_LIST_STYLE_TYPE,
+ ABC_CSS_LIST_STYLE_IMAGE,
+ ABC_CSS_LIST_STYLE_POSITION,
+
+ // ... new css add here
+
+ // css enum from html attrs above
ABC_CSS_ID = ABC_HTML_ATTR_ID,
ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS,
};
@@ -153,7 +170,8 @@ struct abc_obj_s
int text_pos;
abc_io_t io;
- int css_dot; // dot position for css class
+ int css_dot; // dot position for css class
+ int css_colon; // colon position for css status
scf_string_t* file; // file name
int line; // line
@@ -165,6 +183,7 @@ struct abc_obj_s
scf_string_t* js_entry;
uint32_t clicked:1;
+ uint32_t visited:1;
};
abc_obj_t* abc_obj_alloc(scf_string_t* file, int line, int pos, int type);
@@ -172,6 +191,7 @@ void abc_obj_free (abc_obj_t* obj);
abc_obj_t* abc_obj_find (abc_obj_t* root, int x, int y);
void abc_obj_print(abc_obj_t* obj);
+void abc_obj_set_css (abc_obj_t* obj, abc_obj_t* css);
int abc_obj_set_attr (abc_obj_t* obj, int key, const char* value, size_t len);
abc_obj_t* abc_obj_get_attr (abc_obj_t* obj, int key);
abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key);
diff --git a/ui/Makefile b/ui/Makefile
index c2d8c9d..86344a7 100644
--- a/ui/Makefile
+++ b/ui/Makefile
@@ -39,6 +39,7 @@ CFILES += abc_render_input.c
CFILES += abc_render_table.c
CFILES += abc_render_tr.c
CFILES += abc_render_td.c
+CFILES += abc_render_li.c
CFILES += abc_render_video.c
CFILES += abc_render_audio.c
diff --git a/ui/abc.h b/ui/abc.h
index 4ed637a..6c85004 100644
--- a/ui/abc.h
+++ b/ui/abc.h
@@ -76,4 +76,6 @@ int __init_program(GLuint* pprog, const char* vert_shader, const char* frag_sha
int __init_buffers(GLuint* vao, GLuint buffers[2]);
+int __init_text(cairo_t* cr, abc_obj_t* obj, double dx);
+
#endif
diff --git a/ui/abc_layout.c b/ui/abc_layout.c
index 2c0c4ee..84882f4 100644
--- a/ui/abc_layout.c
+++ b/ui/abc_layout.c
@@ -54,6 +54,10 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] =
[ABC_HTML_TR] = abc_layout_empty,
[ABC_HTML_TD] = abc_layout_td,
+ [ABC_HTML_OL] = abc_layout_empty,
+ [ABC_HTML_UL] = abc_layout_empty,
+ [ABC_HTML_LI] = abc_layout_h1,
+
[ABC_HTML_VIDEO] = abc_layout_video,
[ABC_HTML_AUDIO] = abc_layout_audio,
[ABC_HTML_SOURCE] = abc_layout_empty,
@@ -176,6 +180,9 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
case ABC_HTML_H4:
case ABC_HTML_H5:
case ABC_HTML_H6:
+ case ABC_HTML_OL:
+ case ABC_HTML_UL:
+ case ABC_HTML_LI:
child->x = root->x + 4;
child->y = y + h;
@@ -183,6 +190,9 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
if (ret < 0)
return ret;
+ if (ABC_HTML_UL == root->type || ABC_HTML_OL == root->type)
+ child->w += 16;
+
x = root->x + 4;
y = child->y + child->h;
h = 0;
diff --git a/ui/abc_layout_video.c b/ui/abc_layout_video.c
index c7caa07..a0f107a 100644
--- a/ui/abc_layout_video.c
+++ b/ui/abc_layout_video.c
@@ -57,7 +57,7 @@ static int __av_filter_init(abc_obj_t* obj)
}
if (avin->aopen) {
- ret = abc_avio_open(&aout, "ffmpeg_alsa", NULL, "hw:0");
+ ret = abc_avio_open(&aout, "ffmpeg_alsa", NULL, "");
if (ret < 0)
goto error;
diff --git a/ui/abc_render.c b/ui/abc_render.c
index 6811585..50586a6 100644
--- a/ui/abc_render.c
+++ b/ui/abc_render.c
@@ -19,6 +19,7 @@ extern abc_render_t abc_render_input;
extern abc_render_t abc_render_table;
extern abc_render_t abc_render_tr;
extern abc_render_t abc_render_td;
+extern abc_render_t abc_render_li;
extern abc_render_t abc_render_video;
extern abc_render_t abc_render_audio;
@@ -56,6 +57,10 @@ static abc_render_t* abc_renders[ABC_HTML_NB] =
[ABC_HTML_TR] = &abc_render_tr,
[ABC_HTML_TD] = &abc_render_td,
+ [ABC_HTML_OL] = &abc_render_empty,
+ [ABC_HTML_UL] = &abc_render_empty,
+ [ABC_HTML_LI] = &abc_render_li,
+
[ABC_HTML_VIDEO] = &abc_render_video,
[ABC_HTML_AUDIO] = &abc_render_audio,
[ABC_HTML_SOURCE] = &abc_render_empty,
diff --git a/ui/abc_render_a_href.c b/ui/abc_render_a_href.c
index 1c3879c..a10d927 100644
--- a/ui/abc_render_a_href.c
+++ b/ui/abc_render_a_href.c
@@ -40,6 +40,13 @@ static int _render_fini_a_href(abc_render_t* render)
static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width, int height)
{
+ abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_HREF);
+
+ if (!attr || !attr->value || attr->value->len <= 0) {
+ scf_loge("hyper link '%s' not found a URL\n", obj->text->data);
+ return -EINVAL;
+ }
+
if (0 == program)
__init_program(&program, vert_shader, frag_shader);
@@ -53,9 +60,6 @@ static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width,
cairo_surface_t* surface;
cairo_t* cr;
- scf_list_t* l;
- abc_obj_t* attr;
-
uint8_t* bgra = malloc(width * 32 * 4);
if (!bgra)
return -ENOMEM;
@@ -67,15 +71,7 @@ static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width,
cairo_set_font_size (cr, 24);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
- for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
- attr = scf_list_data(l, abc_obj_t, list);
-
- if (ABC_HTML_ATTR_HREF == attr->type) {
-
- cairo_text_extents(cr, attr->value->data, &extents);
- break;
- }
- }
+ cairo_text_extents(cr, attr->value->data, &extents);
int w = extents.width + extents.x_bearing;
int h = extents.height;
@@ -88,14 +84,6 @@ static int _render_draw_a_href(abc_render_t* render, abc_obj_t* obj, int width,
surface = NULL;
cr = NULL;
- if (l == scf_list_sentinel(&obj->attrs)) {
- scf_loge("hyper link '%s' not found a URL\n", obj->text->data);
-
- free(bgra);
- bgra = NULL;
- return -EINVAL;
- }
-
scf_logd("extents: x_bearing: %f, width: %f, y_bearing: %f, height: %f\n",
extents.x_bearing, extents.width, extents.y_bearing, extents.height);
diff --git a/ui/abc_render_bg_image.c b/ui/abc_render_bg_image.c
index 267272d..935319c 100644
--- a/ui/abc_render_bg_image.c
+++ b/ui/abc_render_bg_image.c
@@ -75,7 +75,7 @@ static int _render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width
if (ret < 0)
return ret;
- scf_logi("background-image: %s\n", spath->data);
+ scf_logd("background-image: %s\n", spath->data);
ret = abc_img_open(&img, spath->data);
@@ -155,7 +155,7 @@ static int _render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width
if (attr) {
abc_css_position(&x, &y, w, h, obj, attr->value->data);
- scf_logi("background-position: %s, x: %f, y: %f, w: %f, h: %f\n", attr->value->data, x, y, w, h);
+ scf_logd("background-position: %s, x: %f, y: %f, w: %f, h: %f\n", attr->value->data, x, y, w, h);
if (x + w > 1.0)
index_x = -1;
@@ -178,7 +178,7 @@ static int _render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width
}
}
- scf_logi("repeat_x: %d, repeat_y: %d, index_x: %d, index_y: %d\n", repeat_x, repeat_y, index_x, index_y);
+ scf_logd("repeat_x: %d, repeat_y: %d, index_x: %d, index_y: %d\n", repeat_x, repeat_y, index_x, index_y);
glUseProgram(program);
diff --git a/ui/abc_render_h1.c b/ui/abc_render_h1.c
index a399754..e6d90cd 100644
--- a/ui/abc_render_h1.c
+++ b/ui/abc_render_h1.c
@@ -38,7 +38,7 @@ static int _render_fini_h1(abc_render_t* render)
return 0;
}
-static int __init_text(cairo_t* cr, abc_obj_t* obj)
+int __init_text(cairo_t* cr, abc_obj_t* obj, double dx)
{
abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
if (attr) {
@@ -76,8 +76,9 @@ static int __init_text(cairo_t* cr, abc_obj_t* obj)
cairo_set_source_rgba(cr, r, g, b, 1.0);
cairo_text_extents (cr, obj->text->data, &extents);
- cairo_move_to (cr, extents.x_bearing, -extents.y_bearing);
+ cairo_move_to (cr, extents.x_bearing + dx, -extents.y_bearing);
cairo_show_text(cr, obj->text->data);
+ cairo_stroke(cr);
attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_TEXT_DECORATION);
if (attr) {
@@ -138,7 +139,7 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int
cairo_stroke(cr);
if (obj->text)
- __init_text(cr, obj);
+ __init_text(cr, obj, 0.0);
// cairo_surface_write_to_png(surface, "tmp.png");
cairo_destroy(cr);
diff --git a/ui/abc_render_li.c b/ui/abc_render_li.c
new file mode 100644
index 0000000..9349b6b
--- /dev/null
+++ b/ui/abc_render_li.c
@@ -0,0 +1,249 @@
+#include"abc.h"
+
+static const char* vert_shader =
+ "#version 330 core\n"
+ "layout(location = 0) in vec4 position; \n"
+ "layout(location = 1) in vec2 a_texCoord; \n"
+ "out vec2 v_texCoord; \n"
+ "uniform mat4 mvp; \n"
+ "void main() { \n"
+ "gl_Position = mvp * position; \n"
+ "v_texCoord = a_texCoord; \n"
+ "} \n";
+
+static const char* frag_shader =
+ "#version 330 core\n"
+ "in vec2 v_texCoord; \n"
+ "out vec4 outputColor; \n"
+ "uniform vec4 rect; \n"
+ "uniform sampler2D tex_rgba; \n"
+ "uniform sampler2D tex_img; \n"
+ "void main() { \n"
+ " vec2 xy = v_texCoord; \n"
+ " if (xy.x > rect.x && xy.x < rect.x + rect.z \n"
+ " && xy.y > rect.y && xy.y < rect.y + rect.w) { \n"
+ " xy.x = (xy.x - rect.x) / rect.z; \n"
+ " xy.y = (xy.y - rect.y) / rect.w; \n"
+ " vec4 v = texture2D(tex_img, xy).rgba; \n"
+ " outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
+ " } else { \n"
+ " vec4 v = texture2D(tex_rgba, xy).rgba; \n"
+ " outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
+ " } \n"
+ "} \n";
+
+
+static GLuint program = 0;
+
+static GLuint vao = 0;
+static GLuint buffers[2] = {0};
+static GLuint texture_rgba = 0;
+static GLuint texture_img = 0;
+
+static GLuint uniform_mvp;
+static GLuint uniform_rgba;
+static GLuint uniform_img;
+static GLuint uniform_rect;
+
+static int _render_fini_li(abc_render_t* render)
+{
+ return 0;
+}
+
+static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int height)
+{
+ abc_obj_t* attr;
+ cairo_surface_t* surface;
+ cairo_t* cr;
+
+ uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+ if (!bgra)
+ return -ENOMEM;
+
+ double r = 0.0;
+ double g = 0.0;
+ 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);
+
+ surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4);
+ cr = cairo_create(surface);
+
+ cairo_set_line_width(cr, 1);
+ cairo_set_source_rgb(cr, r, g, b);
+ cairo_rectangle(cr, 0, 0, obj->w, obj->h);
+ cairo_fill(cr);
+ cairo_stroke(cr);
+
+ if (obj->text)
+ __init_text(cr, obj, 16);
+
+ if (ABC_HTML_UL == obj->parent->type) {
+ r = 0.0;
+ g = 0.0;
+ 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);
+
+ cairo_set_source_rgb(cr, r, g, b);
+
+ attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_TYPE);
+ if (attr) {
+ if (!strcmp(attr->value->data, "circle"))
+ cairo_arc (cr, 8, 8, 3, 0, 2 * M_PI);
+
+ else if (!strcmp(attr->value->data, "square")) {
+ cairo_rectangle(cr, 5, 5, 6, 6);
+ cairo_fill(cr);
+
+ } else if (!strcmp(attr->value->data, "disc")) {
+ cairo_arc (cr, 8, 8, 3, 0, 2 * M_PI);
+ cairo_fill(cr);
+ }
+ } else {
+ cairo_arc (cr, 8, 8, 3, 0, 2 * M_PI);
+ cairo_fill(cr);
+ }
+
+ cairo_stroke(cr);
+ }
+// cairo_surface_write_to_png(surface, "tmp.png");
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ surface = NULL;
+ cr = NULL;
+
+ abc_img_t* img = NULL;
+ uint8_t* bgra1 = NULL;
+
+ GLfloat x = 0.0;
+ GLfloat y = 0.0;
+ GLfloat w = 0.0;
+ GLfloat h = 0.0;
+
+ attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_IMAGE);
+
+ if (attr && attr->value && attr->value->len > 0)
+ {
+ scf_string_t* spath = NULL;
+ abc_io_t* io = NULL;
+
+ int ret = __io_url_css(&io, &spath, obj->file->data, attr->value->data);
+ if (ret < 0) {
+ free(bgra);
+ return ret;
+ }
+
+ scf_logd("list-style-image: %s\n", spath->data);
+
+ ret = abc_img_open(&img, spath->data);
+
+ scf_string_free(spath);
+ spath = NULL;
+ if (ret < 0) {
+ free(bgra);
+ return ret;
+ }
+
+ bgra1 = calloc(1, img->width * img->height * 4);
+ if (!bgra1) {
+ abc_img_close(img);
+ free(bgra);
+ return -ENOMEM;
+ }
+
+ ret = abc_img_read(img, bgra1, img->width * img->height * 4);
+ if (ret < 0) {
+ abc_img_close(img);
+ free(bgra1);
+ free(bgra);
+ return ret;
+ }
+
+ x = obj->h * 0.333 / (float)obj->w;
+ y = 0.333;
+ w = x;
+ h = y;
+
+ if (0 == texture_img)
+ __init_texture(&texture_img, GL_RGBA, img->width, img->height, NULL);
+ }
+
+ if (0 == program)
+ __init_program(&program, vert_shader, frag_shader);
+
+ if (0 == vao)
+ __init_buffers(&vao, buffers);
+
+ if (0 == texture_rgba)
+ __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL);
+
+ float mvp[16];
+ __compute_mvp(mvp, 0, 0, 0);
+
+ scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
+
+ GLfloat vert_update[] =
+ {
+ 2.0 * obj->x / (float)width - 1.0,
+ -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+
+ 2.0 * (obj->x + obj->w) / (float)width - 1.0,
+ -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+
+ 2.0 * obj->x / (float)width - 1.0,
+ -2.0 * obj->y / (float)height + 1.0,
+
+ 2.0 * (obj->x + obj->w) / (float)width - 1.0,
+ -2.0 * obj->y / (float)height + 1.0,
+ };
+
+ glUseProgram(program);
+
+ uniform_mvp = glGetUniformLocation(program, "mvp");
+ uniform_rgba = glGetUniformLocation(program, "tex_rgba");
+ uniform_img = glGetUniformLocation(program, "tex_img");
+ uniform_rect = glGetUniformLocation(program, "rect");
+
+ glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture (GL_TEXTURE_2D, texture_rgba);
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, obj->w, obj->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
+ glUniform1i(uniform_rgba, 0);
+
+ if (img) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture (GL_TEXTURE_2D, texture_img);
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra1);
+ glUniform1i(uniform_img, 1);
+ }
+
+ glUniform4f(uniform_rect, x, y, w, h);
+
+ // draw
+ glBindBuffer (GL_ARRAY_BUFFER, buffers[0]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
+
+ glBindVertexArray(vao);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glBindVertexArray(0);
+ glUseProgram(0);
+
+ abc_img_close(img);
+ free(bgra);
+ return 0;
+}
+
+abc_render_t abc_render_li =
+{
+ .type = ABC_HTML_LI,
+
+ .draw = _render_draw_li,
+ .fini = _render_fini_li,
+};
diff --git a/ui/main.c b/ui/main.c
index c3a890d..c931f2c 100644
--- a/ui/main.c
+++ b/ui/main.c
@@ -64,9 +64,11 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
if (!ctx->current->root)
return 0;
+ scf_list_t* l;
abc_obj_t* prev = ctx->current->current;
abc_obj_t* obj = abc_obj_find(ctx->current->root, x, y);
abc_obj_t* attr;
+ abc_obj_t* css;
int ret = 0;
@@ -80,6 +82,13 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
gdk_window_set_cursor(window, cursor);
g_object_unref(cursor);
+ if (prev->visited)
+ css = abc_obj_get_attr(prev, ABC_CSS_VISITED);
+ else
+ css = abc_obj_get_attr(prev, ABC_CSS_LINK);
+ if (css)
+ abc_obj_set_css(prev, css);
+
prev->clicked = 0;
ret = 1;
}
@@ -88,8 +97,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);
- switch (obj->type) {
-
+ switch (obj->type)
+ {
case ABC_HTML_A:
display = gtk_widget_get_display(GTK_WIDGET(ctx->gl_area));
window = gtk_widget_get_window (GTK_WIDGET(ctx->gl_area));
@@ -120,6 +129,12 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
break;
};
+ css = abc_obj_get_attr(obj, ABC_CSS_HOVER);
+ if (css) {
+ abc_obj_set_css(obj, css);
+ ret = 1;
+ }
+
ctx->current->current = obj;
}
@@ -164,16 +179,24 @@ static int __do_button_release_a(abc_ctx_t* ctx, abc_obj_t* obj, int x, int y)
static int __do_button_release(abc_ctx_t* ctx, int x, int y)
{
abc_html_t* html;
- abc_obj_t* attr;
abc_obj_t* obj = abc_obj_find(ctx->current->root, x, y);
+ abc_obj_t* css;
+ abc_obj_t* attr;
+
if (!obj)
- return -ENOMEM;
+ return __do_button_move(ctx, x, y);
- scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
- obj->key->data, obj->x, obj->y, obj->w, obj->h, x, y);
+ obj->visited = 1;
+
+ css = abc_obj_get_attr(obj, ABC_CSS_VISITED);
+ if (css)
+ abc_obj_set_css(obj, css);
- switch (obj->type) {
+ scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
+ obj->keys[0], obj->x, obj->y, obj->w, obj->h, x, y);
+ switch (obj->type)
+ {
case ABC_HTML_A:
return __do_button_release_a(ctx, obj, x, y);
break;
@@ -200,6 +223,7 @@ static int __do_button_release(abc_ctx_t* ctx, int x, int y)
return __do_button_move(ctx, x, y);
break;
default:
+ return __do_button_move(ctx, x, y);
break;
};
@@ -306,6 +330,32 @@ static gboolean button_release_event(GtkWidget* self, GdkEventButton* event, gpo
return TRUE;
}
+static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpointer user_data)
+{
+ abc_ctx_t* ctx = user_data;
+
+ if (gtk_widget_get_window(GTK_WIDGET(ctx->gl_area)) == event->window) {
+
+ scf_logw("event x_root: %f, y_root: %f, x: %f, y: %f\n",
+ event->x_root, event->y_root, event->x, event->y);
+
+ abc_html_t* html;
+ abc_obj_t* obj = abc_obj_find(ctx->current->root, event->x, event->y);
+ abc_obj_t* css;
+
+ if (obj) {
+ css = abc_obj_get_attr(obj, ABC_CSS_ACTIVE);
+ if (css) {
+ abc_obj_set_css(obj, css);
+
+ gtk_gl_area_queue_render(ctx->gl_area);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
static void __utf8_delete(abc_ctx_t* ctx)
{
abc_obj_t* obj;
@@ -396,11 +446,11 @@ static gboolean timer_handler(gpointer user_data)
obj = ctx->current->current;
if (obj) {
obj->jiffies++;
- gtk_gl_area_queue_render(ctx->gl_area);
- } else {
- if (ctx->current->has_video)
- gtk_gl_area_queue_render(ctx->gl_area);
+// gtk_gl_area_queue_render(ctx->gl_area);
}
+
+ if (ctx->current->has_video)
+ gtk_gl_area_queue_render(ctx->gl_area);
}
return TRUE;
@@ -536,6 +586,7 @@ int main(int argc, char *argv[])
gtk_widget_add_events(GTK_WIDGET(gl_area), GDK_POINTER_MOTION_MASK);
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);
--
2.25.1