aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--subprojects/d2tk/d2tk/base.h7
-rw-r--r--subprojects/d2tk/example/example.c13
-rw-r--r--subprojects/d2tk/src/base.c104
-rw-r--r--subprojects/d2tk/test/base.c21
4 files changed, 143 insertions, 2 deletions
diff --git a/subprojects/d2tk/d2tk/base.h b/subprojects/d2tk/d2tk/base.h
index b51b3fe..048b91d 100644
--- a/subprojects/d2tk/d2tk/base.h
+++ b/subprojects/d2tk/d2tk/base.h
@@ -424,6 +424,13 @@ d2tk_base_label(d2tk_base_t *base, ssize_t lbl_len, const char *lbl,
float mul, const d2tk_rect_t *rect, d2tk_align_t align);
D2TK_API d2tk_state_t
+d2tk_base_link(d2tk_base_t *base, d2tk_id_t id, ssize_t lbl_len, const char *lbl,
+ float mul, const d2tk_rect_t *rect, d2tk_align_t align);
+
+#define d2tk_base_link_is_changed(...) \
+ d2tk_state_is_changed(d2tk_base_link(__VA_ARGS__))
+
+D2TK_API d2tk_state_t
d2tk_base_dial_bool(d2tk_base_t *base, d2tk_id_t id, const d2tk_rect_t *rect,
bool *value);
diff --git a/subprojects/d2tk/example/example.c b/subprojects/d2tk/example/example.c
index b13a026..a5bd63c 100644
--- a/subprojects/d2tk/example/example.c
+++ b/subprojects/d2tk/example/example.c
@@ -91,7 +91,7 @@ static const char *bar_lbl [BAR_MAX] = {
static inline void
_render_c_mix(d2tk_base_t *base, const d2tk_rect_t *rect)
{
-#define N 14
+#define N 15
#define M 24
static val_t value [N*M];
@@ -230,6 +230,17 @@ _render_c_mix(d2tk_base_t *base, const d2tk_rect_t *rect)
d2tk_base_bitmap(base, 2, 2, 2*sizeof(uint32_t), argb, rev, bnd,
D2TK_ALIGN_CENTERED);
} break;
+ case 14:
+ {
+ char lbl [32];
+ const size_t lbl_len = snprintf(lbl, sizeof(lbl), "%03X", k);
+
+ if(d2tk_base_link_is_changed(base, id, lbl_len, lbl, 0.5f, bnd,
+ D2TK_ALIGN_MIDDLE | D2TK_ALIGN_LEFT))
+ {
+ fprintf(stdout, "link %016"PRIx64" DOWN\n", id);
+ }
+ } break;
default:
{
// nothing to do
diff --git a/subprojects/d2tk/src/base.c b/subprojects/d2tk/src/base.c
index 0a68dd0..68e1088 100644
--- a/subprojects/d2tk/src/base.c
+++ b/subprojects/d2tk/src/base.c
@@ -2616,9 +2616,9 @@ d2tk_base_label(d2tk_base_t *base, ssize_t lbl_len, const char *lbl,
const d2tk_hash_dict_t dict [] = {
{ rect, sizeof(d2tk_rect_t) },
{ style, sizeof(d2tk_style_t) },
- { lbl, lbl_len },
{ &mul, sizeof(float) },
{ &align, sizeof(d2tk_align_t) },
+ { lbl, lbl_len },
{ NULL, 0 }
};
const uint64_t hash = d2tk_hash_dict(dict);
@@ -2648,6 +2648,108 @@ d2tk_base_label(d2tk_base_t *base, ssize_t lbl_len, const char *lbl,
return D2TK_STATE_NONE;
}
+static void
+_d2tk_base_draw_link(d2tk_base_t *base, ssize_t lbl_len, const char *lbl,
+ float mul, const d2tk_rect_t *rect, d2tk_align_t align, d2tk_triple_t triple,
+ const d2tk_style_t *style)
+{
+ const bool has_lbl = lbl_len && lbl;
+
+ if(has_lbl && (lbl_len == -1) ) // zero terminated string
+ {
+ lbl_len = strlen(lbl);
+ }
+
+ const d2tk_hash_dict_t dict [] = {
+ { &triple, sizeof(d2tk_triple_t) },
+ { rect, sizeof(d2tk_rect_t) },
+ { style, sizeof(d2tk_style_t) },
+ { &mul, sizeof(float) },
+ { &align, sizeof(d2tk_align_t) },
+ { lbl, lbl_len },
+ { NULL, 0 }
+ };
+ const uint64_t hash = d2tk_hash_dict(dict);
+
+ d2tk_core_t *core = base->core;
+
+ //FIXME analyse link and draw underline, hover, etc.
+
+ D2TK_CORE_WIDGET(core, hash, widget)
+ {
+ d2tk_rect_t bnd;
+ d2tk_rect_shrink(&bnd, rect, style->padding);
+
+ {
+ const size_t ref = d2tk_core_bbox_push(core, true, rect);
+
+ d2tk_core_save(core);
+ d2tk_core_scissor(core, &bnd);
+ d2tk_core_font_size(core, mul*bnd.h);
+ d2tk_core_font_face(core, strlen(style->font_face), style->font_face);
+ d2tk_core_color(core, style->text_color[triple]);
+ d2tk_core_text(core, &bnd, lbl_len, lbl, align);
+ d2tk_core_restore(core);
+
+ d2tk_core_bbox_pop(core, ref);
+ }
+
+ {
+ const size_t ref = d2tk_core_bbox_push(core, true, rect);
+
+ d2tk_core_begin_path(core);
+ d2tk_core_move_to(core, bnd.x, bnd.y + bnd.h);
+ d2tk_core_line_to(core, bnd.x + bnd.w, bnd.y + bnd.h);
+ if(triple & D2TK_TRIPLE_FOCUS)
+ {
+ d2tk_core_color(core, style->stroke_color[triple]);
+ }
+ else
+ {
+ d2tk_core_color(core, style->fill_color[triple]);
+ }
+ d2tk_core_stroke_width(core, style->border_width);
+ d2tk_core_stroke(core);
+
+ d2tk_core_bbox_pop(core, ref);
+ }
+ }
+}
+
+D2TK_API d2tk_state_t
+d2tk_base_link(d2tk_base_t *base, d2tk_id_t id, ssize_t lbl_len, const char *lbl,
+ float mul, const d2tk_rect_t *rect, d2tk_align_t align)
+{
+ d2tk_state_t state = d2tk_base_is_active_hot(base, id, rect, D2TK_FLAG_NONE);
+
+ if(d2tk_state_is_down(state) || d2tk_state_is_enter(state))
+ {
+ state |= D2TK_STATE_CHANGED;
+ }
+
+ d2tk_triple_t triple = D2TK_TRIPLE_NONE;
+
+ if(d2tk_state_is_active(state))
+ {
+ triple |= D2TK_TRIPLE_ACTIVE;
+ }
+
+ if(d2tk_state_is_hot(state))
+ {
+ triple |= D2TK_TRIPLE_HOT;
+ }
+
+ if(d2tk_state_is_focused(state))
+ {
+ triple |= D2TK_TRIPLE_FOCUS;
+ }
+
+ _d2tk_base_draw_link(base, lbl_len, lbl, mul, rect, align, triple,
+ d2tk_base_get_style(base));
+
+ return state;
+}
+
D2TK_API d2tk_state_t
d2tk_base_dial_bool(d2tk_base_t *base, d2tk_id_t id, const d2tk_rect_t *rect,
bool *value)
diff --git a/subprojects/d2tk/test/base.c b/subprojects/d2tk/test/base.c
index ca5c3af..1d000ed 100644
--- a/subprojects/d2tk/test/base.c
+++ b/subprojects/d2tk/test/base.c
@@ -1764,6 +1764,26 @@ _test_label()
}
static void
+_test_link()
+{
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+
+ d2tk_base_t *base = d2tk_base_new(&d2tk_mock_driver_lazy, &ctx);
+ const d2tk_rect_t rect = D2TK_RECT(0, 0, DIM_W, DIM_H);
+ assert(base);
+
+ const char *lbl= "link";
+ const d2tk_state_t state = d2tk_base_link(base, D2TK_ID, -1, lbl, 0.8f, &rect,
+ D2TK_ALIGN_LEFT);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+
+ d2tk_base_free(base);
+}
+
+static void
_test_dial_bool()
{
d2tk_mock_ctx_t ctx = {
@@ -2036,6 +2056,7 @@ main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
_test_combo_scroll_down();
_test_text_field();
_test_label();
+ _test_link();
_test_dial_bool();
_test_dial_int32();
_test_dial_int64();