aboutsummaryrefslogtreecommitdiff
path: root/teensy
diff options
context:
space:
mode:
Diffstat (limited to 'teensy')
-rw-r--r--teensy/teensy.h3
-rw-r--r--teensy/teensy_math.c19
-rw-r--r--teensy/teensy_renderer.c4
-rw-r--r--teensy/teensy_ui.c74
4 files changed, 55 insertions, 45 deletions
diff --git a/teensy/teensy.h b/teensy/teensy.h
index e5954fc..80f9a71 100644
--- a/teensy/teensy.h
+++ b/teensy/teensy.h
@@ -22,6 +22,7 @@
#define ty_max(a, b) ((a) > (b) ? (a) : (b))
#define ty_min(a, b) ((a) < (b) ? (a) : (b))
+#define ty_clamp(a, mi, ma) (ty_max(ty_min(a, ma), mi))
#define TY_CLIP_NONE (ty_recti(0, 0, -1, -1))
@@ -155,6 +156,8 @@ bool ty_point_in_rect(ty_Vec2 point, ty_Rect rect);
ty_Recti ty_recti_shrink(ty_Recti rect, int p);
// Grows a rect by `p`.
ty_Recti ty_recti_grow(ty_Recti rect, int p);
+// Clamps a rect's bounds to be entirely within another.
+ty_Recti ty_recti_clamp(ty_Recti rect, ty_Recti minmax);
// Creates an image using the relevant data (formatted in RGB8). You may free
// the passed data after this call as it is copied.
diff --git a/teensy/teensy_math.c b/teensy/teensy_math.c
index 5da800c..9247bd0 100644
--- a/teensy/teensy_math.c
+++ b/teensy/teensy_math.c
@@ -36,3 +36,22 @@ ty_Recti ty_recti_grow(ty_Recti rect, int p)
rect.h += p * 2;
return rect;
}
+
+ty_Recti ty_recti_clamp(ty_Recti rect, ty_Recti minmax)
+{
+ ty_Vec2i start = ty_recti_start(rect);
+ ty_Vec2i end = ty_recti_end(rect);
+
+ ty_Vec2i min = ty_recti_start(minmax);
+ ty_Vec2i max = ty_recti_end(minmax);
+
+ start.x = ty_clamp(start.x, min.x, max.x);
+ start.y = ty_clamp(start.y, min.y, max.y);
+ end.x = ty_clamp(end.x, min.x, max.x);
+ end.y = ty_clamp(end.y, min.y, max.y);
+
+ return ty_recti(
+ start.x, start.y,
+ end.x - start.x, end.y - start.y
+ );
+}
diff --git a/teensy/teensy_renderer.c b/teensy/teensy_renderer.c
index 5f6fced..564718a 100644
--- a/teensy/teensy_renderer.c
+++ b/teensy/teensy_renderer.c
@@ -45,8 +45,8 @@ void image_bounds_check(ty_Image img, ty_Vec2i pos)
static
ty_Vec2i clamp_point(ty_Vec2i p, ty_Recti rect)
{
- p.x = fmin(fmax(p.x, rect.x), rect.x + rect.w);
- p.y = fmin(fmax(p.y, rect.y), rect.y + rect.h);
+ p.x = ty_clamp(p.x, rect.x, rect.x + rect.w);
+ p.y = ty_clamp(p.y, rect.y, rect.y + rect.h);
return p;
}
diff --git a/teensy/teensy_ui.c b/teensy/teensy_ui.c
index 27af0cf..32e4ca5 100644
--- a/teensy/teensy_ui.c
+++ b/teensy/teensy_ui.c
@@ -21,7 +21,7 @@
enum {
CMD_RECT,
CMD_TEXT,
- CMD_TARGET,
+ CMD_CLIP,
CMD_IMAGE,
};
typedef uint8_t Cmd_Kind;
@@ -47,7 +47,6 @@ typedef struct {
typedef struct {
const char *title;
ty_Recti rect;
- ty_Image content;
uint32_t flags;
Layout layout_stack[MAX_LAYOUTS];
@@ -123,19 +122,25 @@ void image_cmd(ty_Image img, ty_Recti rect)
}
static
-void target_cmd(ty_Image target)
+void clip_cmd(ty_Recti rect)
{
Cmd cmd = {};
- cmd.kind = CMD_TARGET;
- cmd.img = target;
+ cmd.kind = CMD_CLIP;
+ if (rect.w < 0 || rect.h < 0)
+ rect = window()->rect; // This is a full screen clip
+
+ cmd.rect = ty_recti_clamp(rect, window()->rect);
ty_list_append(uictx.cmds, cmd);
}
static
void draw_frame(ty_Recti rect, ty_Color bg_col)
{
+ clip_cmd(TY_CLIP_NONE);
rect_cmd(rect, uictx.style.frame);
- rect_cmd(ty_recti_shrink(rect, uictx.style.frame_size), bg_col);
+ ty_Recti content_rect = ty_recti_shrink(rect, uictx.style.frame_size);
+ rect_cmd(content_rect, bg_col);
+ clip_cmd(content_rect);
}
static
@@ -186,6 +191,9 @@ ty_Recti next_rect(int height)
y += outer->total_height;
}
+ x += window()->rect.x;
+ y += window()->rect.y;
+
advance_layout();
return ty_recti(x, y, width, height);
@@ -202,18 +210,9 @@ ty_Vec2i mouse_delta(void)
}
static
-ty_Vec2i mouse_pos(void)
-{
- ty_Vec2i mouse_pos = ty_mouse_pos();
- mouse_pos.x -= window()->rect.x;
- mouse_pos.y -= window()->rect.y;
- return mouse_pos;
-}
-
-static
bool is_hovered(ty_Recti rect)
{
- return ty_pointi_in_recti(mouse_pos(), rect);
+ return ty_pointi_in_recti(ty_mouse_pos(), rect);
}
static
@@ -223,7 +222,6 @@ Window create_window(const char *title, ty_Recti rect, uint32_t flags)
win.title = title;
win.rect = rect;
win.flags = flags;
- win.content = ty_create_image(rect.w, rect.h, NULL);
return win;
}
@@ -255,11 +253,6 @@ void tyui_init(const ty_Font *font)
void tyui_deinit(void)
{
ty_list_free(uictx.cmds);
-
- ty_free_image(uictx.root.content);
- for (int i = 0; i < uictx.window_count; i++) {
- ty_free_image(uictx.windows[i].content);
- }
}
void tyui_push_layout(const float *column_widths)
@@ -327,12 +320,8 @@ void tyui_draw(void)
case CMD_IMAGE:
ty_draw_image(cmd.img, ty_recti_start(cmd.rect));
break;
- case CMD_TARGET:
- // Add a draw rect property to the renderer, which allows me to
- // define a rect that anything drawn will be clipped by.
-
- ty_draw_set_target(cmd.img.data ? &cmd.img : NULL);
- if (cmd.img.data != NULL) ty_draw_clear(TY_COLOR_MAGENTA);
+ case CMD_CLIP:
+ ty_draw_set_clip(cmd.rect);
break;
}
}
@@ -397,12 +386,6 @@ bool tyui_begin_window_ex(
if (ty_button_down(TY_BTN_DB_LMB) && hovering_resizer) {
win->rect.w += md.x;
win->rect.h += md.y;
- ty_free_image(win->content);
- win->content = ty_create_image(
- win->rect.w,
- win->rect.h + title_rect.h,
- NULL
- );
}
// Grabbing title bar?
@@ -418,20 +401,26 @@ bool tyui_begin_window_ex(
title_rect.h = title_bar_height();
}
- target_cmd(win->content);
+ clip_cmd(TY_CLIP_NONE);
- title_rect = ty_recti(0, 0, win->rect.w, title_bar_height());
rect_cmd(title_rect, uictx.style.win_title);
text_cmd(win->title, title_rect, TYUI_ALIGN_LEFT);
ty_Recti body_rect = win->rect;
- body_rect.x = 0;
- body_rect.y = title_bar_height();
+ body_rect.y += title_bar_height();
rect_cmd(body_rect, uictx.style.win_bg);
if (hovering_resizer) {
- rect_cmd(ty_recti(win->rect.w-1, title_bar_height(), 1, win->rect.h), uictx.style.win_title);
- rect_cmd(ty_recti(0, win->rect.h-1+title_bar_height(), win->rect.w, 1), uictx.style.win_title);
+ ty_Recti right_bar = ty_recti(
+ win->rect.x + win->rect.w - 1, 0,
+ 1, win->rect.y + win->rect.h
+ );
+ rect_cmd(right_bar, uictx.style.win_title);
+ ty_Recti bot_bar = ty_recti(
+ 0, win->rect.y + win->rect.h - 1,
+ win->rect.x + win->rect.w, 1
+ );
+ rect_cmd(bot_bar, uictx.style.win_title);
}
tyui_push_layout((float[]){-1, 0});
@@ -448,9 +437,7 @@ void tyui_end_window(void)
return;
}
- target_cmd((ty_Image){});
-
- image_cmd(window()->content, window()->rect);
+ clip_cmd(TY_CLIP_NONE);
uictx.active = &uictx.root;
}
@@ -464,6 +451,7 @@ void tyui_text_ex(tyui_Align align, const char *fmt, ...)
ty_Recti rect = next_rect(TEXT_HEIGHT);
+ clip_cmd(rect);
text_cmd(text, rect, align);
}