Beispiel #1
0
struct rtb_element *
rtb_elem_nearest_clearable(struct rtb_element *self)
{
	struct rtb_surface *surface = self->surface;

	for (; self != RTB_ELEMENT(surface); self = self->parent)
		if (rtb_elem_is_clearable(self))
			return self;

	return RTB_ELEMENT(surface);
}
Beispiel #2
0
static int
dispatch_click_event(struct rtb_button *self, const struct rtb_mouse_event *e)
{
	struct rtb_button_event event = *((struct rtb_button_event *) e);

	event.type = RTB_BUTTON_CLICK;
	event.cursor.x -= self->x;
	event.cursor.y -= self->y;

	return rtb_handle(RTB_ELEMENT(self), RTB_EVENT(&event));
}
Beispiel #3
0
static void
attached(struct rtb_element *elem,
		struct rtb_element *parent, struct rtb_window *window)
{
	SELF_FROM(elem);

	super.attached(elem, parent, window);
	self->type = rtb_type_ref(window, self->type,
			"net.illest.rutabaga.window");

	rtb_style_resolve_list(self, self->style_list);
	self->restyle(RTB_ELEMENT(self));
}
Beispiel #4
0
int
rtb_button_init(struct rtb_button *self)
{
	if (RTB_SUBCLASS(RTB_ELEMENT(self), rtb_elem_init, &super))
		return -1;

	rtb_label_init(&self->label);
	rtb_elem_add_child(RTB_ELEMENT(self), RTB_ELEMENT(&self->label),
			RTB_ADD_HEAD);

	self->label.align = RTB_ALIGN_MIDDLE;
	self->outer_pad.x =
		self->outer_pad.y = 0.f;

	self->on_event  = on_event;
	self->attached  = attached;
	self->layout_cb = rtb_layout_hpack_center;
	self->size_cb   = rtb_size_hfit_children;
	self->reflow    = reflow;

	return 0;
}
Beispiel #5
0
void
rtb_window_reinit(struct rtb_window *self)
{
	struct rtb_element *elem = RTB_ELEMENT(self);

	self->x = self->y = 0.f;

	glScissor(0, 0, self->w, self->h);

	if (!self->window)
		self->attached(elem, NULL, self);

	rtb_elem_trigger_reflow(elem, elem, RTB_DIRECTION_LEAFWARD);
}
Beispiel #6
0
int
rtb_elem_is_clearable(struct rtb_element *self)
{
	struct rtb_surface *surface = self->surface;

	/* XXX: shouldn't depend on stylequad like this */

	for (self = self->parent;
			self != RTB_ELEMENT(surface); self = self->parent)
		if (self->stylequad.properties.bg_color)
			return 0;

	return 1;
}
Beispiel #7
0
static void
mark_dirty(struct rtb_element *self)
{
	struct rtb_surface *surface = self->surface;

	self = rtb_elem_nearest_clearable(self);

	if (!surface || surface->surface_state == RTB_SURFACE_INVALID
			|| self->render_entry.tqe_next || self->render_entry.tqe_prev)
		return;

	TAILQ_INSERT_TAIL(&surface->render_queue, self, render_entry);
	rtb_elem_mark_dirty(RTB_ELEMENT(surface));
}
Beispiel #8
0
static int
handle_key_press(struct rtb_button *self, const struct rtb_key_event *e)
{
	struct rtb_button_event event = {
		.type   = RTB_BUTTON_CLICK,
		.source = RTB_EVENT_SYNTHETIC
	};

	if ((e->keysym == RTB_KEY_NORMAL && e->character == ' ')
			|| (e->keysym == RTB_KEY_ENTER)) {
		rtb_handle(RTB_ELEMENT(self), RTB_EVENT(&event));
		return 1;
	}

	return 0;
}
Beispiel #9
0
int
main(int argc, char **argv)
{
	struct rutabaga *delicious;
	struct rtb_window *win;

	struct rtb_button click_me;

	delicious = rtb_new();
	assert(delicious);
	win = rtb_window_open(delicious, 600, 700, "rtb basic demo");
	assert(win);

	rtb_elem_set_size_cb(RTB_ELEMENT(win), rtb_size_hfit_children);
	rtb_elem_set_layout(RTB_ELEMENT(win), rtb_layout_hpack_center);

	rtb_label_init(&click_counter);
	rtb_button_init(&click_me);

	click_counter.align = RTB_ALIGN_MIDDLE;
	click_me.align = RTB_ALIGN_MIDDLE;
	click_me.flags |= RTB_ELEM_CLICK_FOCUS;

	rtb_button_set_label(&click_me, "click me");
	update_label();

	rtb_register_handler(RTB_ELEMENT(&click_me),
			RTB_BUTTON_CLICK, button_clicked, NULL);

	rtb_elem_add_child(RTB_ELEMENT(win), RTB_ELEMENT(&click_counter),
			RTB_ADD_TAIL);
	rtb_elem_add_child(RTB_ELEMENT(win), RTB_ELEMENT(&click_me),
			RTB_ADD_TAIL);

	rtb_event_loop(delicious);

	rtb_window_lock(win);

	rtb_label_fini(&click_counter);
	rtb_window_close(delicious->win);
	rtb_free(delicious);
}
Beispiel #10
0
int
rtb_window_draw(struct rtb_window *self, int force_redraw)
{
	const struct rtb_style_property_definition *prop;
	struct rtb_window_event ev;

	if (self->state == RTB_STATE_UNATTACHED
			|| self->visibility == RTB_FULLY_OBSCURED)
		return 0;

	ev.type = RTB_FRAME_START;
	ev.source = RTB_EVENT_GENUINE;
	ev.window = self;
	rtb_dispatch_raw(RTB_ELEMENT(self), RTB_EVENT(&ev));

	if (!self->dirty || force_redraw)
		return 0;

	glViewport(0, 0, self->w, self->h);

	prop = rtb_style_query_prop(RTB_ELEMENT(self),
			"background-color", RTB_STYLE_PROP_COLOR, 1);

	glEnable(GL_DITHER);
	glEnable(GL_BLEND);
	glEnable(GL_SCISSOR_TEST);

	glClearColor(
			prop->color.r,
			prop->color.g,
			prop->color.b,
			prop->color.a);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	rtb_render_push(RTB_ELEMENT(self));
	self->draw(RTB_ELEMENT(self));
	rtb_render_pop(RTB_ELEMENT(self));

	self->dirty = 0;

	ev.type = RTB_FRAME_END;
	rtb_dispatch_raw(RTB_ELEMENT(self), RTB_EVENT(&ev));

	return 1;
}
Beispiel #11
0
static int
win_event(struct rtb_element *elem, const struct rtb_event *e)
{
	SELF_FROM(elem);

	switch (e->type) {
	case RTB_WINDOW_CLOSE:
		if (!rtb_handle(elem, e))
			rtb_event_loop_stop(self->rtb);
		return 1;

	case RTB_KEY_PRESS:
	case RTB_KEY_RELEASE:
		if (self->focus && self->focus != RTB_ELEMENT(self))
			if (rtb_elem_deliver_event(self->focus, e))
				return 1;

		if (rtb_handle(elem, e))
			return 1;
	}

	return super.on_event(elem, e);
}
Beispiel #12
0
struct rtb_window *
rtb_window_open_under(struct rutabaga *r, intptr_t parent,
		int w, int h, const char *title)
{
	struct rtb_style_data stdata;
	struct rtb_window *self;

	assert(r);
	assert(h > 0);
	assert(w > 0);
	assert(!r->win);

	self = window_impl_open(r, w, h, title, parent);
	if (!self)
		goto err_window_impl;

	init_gl();

	if (RTB_SUBCLASS(RTB_SURFACE(self), rtb_surface_init, &super))
		goto err_surface_init;

	self->w = w;
	self->h = h;

	self->surface = RTB_SURFACE(self);

	stdata = rtb_style_get_defaults();
	self->style_list = stdata.style;
	self->style_fonts = calloc(stdata.nfonts, sizeof(*self->style_fonts));

	if (shaders_init(self))
		goto err_shaders;

	if (ibos_init(self))
		goto err_ibos;

	if (rtb_font_manager_init(&self->font_manager,
				self->dpi.x, self->dpi.y))
		goto err_font;

	rtb_elem_set_layout(RTB_ELEMENT(self), rtb_layout_vpack_top);

	self->on_event   = win_event;
	self->mark_dirty = mark_dirty;
	self->attached   = attached;

	self->flags = RTB_ELEM_CLICK_FOCUS;

	/* for core profiles */
	glGenVertexArrays(1, &self->vao);
	glBindVertexArray(self->vao);

	self->rtb = r;
	r->win = self;

	self->mouse.current_cursor = RTB_MOUSE_CURSOR_DEFAULT;

	return self;

err_font:
	ibos_fini(self);
err_ibos:
	shaders_fini(self);
err_shaders:
err_surface_init:
	window_impl_close(self);
err_window_impl:
	return NULL;
}
Beispiel #13
0
void
rtb_button_fini(struct rtb_button *self)
{
	rtb_label_fini(&self->label);
	rtb_elem_fini(RTB_ELEMENT(self));
}