aboutsummaryrefslogtreecommitdiff
path: root/subprojects
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2019-05-09 19:02:47 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2019-05-09 19:02:47 +0200
commit964a2f450910180a3e3f04dedbdd81e0bd7f318c (patch)
tree3ae8256770efa703eaed9287eb04e31186e77732 /subprojects
parent491afc6346236b32e5ae49687fd4b159cadf9600 (diff)
parent847b1b8f2a1e8669b2e1e6e49fa0a8f66c44e2aa (diff)
downloadtracker.lv2-964a2f450910180a3e3f04dedbdd81e0bd7f318c.tar.xz
Merge commit '847b1b8f2a1e8669b2e1e6e49fa0a8f66c44e2aa'
Diffstat (limited to 'subprojects')
-rw-r--r--subprojects/d2tk/.gitlab-ci.yml23
-rw-r--r--subprojects/d2tk/VERSION2
-rw-r--r--subprojects/d2tk/d2tk/base.h17
-rw-r--r--subprojects/d2tk/example/example.c88
-rw-r--r--subprojects/d2tk/meson.build2
-rw-r--r--subprojects/d2tk/pugl/pugl/pugl_x11.c3
-rw-r--r--subprojects/d2tk/src/base.c84
-rw-r--r--subprojects/d2tk/test/base.c1738
8 files changed, 1909 insertions, 48 deletions
diff --git a/subprojects/d2tk/.gitlab-ci.yml b/subprojects/d2tk/.gitlab-ci.yml
index 48c411c..f8f8464 100644
--- a/subprojects/d2tk/.gitlab-ci.yml
+++ b/subprojects/d2tk/.gitlab-ci.yml
@@ -18,7 +18,7 @@ stages:
.build_template: &build_definition
<<: *common_definition
script:
- - meson --prefix="/" --libdir="lib" --cross-file "${CI_BUILD_NAME}" -Db_lto=false build
+ - meson --prefix="/" --libdir="lib" --cross-file "${CI_BUILD_NAME}" build
- sed -i -e '/framework/s/-Wl,-O1//g' -e '/framework/s/-Wl,--start-group//g' -e '/framework/s/-Wl,--end-group//g' build/build.ninja
- ninja -C build
- DESTDIR="${CI_PROJECT_DIR}/${BASE_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" ninja -C build install
@@ -26,15 +26,32 @@ stages:
.test_template: &test_definition
<<: *common_definition
script:
- - meson --prefix="/" --libdir="lib" --cross-file "${CI_BUILD_NAME}" -Db_lto=false build
+ - meson --prefix="/" --libdir="lib" --cross-file "${CI_BUILD_NAME}" build
- sed -i -e '/framework/s/-Wl,-O1//g' -e '/framework/s/-Wl,--start-group//g' -e '/framework/s/-Wl,--end-group//g' build/build.ninja
- ninja -C build
- DESTDIR="${CI_PROJECT_DIR}/${BASE_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" ninja -C build install
- ninja -C build test
+.analyze_template: &analyze_definition
+ <<: *common_definition
+ script:
+ - meson --prefix="/" --libdir="lib" --cross-file "${CI_BUILD_NAME}" build
+ - sed -i -e '/framework/s/-Wl,-O1//g' -e '/framework/s/-Wl,--start-group//g' -e '/framework/s/-Wl,--end-group//g' build/build.ninja
+ - ninja -C build
+ - DESTDIR="${CI_PROJECT_DIR}/${BASE_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" ninja -C build install
+ - ninja -C build test
+
+ - CC=clang CXX=clang++ meson --prefix="/" --libdir="lib" --cross-file "${CI_BUILD_NAME}" clang
+ - ninja -C clang
+ - ninja -C clang test
+
+ - scan-build --status-bugs meson --prefix="/" --libdir="lib" --cross-file "${CI_BUILD_NAME}" scanbuild
+ - scan-build --status-bugs ninja -C scanbuild
+ - scan-build --status-bugs ninja -C scanbuild test
+
.universal_linux_template: &universal_linux_definition
image: ventosus/universal-linux-gnu
- <<: *test_definition
+ <<: *analyze_definition
.arm_linux_template: &arm_linux_definition
image: ventosus/arm-linux-gnueabihf
diff --git a/subprojects/d2tk/VERSION b/subprojects/d2tk/VERSION
index 2ce9d83..0014166 100644
--- a/subprojects/d2tk/VERSION
+++ b/subprojects/d2tk/VERSION
@@ -1 +1 @@
-0.1.641
+0.1.713
diff --git a/subprojects/d2tk/d2tk/base.h b/subprojects/d2tk/d2tk/base.h
index 26cea3b..2d4774f 100644
--- a/subprojects/d2tk/d2tk/base.h
+++ b/subprojects/d2tk/d2tk/base.h
@@ -268,6 +268,9 @@ d2tk_base_get_alt(d2tk_base_t *base);
D2TK_API bool
d2tk_base_get_mod(d2tk_base_t *base);
+D2TK_API const char *
+d2tk_state_dump(d2tk_state_t state);
+
D2TK_API bool
d2tk_state_is_down(d2tk_state_t state);
@@ -381,7 +384,7 @@ d2tk_base_toggle(d2tk_base_t *base, d2tk_id_t id, const d2tk_rect_t *rect,
D2TK_API d2tk_state_t
d2tk_base_meter(d2tk_base_t *base, d2tk_id_t id, const d2tk_rect_t *rect,
- int32_t *value);
+ const int32_t *value);
#define d2tk_base_meter_is_changed(...) \
d2tk_state_is_changed(d2tk_base_meter(__VA_ARGS__))
@@ -590,6 +593,18 @@ d2tk_base_set_up(d2tk_base_t *base, bool down);
D2TK_API void
d2tk_base_set_down(d2tk_base_t *base, bool down);
+D2TK_API bool
+d2tk_base_get_left(d2tk_base_t *base);
+
+D2TK_API bool
+d2tk_base_get_right(d2tk_base_t *base);
+
+D2TK_API bool
+d2tk_base_get_up(d2tk_base_t *base);
+
+D2TK_API bool
+d2tk_base_get_down(d2tk_base_t *base);
+
D2TK_API void
d2tk_base_set_dimensions(d2tk_base_t *base, d2tk_coord_t w, d2tk_coord_t h);
diff --git a/subprojects/d2tk/example/example.c b/subprojects/d2tk/example/example.c
index b2ccc06..caaea41 100644
--- a/subprojects/d2tk/example/example.c
+++ b/subprojects/d2tk/example/example.c
@@ -229,6 +229,9 @@ _render_c_seq(d2tk_base_t *base, const d2tk_rect_t *rect)
#define NN (N*N)
const unsigned M = N * rect->h / rect->w;
static val_t value [N*N];
+ static bool drag = false;
+ static d2tk_pos_t from_pos;
+ static d2tk_pos_t to_pos;
d2tk_style_t style = *d2tk_base_get_default_style();
style.border_width = 1;
@@ -239,8 +242,8 @@ _render_c_seq(d2tk_base_t *base, const d2tk_rect_t *rect)
D2TK_BASE_TABLE(rect, N, M, tab)
{
const unsigned k = d2tk_table_get_index(tab);
- const unsigned x = d2tk_table_get_index_x(tab);
- const unsigned y = d2tk_table_get_index_y(tab);
+ const d2tk_coord_t x = d2tk_table_get_index_x(tab);
+ const d2tk_coord_t y = d2tk_table_get_index_y(tab);
const d2tk_rect_t *bnd = d2tk_table_get_rect(tab);
const d2tk_id_t id = D2TK_ID_IDX(k);
@@ -268,9 +271,86 @@ _render_c_seq(d2tk_base_t *base, const d2tk_rect_t *rect)
continue;
}
- if(d2tk_base_toggle_is_changed(base, id, bnd, &val->b))
+ bool clone = val->b;
+
+ const uint32_t col_active = style.fill_color[D2TK_TRIPLE_ACTIVE];
+
+ if(drag)
+ {
+ const d2tk_coord_t y0 = from_pos.y <= to_pos.y ? from_pos.y : to_pos.y;
+ const d2tk_coord_t y1 = from_pos.y > to_pos.y ? from_pos.y : to_pos.y;
+ const d2tk_coord_t x0 = from_pos.x <= to_pos.x ? from_pos.x : to_pos.x;
+ const d2tk_coord_t x1 = from_pos.x > to_pos.x ? from_pos.x : to_pos.x;
+
+ for(d2tk_coord_t Y = y0; Y <= y1; Y++)
+ {
+ for(d2tk_coord_t X = x0; X <= x1; X++)
+ {
+ if( (y == from_pos.y) && (x == from_pos.x) )
+ {
+ continue;
+ }
+
+ if( (y != Y) || (x != X) )
+ {
+ continue;
+ }
+
+ clone = true;
+
+ style.fill_color[D2TK_TRIPLE_ACTIVE] = 0x9f00cfff;
+ break;
+ }
+ }
+ }
+
+ const d2tk_state_t state = d2tk_base_toggle(base, id, bnd, &clone);
+
+ style.fill_color[D2TK_TRIPLE_ACTIVE] = col_active;
+
+ if(d2tk_state_is_changed(state))
+ {
+ val->b = clone;
+ }
+
+ if(d2tk_state_is_down(state))
+ {
+ drag = true;
+
+ from_pos.x = to_pos.x = x;
+ from_pos.y = to_pos.y = y;
+
+ fprintf(stdout, "toggle %016"PRIx64" DOWN\n", id);
+ }
+
+ if(drag && d2tk_state_is_over(state))
+ {
+ to_pos.x = x;
+ to_pos.y = y;
+ }
+
+ if(d2tk_state_is_up(state))
{
- fprintf(stdout, "toggle %016"PRIx64" %s\n", id, val->b ? "ON" : "OFF");
+ drag = false;
+
+ const d2tk_coord_t y0 = from_pos.y <= to_pos.y ? from_pos.y : to_pos.y;
+ const d2tk_coord_t y1 = from_pos.y > to_pos.y ? from_pos.y : to_pos.y;
+ const d2tk_coord_t x0 = from_pos.x <= to_pos.x ? from_pos.x : to_pos.x;
+ const d2tk_coord_t x1 = from_pos.x > to_pos.x ? from_pos.x : to_pos.x;
+
+ for(d2tk_coord_t Y = y0; Y <= y1; Y++)
+ {
+ const d2tk_coord_t O = N*Y;
+
+ for(d2tk_coord_t X = x0; X <= x1; X++)
+ {
+ const d2tk_coord_t K = O + X;
+
+ value[K] = *val;
+ }
+ }
+
+ fprintf(stdout, "toggle %016"PRIx64" UP\n", id);
}
}
diff --git a/subprojects/d2tk/meson.build b/subprojects/d2tk/meson.build
index f3cdf57..e2e5b73 100644
--- a/subprojects/d2tk/meson.build
+++ b/subprojects/d2tk/meson.build
@@ -2,7 +2,7 @@ project('d2tk', 'c', default_options : [
'buildtype=release',
'warning_level=3',
'werror=false',
- 'b_lto=true',
+ 'b_lto=false',
'c_std=c11'])
static_link = false #meson.is_cross_build()
diff --git a/subprojects/d2tk/pugl/pugl/pugl_x11.c b/subprojects/d2tk/pugl/pugl/pugl_x11.c
index 5c20782..5afc880 100644
--- a/subprojects/d2tk/pugl/pugl/pugl_x11.c
+++ b/subprojects/d2tk/pugl/pugl/pugl_x11.c
@@ -522,8 +522,7 @@ translateEvent(PuglView* view, XEvent xevent)
case 7: event.scroll.dx = 1.0f; break;
}
}
- __attribute__((fallthrough));
- // nobreak
+ /* fall through */
case ButtonRelease:
if (xevent.xbutton.button < 4 || xevent.xbutton.button > 7) {
event.button.type = ((xevent.type == ButtonPress)
diff --git a/subprojects/d2tk/src/base.c b/subprojects/d2tk/src/base.c
index f2ecf34..0bbbb8a 100644
--- a/subprojects/d2tk/src/base.c
+++ b/subprojects/d2tk/src/base.c
@@ -82,6 +82,8 @@ struct _d2tk_base_t {
d2tk_flip_t focusitem;
d2tk_id_t lastitem;
+ bool not_first_time;
+
struct {
d2tk_coord_t x;
d2tk_coord_t y;
@@ -222,7 +224,7 @@ const size_t d2tk_flowmatrix_arc_sz = sizeof(d2tk_flowmatrix_arc_t);
const size_t d2tk_pane_sz = sizeof(d2tk_pane_t);
static inline d2tk_id_t
-_d2tk_flip_get(d2tk_flip_t *flip)
+_d2tk_flip_get_cur(d2tk_flip_t *flip)
{
return flip->cur;
}
@@ -234,9 +236,9 @@ _d2tk_flip_get_old(d2tk_flip_t *flip)
}
static inline bool
-_d2tk_flip_equal(d2tk_flip_t *flip, d2tk_id_t id)
+_d2tk_flip_equal_cur(d2tk_flip_t *flip, d2tk_id_t id)
{
- return _d2tk_flip_get(flip) == id;
+ return _d2tk_flip_get_cur(flip) == id;
}
static inline bool
@@ -248,7 +250,7 @@ _d2tk_flip_equal_old(d2tk_flip_t *flip, d2tk_id_t id)
static inline bool
_d2tk_flip_invalid(d2tk_flip_t *flip)
{
- return _d2tk_flip_equal(flip, 0);
+ return _d2tk_flip_equal_cur(flip, 0);
}
static inline bool
@@ -646,6 +648,25 @@ d2tk_base_get_mod(d2tk_base_t *base)
return base->keys.shift || base->keys.ctrl || base->keys.alt;
}
+D2TK_API const char *
+d2tk_state_dump(d2tk_state_t state)
+{
+#define LEN 16
+ static char buf [LEN + 1];
+
+ for(unsigned i = 0; i < LEN; i++)
+ {
+ buf[LEN - 1 - i] = (1 << i) & state
+ ? '1'
+ : '.';
+ }
+
+ buf[LEN] = '\0';
+
+ return buf;
+#undef LEN
+}
+
D2TK_API bool
d2tk_state_is_down(d2tk_state_t state)
{
@@ -832,19 +853,21 @@ d2tk_base_is_active_hot(d2tk_base_t *base, d2tk_id_t id,
const d2tk_rect_t *rect, d2tk_flag_t flags)
{
d2tk_state_t state = D2TK_STATE_NONE;
- bool is_active = _d2tk_flip_equal(&base->activeitem, id);
+ bool is_active = _d2tk_flip_equal_cur(&base->activeitem, id);
bool is_hot = false;
bool is_over = false;
- bool is_focused = _d2tk_flip_equal(&base->focusitem, id);
+ bool curfocus = _d2tk_flip_equal_cur(&base->focusitem, id);
+ bool newfocus = curfocus;
+ const bool lastfocus = _d2tk_flip_equal_old(&base->focusitem, id);
// handle forward focus
- if(is_focused)
+ if(curfocus)
{
if(base->keys.ctrl)
{
if(base->keys.right)
{
- is_focused = false;
+ newfocus = false; // do NOT change curfocus
base->focused = false; // clear focused flag
base->keys.right = false;
}
@@ -895,7 +918,8 @@ d2tk_base_is_active_hot(d2tk_base_t *base, d2tk_id_t id,
}
else if(!base->focused)
{
- is_focused = _d2tk_base_set_focus(base, id);
+ curfocus = _d2tk_base_set_focus(base, id);
+ newfocus = curfocus;
base->focused = true; // set focused flag
}
@@ -915,7 +939,8 @@ d2tk_base_is_active_hot(d2tk_base_t *base, d2tk_id_t id,
{
_d2tk_flip_set(&base->activeitem, id);
is_active = true;
- is_focused = _d2tk_base_set_focus(base, id);
+ curfocus = _d2tk_base_set_focus(base, id);
+ newfocus = curfocus;
state |= D2TK_STATE_DOWN;
}
@@ -963,15 +988,12 @@ d2tk_base_is_active_hot(d2tk_base_t *base, d2tk_id_t id,
state |= D2TK_STATE_OVER;
}
- if(is_focused)
+ if(newfocus)
{
state |= D2TK_STATE_FOCUS;
}
{
- const bool lastfocus = _d2tk_flip_equal_old(&base->focusitem, id);
- const bool curfocus = _d2tk_flip_equal(&base->focusitem, id);
-
if(lastfocus && !curfocus)
{
state |= D2TK_STATE_FOCUS_OUT;
@@ -982,9 +1004,9 @@ d2tk_base_is_active_hot(d2tk_base_t *base, d2tk_id_t id,
}
else if(!lastfocus && curfocus)
{
- if(_d2tk_flip_invalid_old(&base->focusitem))
+ if(_d2tk_flip_invalid_old(&base->focusitem) && base->not_first_time)
{
- _d2tk_flip_set(&base->focusitem, _d2tk_flip_get(&base->focusitem));
+ _d2tk_flip_set(&base->focusitem, _d2tk_flip_get_cur(&base->focusitem));
}
else
{
@@ -998,7 +1020,7 @@ d2tk_base_is_active_hot(d2tk_base_t *base, d2tk_id_t id,
}
// handle backwards focus
- if(is_focused)
+ if(newfocus)
{
if(base->keys.ctrl)
{
@@ -1012,6 +1034,8 @@ d2tk_base_is_active_hot(d2tk_base_t *base, d2tk_id_t id,
base->lastitem = id;
+ base->not_first_time = true;
+
return state;
}
@@ -2010,7 +2034,7 @@ _d2tk_base_draw_meter(d2tk_core_t *core, const d2tk_rect_t *rect,
D2TK_API d2tk_state_t
d2tk_base_meter(d2tk_base_t *base, d2tk_id_t id, const d2tk_rect_t *rect,
- int32_t *value)
+ const int32_t *value)
{
const d2tk_style_t *style = d2tk_base_get_style(base);
@@ -3798,6 +3822,30 @@ d2tk_base_set_down(d2tk_base_t *base, bool down)
base->keys.down = down;
}
+D2TK_API bool
+d2tk_base_get_left(d2tk_base_t *base)
+{
+ return base->keys.left;
+}
+
+D2TK_API bool
+d2tk_base_get_right(d2tk_base_t *base)
+{
+ return base->keys.right;
+}
+
+D2TK_API bool
+d2tk_base_get_up(d2tk_base_t *base)
+{
+ return base->keys.up;
+}
+
+D2TK_API bool
+d2tk_base_get_down(d2tk_base_t *base)
+{
+ return base->keys.down;
+}
+
D2TK_API void
d2tk_base_set_dimensions(d2tk_base_t *base, d2tk_coord_t w, d2tk_coord_t h)
{
diff --git a/subprojects/d2tk/test/base.c b/subprojects/d2tk/test/base.c
index c711528..367c0af 100644
--- a/subprojects/d2tk/test/base.c
+++ b/subprojects/d2tk/test/base.c
@@ -25,9 +25,30 @@
#include <d2tk/hash.h>
#include "mock.h"
+#define N 4
static void
_expose_hot(d2tk_base_t *base, const d2tk_rect_t *rect, unsigned n, unsigned p)
{
+#define hot_over (D2TK_STATE_HOT | D2TK_STATE_OVER)
+ static const d2tk_state_t states [N][N] = {
+ [0] = {
+ [0] = D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN | hot_over
+ },
+ [1] = {
+ [0] = D2TK_STATE_FOCUS,
+ [1] = hot_over
+ },
+ [2] = {
+ [0] = D2TK_STATE_FOCUS,
+ [2] = hot_over
+ },
+ [3] = {
+ [0] = D2TK_STATE_FOCUS,
+ [3] = hot_over
+ }
+ };
+#undef hot_over
+
D2TK_BASE_TABLE(rect, n, 1, tab)
{
const d2tk_rect_t *bnd = d2tk_table_get_rect(tab);
@@ -36,32 +57,256 @@ _expose_hot(d2tk_base_t *base, const d2tk_rect_t *rect, unsigned n, unsigned p)
const d2tk_state_t state = d2tk_base_button(base, id, bnd);
- if(k == p) // this element must be of state OVER and HOT
- {
- if(p == 0) // first element additionally has FOCUS
- {
- assert(state == (D2TK_STATE_OVER | D2TK_STATE_FOCUS | D2TK_STATE_HOT) );
+ assert(state == states[p][k]);
+ }
+}
+
+static void
+_test_hot()
+{
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+
+ d2tk_base_t *base = d2tk_base_new(&d2tk_mock_driver_lazy, &ctx);
+ assert(base);
+
+ d2tk_base_set_dimensions(base, DIM_W, DIM_H);
+ const d2tk_rect_t rect = D2TK_RECT(0, 0, DIM_W, DIM_H);
+
+ for(unsigned p = 0; p < N; p++)
+ {
+ const float p5 = p + 0.5f;
+ const d2tk_coord_t mx = DIM_W / N * p5;
+ const d2tk_coord_t my = DIM_H / 2;
+
+ d2tk_base_set_mouse_pos(base, mx, my);
+
+ d2tk_base_pre(base);
+
+ _expose_hot(base, &rect, N, p);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+
+ // trigger garbage collector
+ for(unsigned i = 0; i < 0x400; i++)
+ {
+ d2tk_base_pre(base);
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+
+ d2tk_base_free(base);
+}
+#undef N
+
+#define N 4
+static void
+_expose_mouse_fwd_focus(d2tk_base_t *base, const d2tk_rect_t *rect, unsigned n,
+ unsigned p, bool down)
+{
+#define focus_down ( \
+ D2TK_STATE_DOWN \
+ | D2TK_STATE_ACTIVE \
+ | D2TK_STATE_HOT \
+ | D2TK_STATE_FOCUS \
+ | D2TK_STATE_FOCUS_IN \
+ | D2TK_STATE_MOTION \
+ | D2TK_STATE_CHANGED \
+ | D2TK_STATE_OVER )
+#define focus_up ( \
+ D2TK_STATE_UP \
+ | D2TK_STATE_HOT \
+ | D2TK_STATE_FOCUS \
+ | D2TK_STATE_OVER )
+ static const d2tk_state_t states [N][2][N] = {
+ [0] = {
+ [true] = {
+ [0] = focus_down
+ },
+ [false] = {
+ [0] = focus_up
}
- else
- {
- assert(state == (D2TK_STATE_OVER | D2TK_STATE_HOT) );
+ },
+ [1] = {
+ [true] = {
+ [0] = D2TK_STATE_FOCUS,
+ [1] = focus_down
+ },
+ [false] = {
+ [0] = D2TK_STATE_FOCUS_OUT,
+ [1] = focus_up
+ }
+ },
+ [2] = {
+ [true] = {
+ [1] = D2TK_STATE_FOCUS,
+ [2] = focus_down
+ },
+ [false] = {
+ [1] = D2TK_STATE_FOCUS_OUT,
+ [2] = focus_up
+ }
+ },
+ [3] = {
+ [true] = {
+ [2] = D2TK_STATE_FOCUS,
+ [3] = focus_down
+ },
+ [false] = {
+ [2] = D2TK_STATE_FOCUS_OUT,
+ [3] = focus_up
}
}
- else if(k == 0) // first element always has FOCUS
+ };
+#undef focus_up
+#undef focus_down
+
+ D2TK_BASE_TABLE(rect, n, 1, tab)
+ {
+ const d2tk_rect_t *bnd = d2tk_table_get_rect(tab);
+ const unsigned k = d2tk_table_get_index(tab);
+ const d2tk_id_t id = D2TK_ID_IDX(k);
+
+ const d2tk_state_t state = d2tk_base_button(base, id, bnd);
+
+ assert(state == states[p][down][k]);
+ }
+}
+
+static void
+_test_mouse_fwd_focus()
+{
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+
+ d2tk_base_t *base = d2tk_base_new(&d2tk_mock_driver_lazy, &ctx);
+ assert(base);
+
+ d2tk_base_set_dimensions(base, DIM_W, DIM_H);
+ const d2tk_rect_t rect = D2TK_RECT(0, 0, DIM_W, DIM_H);
+
+ for(unsigned p = 0; p < N; p++)
+ {
+ const float p5 = p + 0.5f;
+ const d2tk_coord_t mx = DIM_W / N * p5;
+ const d2tk_coord_t my = DIM_H / 2;
+
{
- assert(state == D2TK_STATE_FOCUS);
+ d2tk_base_set_mouse_pos(base, mx, my);
+ d2tk_base_set_mouse_l(base, true);
+
+ d2tk_base_pre(base);
+
+ _expose_mouse_fwd_focus(base, &rect, N, p, true);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
}
- else // all other elements have no state
+
{
- assert(state == D2TK_STATE_NONE);
+ d2tk_base_set_mouse_l(base, false);
+
+ d2tk_base_pre(base);
+
+ _expose_mouse_fwd_focus(base, &rect, N, p, false);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
}
}
+
+ // trigger garbage collector
+ for(unsigned i = 0; i < 0x400; i++)
+ {
+ d2tk_base_pre(base);
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+
+ d2tk_base_free(base);
}
+#undef N
+#define N 4
static void
-_test_hot()
+_expose_mouse_bwd_focus(d2tk_base_t *base, const d2tk_rect_t *rect, unsigned n,
+ unsigned p, bool down)
+{
+#define focus_down ( \
+ D2TK_STATE_DOWN \
+ | D2TK_STATE_ACTIVE \
+ | D2TK_STATE_HOT \
+ | D2TK_STATE_FOCUS \
+ | D2TK_STATE_FOCUS_IN \
+ | D2TK_STATE_MOTION \
+ | D2TK_STATE_CHANGED \
+ | D2TK_STATE_OVER )
+#define focus_up ( \
+ D2TK_STATE_UP \
+ | D2TK_STATE_HOT \
+ | D2TK_STATE_FOCUS \
+ | D2TK_STATE_OVER )
+ static const d2tk_state_t states [N][2][N] = {
+ [0] = {
+ [true] = {
+ [0] = D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN,
+ [3] = focus_down
+ },
+ [false] = {
+ [0] = D2TK_STATE_FOCUS_OUT,
+ [3] = focus_up
+ }
+ },
+ [1] = {
+ [true] = {
+ [2] = focus_down,
+ [3] = D2TK_STATE_FOCUS_OUT
+ },
+ [false] = {
+ [2] = focus_up
+ }
+ },
+ [2] = {
+ [true] = {
+ [1] = focus_down,
+ [2] = D2TK_STATE_FOCUS_OUT
+ },
+ [false] = {
+ [1] = focus_up
+ }
+ },
+ [3] = {
+ [true] = {
+ [0] = focus_down,
+ [1] = D2TK_STATE_FOCUS_OUT
+ },
+ [false] = {
+ [0] = focus_up
+ }
+ }
+ };
+#undef focus_up
+#undef focus_down
+
+ D2TK_BASE_TABLE(rect, n, 1, tab)
+ {
+ const d2tk_rect_t *bnd = d2tk_table_get_rect(tab);
+ const unsigned k = d2tk_table_get_index(tab);
+ const d2tk_id_t id = D2TK_ID_IDX(k);
+
+ const d2tk_state_t state = d2tk_base_button(base, id, bnd);
+
+ assert(state == states[p][down][k]);
+ }
+}
+
+static void
+_test_mouse_bwd_focus()
{
-#define N 4
d2tk_mock_ctx_t ctx = {
.check = NULL
};
@@ -73,18 +318,253 @@ _test_hot()
const d2tk_rect_t rect = D2TK_RECT(0, 0, DIM_W, DIM_H);
for(unsigned p = 0; p < N; p++)
- {
+ {
const float p5 = p + 0.5f;
- const d2tk_coord_t mx = DIM_W / N * p5;
+ const d2tk_coord_t mx = DIM_W - DIM_W / N * p5;
const d2tk_coord_t my = DIM_H / 2;
- d2tk_base_set_mouse_pos(base, mx, my);
+ {
+ d2tk_base_set_mouse_pos(base, mx, my);
+ d2tk_base_set_mouse_l(base, true);
+ d2tk_base_pre(base);
+
+ _expose_mouse_bwd_focus(base, &rect, N, p, true);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+
+ {
+ d2tk_base_set_mouse_l(base, false);
+
+ d2tk_base_pre(base);
+
+ _expose_mouse_bwd_focus(base, &rect, N, p, false);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+ }
+
+ // trigger garbage collector
+ for(unsigned i = 0; i < 0x400; i++)
+ {
d2tk_base_pre(base);
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
- _expose_hot(base, &rect, N, p);
+ d2tk_base_free(base);
+}
+#undef N
+#define N 4
+static void
+_expose_key_fwd_focus(d2tk_base_t *base, const d2tk_rect_t *rect, unsigned n,
+ unsigned p, bool down)
+{
+#define invar D2TK_STATE_HOT | D2TK_STATE_OVER
+ static const d2tk_state_t states [N][2][N] = {
+ [0] = {
+ [true] = {
+ [0] = invar | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ },
+ [false] = {
+ [0] = invar | D2TK_STATE_FOCUS
+ }
+ },
+ [1] = {
+ [true] = {
+ [0] = invar,
+ [1] = D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ },
+ [false] = {
+ [0] = invar | D2TK_STATE_FOCUS_OUT,
+ [1] = D2TK_STATE_FOCUS
+ }
+ },
+ [2] = {
+ [true] = {
+ [0] = invar,
+ [2] = D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ },
+ [false] = {
+ [0] = invar,
+ [1] = D2TK_STATE_FOCUS_OUT,
+ [2] = D2TK_STATE_FOCUS
+ }
+ },
+ [3] = {
+ [true] = {
+ [0] = invar,
+ [3] = D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ },
+ [false] = {
+ [0] = invar,
+ [2] = D2TK_STATE_FOCUS_OUT,
+ [3] = D2TK_STATE_FOCUS
+ }
+ }
+ };
+#undef invar
+
+ D2TK_BASE_TABLE(rect, n, 1, tab)
+ {
+ const d2tk_rect_t *bnd = d2tk_table_get_rect(tab);
+ const unsigned k = d2tk_table_get_index(tab);
+ const d2tk_id_t id = D2TK_ID_IDX(k);
+
+ const d2tk_state_t state = d2tk_base_button(base, id, bnd);
+
+ assert(state == states[p][down][k]);
+ }
+}
+
+static void
+_test_key_fwd_focus()
+{
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+
+ d2tk_base_t *base = d2tk_base_new(&d2tk_mock_driver_lazy, &ctx);
+ assert(base);
+
+ d2tk_base_set_dimensions(base, DIM_W, DIM_H);
+ const d2tk_rect_t rect = D2TK_RECT(0, 0, DIM_W, DIM_H);
+
+ for(unsigned p = 0; p < N; p++)
+ {
+ {
+ d2tk_base_set_ctrl(base, true);
+ d2tk_base_set_right(base, true);
+
+ d2tk_base_pre(base);
+
+ _expose_key_fwd_focus(base, &rect, N, p, true);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+
+ {
+ d2tk_base_set_right(base, false);
+ d2tk_base_set_ctrl(base, false);
+
+ d2tk_base_pre(base);
+
+ _expose_key_fwd_focus(base, &rect, N, p, false);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+ }
+
+ // trigger garbage collector
+ for(unsigned i = 0; i < 0x400; i++)
+ {
+ d2tk_base_pre(base);
d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+
+ d2tk_base_free(base);
+}
+#undef N
+
+#define N 4
+static void
+_expose_key_bwd_focus(d2tk_base_t *base, const d2tk_rect_t *rect, unsigned n,
+ unsigned p, bool down)
+{
+#define invar D2TK_STATE_HOT | D2TK_STATE_OVER
+ static const d2tk_state_t states [N][2][N] = {
+ [0] = {
+ [true] = {
+ [0] = invar | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ },
+ [false] = {
+ [0] = invar | D2TK_STATE_FOCUS_OUT
+ }
+ },
+ [1] = { //FIXME something's very wrong here, focus seems lost
+ [true] = {
+ [0] = invar
+ },
+ [false] = {
+ [0] = invar
+ }
+ },
+ [2] = {
+ [true] = {
+ [0] = invar
+ },
+ [false] = {
+ [0] = invar
+ }
+ },
+ [3] = {
+ [true] = {
+ [0] = invar
+ },
+ [false] = {
+ [0] = invar
+ }
+ }
+ };
+#undef invar
+
+ D2TK_BASE_TABLE(rect, n, 1, tab)
+ {
+ const d2tk_rect_t *bnd = d2tk_table_get_rect(tab);
+ const unsigned k = d2tk_table_get_index(tab);
+ const d2tk_id_t id = D2TK_ID_IDX(k);
+
+ const d2tk_state_t state = d2tk_base_button(base, id, bnd);
+
+ assert(state == states[p][down][k]);
+ }
+}
+
+static void
+_test_key_bwd_focus()
+{
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+
+ d2tk_base_t *base = d2tk_base_new(&d2tk_mock_driver_lazy, &ctx);
+ assert(base);
+
+ d2tk_base_set_dimensions(base, DIM_W, DIM_H);
+ const d2tk_rect_t rect = D2TK_RECT(0, 0, DIM_W, DIM_H);
+
+ for(unsigned p = 0; p < N; p++)
+ {
+ {
+ d2tk_base_set_ctrl(base, true);
+ d2tk_base_set_left(base, true);
+
+ d2tk_base_pre(base);
+
+ _expose_key_bwd_focus(base, &rect, N, p, true);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+
+ {
+ d2tk_base_set_left(base, false);
+ d2tk_base_set_ctrl(base, false);
+
+ d2tk_base_pre(base);
+
+ _expose_key_bwd_focus(base, &rect, N, p, false);
+
+ d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
}
// trigger garbage collector
@@ -92,6 +572,1188 @@ _test_hot()
{
d2tk_base_pre(base);
d2tk_base_post(base);
+ assert(!d2tk_base_get_again(base));
+ }
+
+ d2tk_base_free(base);
+}
+#undef N
+
+static void
+_test_get_set()
+{
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+
+ d2tk_base_t *base = d2tk_base_new(&d2tk_mock_driver_lazy, &ctx);
+ assert(base);
+
+ {
+ d2tk_coord_t w = 0;
+ d2tk_coord_t h = 0;
+
+ d2tk_base_set_dimensions(base, DIM_W, DIM_H);
+ d2tk_base_get_dimensions(base, &w, &h);
+
+ assert(w == DIM_W);
+ assert(h == DIM_H);
+ }
+
+ {
+ d2tk_base_set_ttls(base, 128, 128);
+ //FIXME add getter
+ }
+
+ {
+ d2tk_base_clear_focus(base);
+ d2tk_base_set_again(base);
+ //FIXME add getter
+ }
+
+ {
+ d2tk_base_set_mouse_l(base, true);
+ d2tk_base_set_mouse_m(base, true);
+ d2tk_base_set_mouse_r(base, true);
+ //FIXME add getter
+ }
+
+ {
+ d2tk_coord_t x = 0;
+ d2tk_coord_t y = 0;
+
+ d2tk_base_set_mouse_pos(base, 30, 40);
+
+ d2tk_base_get_mouse_pos(base, &x, &y);
+ assert(x == 30);
+ assert(y == 40);
+
+ x = 0;
+ y = 0;
+ d2tk_base_get_mouse_pos(base, NULL, NULL);
+ assert(x == 0);
+ assert(y == 0);
+ }
+
+ {
+ d2tk_base_add_mouse_scroll(base, 2, 3);
+ //FIXME add getter
+ }
+
+ {
+ d2tk_base_set_shift(base, false);
+ d2tk_base_set_ctrl(base, false);
+ d2tk_base_set_alt(base, false);
+
+ assert(d2tk_base_get_shift(base) == false);
+ assert(d2tk_base_get_ctrl(base) == false);
+ assert(d2tk_base_get_alt(base) == false);
+
+ d2tk_base_set_shift(base, true);
+ d2tk_base_set_ctrl(base, true);
+ d2tk_base_set_alt(base, true);
+
+ assert(d2tk_base_get_shift(base) == true);
+ assert(d2tk_base_get_ctrl(base) == true);
+ assert(d2tk_base_get_alt(base) == true);
+ }
+
+ {
+ d2tk_base_set_shift(base, false);
+ d2tk_base_set_ctrl(base, false);
+ d2tk_base_set_alt(base, false);
+
+ assert(d2tk_base_get_mod(base) == false);
+
+ d2tk_base_set_shift(base, true);
+ d2tk_base_set_ctrl(base, false);
+ d2tk_base_set_alt(base, false);
+
+ assert(d2tk_base_get_mod(base) == true);
+
+ d2tk_base_set_shift(base, false);
+ d2tk_base_set_ctrl(base, true);
+ d2tk_base_set_alt(base, false);
+
+ assert(d2tk_base_get_mod(base) == true);
+
+ d2tk_base_set_shift(base, false);
+ d2tk_base_set_ctrl(base, false);
+ d2tk_base_set_alt(base, true);
+
+ assert(d2tk_base_get_mod(base) == true);
+ }
+
+ {
+ d2tk_base_set_left(base, false);
+ d2tk_base_set_right(base, false);
+ d2tk_base_set_up(base, false);
+ d2tk_base_set_down(base, false);
+
+ assert(d2tk_base_get_left(base) == false);
+ assert(d2tk_base_get_right(base) == false);
+ assert(d2tk_base_get_up(base) == false);
+ assert(d2tk_base_get_down(base) == false);
+
+ d2tk_base_set_left(base, true);
+ d2tk_base_set_right(base, true);
+ d2tk_base_set_up(base, true);
+ d2tk_base_set_down(base, true);
+
+ assert(d2tk_base_get_left(base) == true);
+ assert(d2tk_base_get_right(base) == true);
+ assert(d2tk_base_get_up(base) == true);
+ assert(d2tk_base_get_down(base) == true);
+ }
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_table()
+{
+#define N 12
+#define M 8
+ 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);
+
+ D2TK_BASE_TABLE(&rect, N, M, tab)
+ {
+ const d2tk_rect_t *bnd = d2tk_table_get_rect(tab);
+ const unsigned k = d2tk_table_get_index(tab);
+ const unsigned x = d2tk_table_get_index_x(tab);
+ const unsigned y = d2tk_table_get_index_y(tab);
+
+ assert(bnd);
+ assert(bnd->x == rect.w / N * (d2tk_coord_t)x);
+ assert(bnd->y == rect.h / M * (d2tk_coord_t)y);
+ assert(bnd->w == rect.w / N);
+ assert(bnd->h == rect.h / M);
+ assert(y*N + x == k);
+ }
+
+ d2tk_base_free(base);
+#undef M
+#undef N
+}
+
+static void
+_test_frame()
+{
+ 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);
+
+ D2TK_BASE_FRAME(base, &rect, -1, "label", frm)
+ {
+ const d2tk_rect_t *bnd = d2tk_frame_get_rect(frm);
+
+ assert(bnd);
+ assert(bnd->x > rect.x);
+ assert(bnd->y > rect.y);
+ assert(bnd->w < rect.w);
+ assert(bnd->h < rect.h);
+ }
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_layout_relative_x()
+{
+#define N 4
+ 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 d2tk_coord_t frac [N] = {
+ 1, 2, 4, 0
+ };
+ unsigned i = 0;
+ D2TK_BASE_LAYOUT(&rect, N, frac, D2TK_FLAG_LAYOUT_X | D2TK_FLAG_LAYOUT_REL, lay)
+ {
+ const d2tk_rect_t *bnd = d2tk_layout_get_rect(lay);
+ const unsigned k = d2tk_layout_get_index(lay);
+
+ assert(k == i++);
+ assert(bnd);
+ //FIXME bnd->x/y/w/h
+ }
+
+ d2tk_base_free(base);
+#undef N
+}
+
+static void
+_test_layout_relative_y()
+{
+#define N 4
+ 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 d2tk_coord_t frac [N] = {
+ 1, 2, 4, 0
+ };
+ unsigned i = 0;
+ D2TK_BASE_LAYOUT(&rect, N, frac, D2TK_FLAG_LAYOUT_Y | D2TK_FLAG_LAYOUT_REL, lay)
+ {
+ const d2tk_rect_t *bnd = d2tk_layout_get_rect(lay);
+ const unsigned k = d2tk_layout_get_index(lay);
+
+ assert(k == i++);
+ assert(bnd);
+ //FIXME bnd->x/y/w/h
+ }
+
+ d2tk_base_free(base);
+#undef N
+}
+
+static void
+_test_layout_absolute_x()
+{
+#define N 4
+ 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 d2tk_coord_t frac [N] = {
+ DIM_W/4, 0, 0, 0
+ };
+ unsigned i = 0;
+ D2TK_BASE_LAYOUT(&rect, N, frac, D2TK_FLAG_LAYOUT_X | D2TK_FLAG_LAYOUT_ABS, lay)
+ {
+ const d2tk_rect_t *bnd = d2tk_layout_get_rect(lay);
+ const unsigned k = d2tk_layout_get_index(lay);
+
+ assert(k == i++);
+ assert(bnd);
+ //FIXME bnd->x/y/w/h
+ }
+
+ d2tk_base_free(base);
+#undef N
+}
+
+static void
+_test_layout_absolute_y()
+{
+#define N 4
+ 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 d2tk_coord_t frac [N] = {
+ DIM_W/4, 0, 0, 0
+ };
+ unsigned i = 0;
+ D2TK_BASE_LAYOUT(&rect, N, frac, D2TK_FLAG_LAYOUT_Y | D2TK_FLAG_LAYOUT_ABS, lay)
+ {
+ const d2tk_rect_t *bnd = d2tk_layout_get_rect(lay);
+ const unsigned k = d2tk_layout_get_index(lay);
+
+ assert(k == i++);
+ assert(bnd);
+ //FIXME bnd->x/y/w/h
+ }
+
+ d2tk_base_free(base);
+#undef N
+}
+
+static void
+_test_clip()
+{
+ {
+ const int32_t imin = 2;
+ const int32_t imax = 4;
+
+ int32_t ival = 1;
+ d2tk_clip_int32(imin, &ival, imax);
+ assert(ival == imin);
+
+ ival = 2;
+ d2tk_clip_int32(imin, &ival, imax);
+ assert(ival == imin);
+
+ ival = 3;
+ d2tk_clip_int32(imin, &ival, imax);
+ assert(ival == 3);
+
+ ival = 4;
+ d2tk_clip_int32(imin, &ival, imax);
+ assert(ival == imax);
+
+ ival = 5;
+ d2tk_clip_int32(imin, &ival, imax);
+ assert(ival == imax);
+ }
+
+ {
+ const int64_t imin = 2;
+ const int64_t imax = 4;
+
+ int64_t ival = 1;
+ d2tk_clip_int64(imin, &ival, imax);
+ assert(ival == imin);
+
+ ival = 2;
+ d2tk_clip_int64(imin, &ival, imax);
+ assert(ival == imin);
+
+ ival = 3;
+ d2tk_clip_int64(imin, &ival, imax);
+ assert(ival == 3);
+
+ ival = 4;
+ d2tk_clip_int64(imin, &ival, imax);
+ assert(ival == imax);
+
+ ival = 5;
+ d2tk_clip_int64(imin, &ival, imax);
+ assert(ival == imax);
+ }
+
+ {
+ const float imin = 2.f;
+ const float imax = 4.f;
+
+ float ival = 1.f;
+ d2tk_clip_float(imin, &ival, imax);
+ assert(ival == imin);
+
+ ival = 2.f;
+ d2tk_clip_float(imin, &ival, imax);
+ assert(ival == imin);
+
+ ival = 3.f;
+ d2tk_clip_float(imin, &ival, imax);
+ assert(ival == 3);
+
+ ival = 4.f;
+ d2tk_clip_float(imin, &ival, imax);
+ assert(ival == imax);
+
+ ival = 5.f;
+ d2tk_clip_float(imin, &ival, imax);
+ assert(ival == imax);
+ }
+
+ {
+ const double imin = 2.0;
+ const double imax = 4.0;
+
+ double ival = 1.0;
+ d2tk_clip_double(imin, &ival, imax);
+ assert(ival == imin);
+
+ ival = 2.0;
+ d2tk_clip_double(imin, &ival, imax);
+ assert(ival == imin);
+
+ ival = 3.0;
+ d2tk_clip_double(imin, &ival, imax);
+ assert(ival == 3);
+
+ ival = 4.0;
+ d2tk_clip_double(imin, &ival, imax);
+ assert(ival == imax);
+
+ ival = 5.0;
+ d2tk_clip_double(imin, &ival, imax);
+ assert(ival == imax);
+ }
+}
+
+static void
+_test_state()
+{
+ assert(d2tk_state_is_down(D2TK_STATE_DOWN));
+ assert(!d2tk_state_is_down(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_up(D2TK_STATE_UP));
+ assert(!d2tk_state_is_up(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_motion(D2TK_STATE_MOTION));
+ assert(!d2tk_state_is_motion(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_scroll_up(D2TK_STATE_SCROLL_UP));
+ assert(!d2tk_state_is_scroll_up(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_scroll_down(D2TK_STATE_SCROLL_DOWN));
+ assert(!d2tk_state_is_scroll_down(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_scroll_left(D2TK_STATE_SCROLL_LEFT));
+ assert(!d2tk_state_is_scroll_left(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_scroll_right(D2TK_STATE_SCROLL_RIGHT));
+ assert(!d2tk_state_is_scroll_right(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_active(D2TK_STATE_ACTIVE));
+ assert(!d2tk_state_is_active(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_hot(D2TK_STATE_HOT));
+ assert(!d2tk_state_is_hot(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_focused(D2TK_STATE_FOCUS));
+ assert(!d2tk_state_is_focused(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_focus_in(D2TK_STATE_FOCUS_IN));
+ assert(!d2tk_state_is_focus_in(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_focus_out(D2TK_STATE_FOCUS_OUT));
+ assert(!d2tk_state_is_focus_out(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_changed(D2TK_STATE_CHANGED));
+ assert(!d2tk_state_is_changed(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_enter(D2TK_STATE_ENTER));
+ assert(!d2tk_state_is_enter(D2TK_STATE_NONE));
+
+ assert(d2tk_state_is_over(D2TK_STATE_OVER));
+ assert(!d2tk_state_is_over(D2TK_STATE_NONE));
+}
+
+static void
+_test_hit()
+{
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+
+ d2tk_base_t *base = d2tk_base_new(&d2tk_mock_driver_lazy, &ctx);
+ assert(base);
+
+ const d2tk_rect_t rect = D2TK_RECT(10, 10, 10, 10);
+
+ d2tk_base_set_mouse_pos(base, 0, 0);
+ assert(!d2tk_base_is_hit(base, &rect));
+
+ d2tk_base_set_mouse_pos(base, 0, 10);
+ assert(!d2tk_base_is_hit(base, &rect));
+
+ d2tk_base_set_mouse_pos(base, 10, 0);
+ assert(!d2tk_base_is_hit(base, &rect));
+
+ d2tk_base_set_mouse_pos(base, 10, 10);
+ assert(d2tk_base_is_hit(base, &rect));
+
+ d2tk_base_set_mouse_pos(base, 15, 15);
+ assert(d2tk_base_is_hit(base, &rect));
+
+ d2tk_base_set_mouse_pos(base, 10, 20);
+ assert(!d2tk_base_is_hit(base, &rect));
+
+ d2tk_base_set_mouse_pos(base, 20, 10);
+ assert(!d2tk_base_is_hit(base, &rect));
+
+ d2tk_base_set_mouse_pos(base, 20, 20);
+ assert(!d2tk_base_is_hit(base, &rect));
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_default_style()
+{
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+
+ d2tk_base_t *base = d2tk_base_new(&d2tk_mock_driver_lazy, &ctx);
+ assert(base);
+
+ const d2tk_style_t *default_style = d2tk_base_get_default_style();
+ const d2tk_style_t *style = d2tk_base_get_style(base);
+ const d2tk_style_t custom_style = *default_style;
+
+ assert(default_style);
+ assert(style);
+ assert(default_style == style);
+
+ d2tk_base_set_style(base, &custom_style);
+ style = d2tk_base_get_style(base);
+
+ assert(style);
+ assert(style == &custom_style);
+
+ d2tk_base_set_default_style(base);
+ style = d2tk_base_get_style(base);
+
+ assert(style);
+ assert(style == default_style);
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_scrollbar_x()
+{
+ 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);
+
+#define H 128
+#define h 32
+ D2TK_BASE_SCROLLBAR(base, &rect, D2TK_ID, D2TK_FLAG_SCROLL_X, H, 0, h, 0, scroll)
+ {
+ const d2tk_rect_t *bnd = d2tk_scrollbar_get_rect(scroll);
+ const float xo = d2tk_scrollbar_get_offset_x(scroll);
+ const float yo = d2tk_scrollbar_get_offset_y(scroll);
+
+ assert(bnd);
+ assert(xo == 0);
+ assert(yo == 0);
+ }
+ //FIXME test scrolling
+#undef h
+#undef H
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_scrollbar_y()
+{
+ 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);
+
+#define V 128
+#define v 32
+ D2TK_BASE_SCROLLBAR(base, &rect, D2TK_ID, D2TK_FLAG_SCROLL_Y, 0, V, 0, v, scroll)
+ {
+ const d2tk_rect_t *bnd = d2tk_scrollbar_get_rect(scroll);
+ const float xo = d2tk_scrollbar_get_offset_x(scroll);
+ const float yo = d2tk_scrollbar_get_offset_y(scroll);
+
+ assert(bnd);
+ assert(xo == 0);
+ assert(yo == 0);
+ }
+ //FIXME test scrolling
+#undef v
+#undef V
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_pane_x()
+{
+ 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);
+
+#define fmin 0.25f
+#define fmax 0.75f
+ D2TK_BASE_PANE(base, &rect, D2TK_ID, D2TK_FLAG_PANE_X, fmin, fmax, pane)
+ {
+ const d2tk_rect_t *bnd = d2tk_pane_get_rect(pane);
+ const unsigned k = d2tk_pane_get_index(pane);
+ const float f = d2tk_pane_get_fraction(pane);
+
+ assert(bnd);
+ switch(k)
+ {
+ case 0:
+ {
+ assert(f == fmin);
+ } break;
+ case 1:
+ {
+ assert(f == fmin);
+ } break;
+ }
+ }
+ //FIXME test panning
+#undef fmin
+#undef fmax
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_pane_y()
+{
+ 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);
+
+#define fmin 0.25f
+#define fmax 0.75f
+ D2TK_BASE_PANE(base, &rect, D2TK_ID, D2TK_FLAG_PANE_Y, fmin, fmax, pane)
+ {
+ const d2tk_rect_t *bnd = d2tk_pane_get_rect(pane);
+ const unsigned k = d2tk_pane_get_index(pane);
+ const float f = d2tk_pane_get_fraction(pane);
+
+ assert(bnd);
+ switch(k)
+ {
+ case 0:
+ {
+ assert(f == fmin);
+ } break;
+ case 1:
+ {
+ assert(f == fmin);
+ } break;
+ }
+ }
+ //FIXME test panning
+#undef fmin
+#undef fmax
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_cursor()
+{
+ 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);
+
+ d2tk_base_cursor(base, &rect);
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_button_label_image()
+{
+ 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 d2tk_state_t state = d2tk_base_button_label_image(base, D2TK_ID,
+ -1, "label", -1, "image.png", &rect);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ |D2TK_STATE_OVER) );
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_button_label()
+{
+ 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 d2tk_state_t state = d2tk_base_button_label(base, D2TK_ID,
+ -1, "label", &rect);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_button_image()
+{
+ 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 d2tk_state_t state = d2tk_base_button_image(base, D2TK_ID,
+ -1, "image.png", &rect);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_button()
+{
+ 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 d2tk_state_t state = d2tk_base_button(base, D2TK_ID, &rect);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_toggle_label()
+{
+ 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);
+
+ bool val = false;
+ const d2tk_state_t state = d2tk_base_toggle_label(base, D2TK_ID,
+ -1, "label", &rect, &val);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == false);
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_toggle()
+{
+ 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);
+
+ bool val = false;
+ d2tk_base_set_mouse_l(base, true);
+ const d2tk_state_t state = d2tk_base_toggle(base, D2TK_ID, &rect, &val);
+ assert(state == (D2TK_STATE_DOWN | D2TK_STATE_ACTIVE | D2TK_STATE_HOT
+ | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN | D2TK_STATE_CHANGED
+ | D2TK_STATE_OVER) );
+ assert(val == true);
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_meter()
+{
+ 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 int32_t val = -32;
+ const d2tk_state_t state = d2tk_base_meter(base, D2TK_ID, &rect, &val);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_combo()
+{
+#define nitms 4
+ 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 *itms [nitms] = {
+ "1", "2", "3", "4"
+ };
+ int32_t val = 0;
+ const d2tk_state_t state = d2tk_base_combo(base, D2TK_ID, nitms, itms, &rect, &val);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == 0);
+ //FIXME test toggling
+
+ d2tk_base_free(base);
+#undef ntims
+}
+
+static void
+_test_combo_scroll_up()
+{
+#define nitms 4
+ 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);
+
+ d2tk_base_add_mouse_scroll(base, 0.f, 1.f);
+
+ const char *itms [nitms] = {
+ "1", "2", "3", "4"
+ };
+ int32_t val = 0;
+ const d2tk_state_t state = d2tk_base_combo(base, D2TK_ID, nitms, itms, &rect, &val);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ |D2TK_STATE_SCROLL_UP | D2TK_STATE_CHANGED | D2TK_STATE_OVER) );
+ assert(val == 1);
+ //FIXME test toggling
+
+ d2tk_base_free(base);
+#undef ntims
+}
+
+static void
+_test_combo_scroll_down()
+{
+#define nitms 4
+ 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);
+
+ d2tk_base_add_mouse_scroll(base, 0.f, -1.f);
+
+ const char *itms [nitms] = {
+ "1", "2", "3", "4"
+ };
+ int32_t val = 0;
+ const d2tk_state_t state = d2tk_base_combo(base, D2TK_ID, nitms, itms, &rect, &val);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_SCROLL_DOWN | D2TK_STATE_OVER) );
+ assert(val == 0);
+ //FIXME test toggling
+
+ d2tk_base_free(base);
+#undef ntims
+}
+
+static void
+_test_text_field()
+{
+ 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);
+
+ d2tk_base_append_char(base, 'h');
+ d2tk_base_append_char(base, 'e');
+ d2tk_base_append_char(base, 'l');
+ d2tk_base_append_char(base, 'l');
+ d2tk_base_append_char(base, 'o');
+
+ char txt [32] = "foo bar";
+ const d2tk_state_t state = d2tk_base_text_field(base, D2TK_ID, &rect,
+ sizeof(txt), txt, D2TK_ALIGN_LEFT, "hello");
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(!strcmp(txt, "foo bar"));
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_label()
+{
+ 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= "label";
+ const d2tk_state_t state = d2tk_base_label(base, -1, lbl, 0.8f, &rect,
+ D2TK_ALIGN_LEFT);
+ assert(state == D2TK_STATE_NONE);
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_dial_bool()
+{
+ 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);
+
+ bool val = false;
+ const d2tk_state_t state = d2tk_base_dial_bool(base, D2TK_ID, &rect, &val);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == false);
+ //FIXME toggling
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_dial_int32()
+{
+ 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);
+
+ int32_t val = 12;
+ const d2tk_state_t state = d2tk_base_dial_int32(base, D2TK_ID, &rect,
+ 0, &val, 20);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == 12);
+ //FIXME toggling
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_dial_int64()
+{
+ 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);
+
+ int64_t val = 12;
+ const d2tk_state_t state = d2tk_base_dial_int64(base, D2TK_ID, &rect,
+ 0, &val, 20);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == 12);
+ //FIXME toggling
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_dial_float()
+{
+ 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);
+
+ float val = 12.f;
+ const d2tk_state_t state = d2tk_base_dial_float(base, D2TK_ID, &rect,
+ 0.f, &val, 20.f);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == 12.f);
+ //FIXME toggling
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_dial_double()
+{
+ 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);
+
+ double val = 12.0;
+ const d2tk_state_t state = d2tk_base_dial_double(base, D2TK_ID, &rect,
+ 0.0, &val, 20.0);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == 12.0);
+ //FIXME toggling
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_prop_int32()
+{
+ 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);
+
+ int32_t val = 12;
+ const d2tk_state_t state = d2tk_base_prop_int32(base, D2TK_ID, &rect,
+ 0, &val, 20);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == 12);
+ //FIXME toggling
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_prop_float()
+{
+ 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);
+
+ float val = 12.f;
+ const d2tk_state_t state = d2tk_base_prop_float(base, D2TK_ID, &rect,
+ 0.f, &val, 20.f);
+ assert(state == (D2TK_STATE_HOT | D2TK_STATE_FOCUS | D2TK_STATE_FOCUS_IN
+ | D2TK_STATE_OVER) );
+ assert(val == 12.f);
+ //FIXME toggling
+
+ d2tk_base_free(base);
+}
+
+static void
+_test_flowmatrix()
+{
+#define N 4
+ d2tk_mock_ctx_t ctx = {
+ .check = NULL
+ };
+ static d2tk_pos_t pos_nodes [N];
+ static d2tk_pos_t pos_arcs [N][N];
+
+ 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);
+
+ D2TK_BASE_FLOWMATRIX(base, &rect, D2TK_ID, flowm)
+ {
+ // draw arcs
+ for(unsigned i = 0; i < N; i++)
+ {
+ const unsigned nin = i + 1;
+
+ d2tk_flowmatrix_set_src(flowm, D2TK_ID, &pos_nodes[i]);
+
+ for(unsigned j = 0; j < N; j++)
+ {
+ const unsigned nout = j + 1;
+ d2tk_state_t state = D2TK_STATE_NONE;
+
+ d2tk_flowmatrix_set_dst(flowm, D2TK_ID, &pos_nodes[j]);
+
+ D2TK_BASE_FLOWMATRIX_ARC(base, flowm, nin, nout, &pos_nodes[i],
+ &pos_nodes[j], &pos_arcs[i][j], arc, &state)
+ {
+ const d2tk_rect_t *bnd = d2tk_flowmatrix_arc_get_rect(arc);
+ const unsigned k = d2tk_flowmatrix_arc_get_index(arc);
+ const unsigned x = d2tk_flowmatrix_arc_get_index_x(arc);
+ const unsigned y = d2tk_flowmatrix_arc_get_index_y(arc);
+
+ assert(pos_nodes[i].x == 0);
+ assert(pos_nodes[i].y == 0);
+ assert(pos_nodes[j].x == 0);
+ assert(pos_nodes[j].y == 0);
+ assert(pos_arcs[i][j].x == 0);
+ assert(pos_arcs[i][j].y == 0);
+ assert(bnd); //FIXME check x,y,w,h
+ (void)k; //FIXME
+ (void)x; //FIXME
+ (void)y; //FIXME
+ }
+
+ assert(state == D2TK_STATE_NONE);
+ }
+ }
+
+ // draw nodes
+ for(int i = 0; i < N; i++)
+ {
+ d2tk_state_t state = D2TK_STATE_NONE;
+
+ D2TK_BASE_FLOWMATRIX_NODE(base, flowm, &pos_nodes[i], node, &state)
+ {
+ const d2tk_rect_t *bnd = d2tk_flowmatrix_node_get_rect(node);
+
+ assert(pos_nodes[i].x == 150 + 150*i);
+ assert(pos_nodes[i].y == 25 + 25*i);
+ assert(bnd); //FIXME check x,y,w,h
+ }
+
+ assert(state == D2TK_STATE_NONE);
+ }
}
d2tk_base_free(base);
@@ -102,6 +1764,46 @@ int
main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
{
_test_hot();
+ _test_mouse_fwd_focus();
+ _test_mouse_bwd_focus();
+ _test_key_fwd_focus();
+ _test_key_bwd_focus();
+ _test_get_set();
+ _test_table();
+ _test_frame();
+ _test_layout_relative_x();
+ _test_layout_relative_y();
+ _test_layout_absolute_x();
+ _test_layout_absolute_y();
+ _test_clip();
+ _test_state();
+ _test_hit();
+ _test_default_style();
+ _test_scrollbar_x();
+ _test_scrollbar_y();
+ _test_pane_x();
+ _test_pane_y();
+ _test_cursor();
+ _test_button_label_image();
+ _test_button_label();
+ _test_button_image();
+ _test_button();
+ _test_toggle_label();
+ _test_toggle();
+ _test_meter();
+ _test_combo();
+ _test_combo_scroll_up();
+ _test_combo_scroll_down();
+ _test_text_field();
+ _test_label();
+ _test_dial_bool();
+ _test_dial_int32();
+ _test_dial_int64();
+ _test_dial_float();
+ _test_dial_double();
+ _test_prop_int32();
+ _test_prop_float();
+ _test_flowmatrix();
return EXIT_SUCCESS;
}