mirror of
https://git.planet-casio.com/Lephenixnoir/JustUI.git
synced 2024-12-28 04:23:40 +01:00
jwidget: add a per-widget clipping setting
This commit is contained in:
parent
67219834be
commit
950c5b7152
3 changed files with 61 additions and 2 deletions
|
@ -89,8 +89,10 @@ typedef struct jwidget {
|
|||
uint visible :1;
|
||||
/* Widget is floating outside the layout (and positioned manually) */
|
||||
uint floating :1;
|
||||
/* Widget is clipped during rendering */
|
||||
uint clipped :1;
|
||||
|
||||
uint :23;
|
||||
uint :22;
|
||||
|
||||
} jwidget;
|
||||
|
||||
|
@ -358,6 +360,23 @@ bool jwidget_visible(void *w);
|
|||
/* jwidget_set_visible(): Hide or show a widget */
|
||||
void jwidget_set_visible(void *w, bool visible);
|
||||
|
||||
/* jwidget_clipped(): Whether widget is clipped
|
||||
|
||||
If a widget is clipped then its rendering function cannot draw pixels
|
||||
outside of its bounding box. There is no performance cost to this feature
|
||||
because it relies on underlying gint rendering functions already supporting
|
||||
clipping.
|
||||
|
||||
This is disabled by default because it is convenient to have widgets draw
|
||||
outside their bounding box. For instance it is easier to align a single-
|
||||
line label by setting the font's bearing as its height, and then drawing
|
||||
glyphs' tails outside the bouding box. It is also harder to spot layout
|
||||
issues if the widgets are clipped away. */
|
||||
bool jwidget_clipped(void *w);
|
||||
|
||||
/* jwidget_set_clipped(): Set a widget's rendering clipping preference */
|
||||
void jwidget_set_clipped(void *w, bool clipped);
|
||||
|
||||
/* jwidget_needs_update(): Check whether the tree needs to be re-rendered
|
||||
|
||||
If this function returns true, you should re-render the tree. Aditionally,
|
||||
|
|
|
@ -109,6 +109,7 @@ void jwidget_init(jwidget *w, int type, void *parent)
|
|||
w->dirty = 1;
|
||||
w->visible = 1;
|
||||
w->floating = 0;
|
||||
w->clipped = 0;
|
||||
|
||||
w->type = type;
|
||||
w->geometry = NULL;
|
||||
|
@ -597,6 +598,21 @@ void jwidget_set_floating(void *w0, bool floating)
|
|||
if(w->parent) w->parent->dirty = 1;
|
||||
}
|
||||
|
||||
bool jwidget_clipped(void *w0)
|
||||
{
|
||||
J_CAST(w)
|
||||
return w->clipped;
|
||||
}
|
||||
|
||||
void jwidget_set_clipped(void *w0, bool clipped)
|
||||
{
|
||||
J_CAST(w)
|
||||
if(w->clipped == clipped) return;
|
||||
|
||||
w->clipped = (clipped != 0);
|
||||
w->update = 1;
|
||||
}
|
||||
|
||||
//---
|
||||
// Rendering
|
||||
//---
|
||||
|
@ -643,7 +659,18 @@ void jwidget_render(void *w0, int x, int y)
|
|||
y += g->margin.top + b.top + g->padding.top;
|
||||
|
||||
jwidget_poly const *poly = widget_types[w->type];
|
||||
if(poly->render) poly->render(w, x, y);
|
||||
if(poly->render) {
|
||||
if(w->clipped) {
|
||||
struct dwindow win = { x, y, x+cw, y+ch };
|
||||
win = intersect_dwindow(win, dwindow);
|
||||
struct dwindow old_window = dwindow_set(win);
|
||||
poly->render(w, x, y);
|
||||
dwindow_set(old_window);
|
||||
}
|
||||
else {
|
||||
poly->render(w, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
w->update = 0;
|
||||
}
|
||||
|
|
13
src/util.h
13
src/util.h
|
@ -6,6 +6,7 @@
|
|||
#define _J_UTIL
|
||||
|
||||
#include <justui/defs.h>
|
||||
#include <gint/display.h>
|
||||
|
||||
/* Clamp a value between two ends. */
|
||||
__attribute__((always_inline))
|
||||
|
@ -20,4 +21,16 @@ static inline int clamp(int value, int min, int max)
|
|||
/* Code point for a character input */
|
||||
uint32_t keymap_translate(int key, bool shift, bool alpha);
|
||||
|
||||
/* Intersect two dwindow settings. */
|
||||
static inline struct dwindow intersect_dwindow(
|
||||
struct dwindow d1, struct dwindow d2)
|
||||
{
|
||||
struct dwindow win;
|
||||
win.left = max(d1.left, d2.left);
|
||||
win.top = max(d1.top, d2.top);
|
||||
win.right = max(min(d1.right, d2.right), win.left);
|
||||
win.bottom = max(min(d1.bottom, d2.bottom), win.top);
|
||||
return win;
|
||||
}
|
||||
|
||||
#endif /* _J_UTIL */
|
||||
|
|
Loading…
Reference in a new issue