summaryrefslogtreecommitdiff
path: root/gui-over.c
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2016-08-17 20:54:25 -0300
committerWerner Almesberger <werner@almesberger.net>2016-08-17 20:54:25 -0300
commit5014b5de97b9c3fa1600fd8c4d3460520c4ba081 (patch)
treecafd98b7d86d6619c6b9cf13bf42945fca391f57 /gui-over.c
parent34ea81f8d4018fc3ecf91663d741ae5afcbc26d7 (diff)
downloadeeshow-5014b5de97b9c3fa1600fd8c4d3460520c4ba081.tar.gz
eeshow-5014b5de97b9c3fa1600fd8c4d3460520c4ba081.tar.bz2
eeshow-5014b5de97b9c3fa1600fd8c4d3460520c4ba081.zip
eeshow/: move gui* into subdirectory gui/
Diffstat (limited to 'gui-over.c')
-rw-r--r--gui-over.c305
1 files changed, 0 insertions, 305 deletions
diff --git a/gui-over.c b/gui-over.c
deleted file mode 100644
index b648f70..0000000
--- a/gui-over.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * gui-over.c - GUI: overlays
- *
- * Written 2016 by Werner Almesberger
- * Copyright 2016 by Werner Almesberger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-/*
- * Resources:
- *
- * http://zetcode.com/gfx/cairo/cairobackends/
- * https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html
- * https://www.cairographics.org/samples/rounded_rectangle/
- *
- * Section "Description" in
- * https://developer.gnome.org/pango/stable/pango-Cairo-Rendering.html
- */
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-#include <cairo/cairo.h>
-#include <pango/pangocairo.h>
-
-#include "util.h"
-#include "fmt-pango.h"
-#include "gui-aoi.h"
-#include "gui-style.h"
-#include "gui-over.h"
-
-
-struct overlay {
- const char *s;
- struct overlay_style style;
-
- struct aoi **aois;
- bool (*hover)(void *user, bool on);
- void (*click)(void *user);
- void (*drag)(void *user, int dx, int dy);
- void *user;
-
- struct aoi *aoi;
-
- struct overlay *next, *prev;
-};
-
-
-static void rrect(cairo_t *cr, int x, int y, int w, int h, int r)
-{
- const double deg = M_PI / 180.0;
-
- cairo_new_path(cr);
- cairo_arc(cr, x + w - r, y + r, r, -90 * deg, 0);
- cairo_arc(cr, x + w - r, y + h - r, r, 0, 90 * deg);
- cairo_arc(cr, x + r, y + h - r, r, 90 * deg, 180 * deg);
- cairo_arc(cr, x + r, y + r, r, 180 * deg, 270 * deg);
- cairo_close_path(cr);
-}
-
-
-static unsigned overlay_draw(struct overlay *over, cairo_t *cr,
- unsigned x, unsigned y, int dx, int dy)
-{
- const struct overlay_style *style = &over->style;
- const struct color *fg = &style->fg;
- const struct color *bg = &style->bg;
- const struct color *frame = &style->frame;
- unsigned ink_w, ink_h; /* effectively used text area size */
- unsigned w, h; /* box size */
- int tx, ty; /* text start position */
-
- PangoLayout *layout;
- PangoFontDescription *desc;
- PangoRectangle ink_rect;
-
- desc = pango_font_description_from_string(style->font);
- layout = pango_cairo_create_layout(cr);
- pango_layout_set_font_description(layout, desc);
- pango_layout_set_markup(layout, over->s, -1);
- pango_font_description_free(desc);
-
- pango_layout_get_extents(layout, &ink_rect, NULL);
-#if 0
-fprintf(stderr, "%d + %d %d + %d\n",
- ink_rect.x / PANGO_SCALE, ink_rect.width / PANGO_SCALE,
- ink_rect.y / PANGO_SCALE, ink_rect.height / PANGO_SCALE);
-#endif
- ink_w = ink_rect.width / PANGO_SCALE;
- ink_h = ink_rect.height / PANGO_SCALE;
-
- ink_w = ink_w > style->wmin ? ink_w : style->wmin;
- ink_w = !style->wmax || ink_w < style->wmax ? ink_w : style->wmax;
- w = ink_w + 2 * style->pad;
- h = ink_h + 2 * style->pad;
-
- if (dx < 0)
- x -= w;
- if (dy < 0)
- y -= h;
-
- tx = x - ink_rect.x / PANGO_SCALE + style->pad;
- ty = y - ink_rect.y / PANGO_SCALE + style->pad;
-
- rrect(cr, x, y, w, h, style->radius);
-
- cairo_set_source_rgba(cr, bg->r, bg->g, bg->b, bg->alpha);
- cairo_fill_preserve(cr);
- cairo_set_source_rgba(cr, frame->r, frame->g, frame->b, frame->alpha);
- cairo_set_line_width(cr, style->width);
- cairo_stroke(cr);
-
- if (style->wmax) {
- cairo_new_path(cr);
-#if 0
-fprintf(stderr, "%u(%d) %u %.60s\n", ty, ink_rect.y / PANGO_SCALE, ink_h, over->s);
-#endif
-/*
- * @@@ for some mysterious reason, we get
- * ink_h = ink_rect.height / PANGO_SCALE = 5
- * instead of 2 if using overlay_style_dense_selected. Strangely, changing
- * overlay_style_dense_selected such that it becomes more like
- * overlay_style_dense has no effect.
- *
- * This causes the text to be cut vertically, roughly in the middle. We hack
- * around this problem by growind the clipping area vertically. This works,
- * since we're currently only concerned about horizontal clipping anyway.
- */
-
- cairo_rectangle(cr, tx, ty, ink_w, ink_h + 20);
- cairo_clip(cr);
- }
-
- cairo_set_source_rgba(cr, fg->r, fg->g, fg->b, fg->alpha);
- cairo_move_to(cr, tx, ty);
-
- pango_cairo_update_layout(cr, layout);
- pango_cairo_show_layout(cr, layout);
- cairo_reset_clip(cr);
- g_object_unref(layout);
-
- if (over->hover || over->click || over->drag) {
- struct aoi aoi_cfg = {
- .x = x,
- .y = y,
- .w = w,
- .h = h,
- .hover = over->hover,
- .click = over->click,
- .drag = over->drag,
- .user = over->user,
- };
-
- if (over->aoi)
- aoi_update(over->aoi, &aoi_cfg);
- else
- over->aoi = aoi_add(over->aois, &aoi_cfg);
- }
-
- return h;
-}
-
-
-void overlay_draw_all_d(struct overlay *overlays, cairo_t *cr,
- unsigned x, unsigned y, int dx, int dy)
-{
- struct overlay *over = overlays;
- unsigned h;
-
- if (dy < 0)
- while (over && over->next)
- over = over->next;
- while (over) {
- h = overlay_draw(over, cr, x, y, dx, dy);
- y += dy * (h + over->style.skip);
- if (dy >= 0)
- over = over->next;
- else
- over = over->prev;
-
- }
-}
-
-
-void overlay_draw_all(struct overlay *overlays, cairo_t *cr, int x, int y)
-{
- int dx = 1;
- int dy = 1;
-
- if (x < 0 || y < 0) {
- double x1, y1, x2, y2;
- int sw, sh;
-
- cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
- sw = x2 - x1;
- sh = y2 - y1;
- if (x < 0) {
- x = sw + x;
- dx = -1;
- }
- if (y < 0) {
- y = sh + y;
- dy = -1;
- }
- }
-
- overlay_draw_all_d(overlays, cr, x, y, dx, dy);
-}
-
-
-struct overlay *overlay_add(struct overlay **overlays, struct aoi **aois,
- bool (*hover)(void *user, bool on), void (*click)(void *user), void *user)
-{
- struct overlay *over, *prev;
- struct overlay **anchor;
-
- over = alloc_type(struct overlay);
- over->s = NULL;
- over->style = overlay_style_default;
-
- over->aois = aois;
- over->hover = hover;
- over->click = click;
- over->user = user;
- over->aoi = NULL;
-
- prev = NULL;
- for (anchor = overlays; *anchor; anchor = &(*anchor)->next)
- prev = *anchor;
- over->next = NULL;
- over->prev = prev;
- *anchor = over;
-
- return over;
-}
-
-
-void overlay_style(struct overlay *over, const struct overlay_style *style)
-{
- over->style = *style;
-}
-
-
-void overlay_draggable(struct overlay *over,
- void (*drag)(void *user, int dx, int dy))
-{
- over->drag = drag;
-}
-
-
-void overlay_text_raw(struct overlay *over, const char *s)
-{
- free((char *) over->s);
- over->s = stralloc(s);
-}
-
-
-void overlay_text(struct overlay *over, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- overlay_text_raw(over, vfmt_pango(fmt, ap));
- va_end(ap);
-}
-
-
-static void overlay_free(struct overlay *over)
-{
- if (over->aoi)
- aoi_remove(over->aois, over->aoi);
- free((void *) over->s);
- free(over);
-}
-
-
-void overlay_remove(struct overlay **overlays, struct overlay *over)
-{
- if (over->next)
- over->next->prev = over->prev;
- if (over->prev)
- over->prev->next = over->next;
- else
- *overlays = over->next;
- overlay_free(over);
-}
-
-
-void overlay_remove_all(struct overlay **overlays)
-{
- struct overlay *next;
-
- while (*overlays) {
- next = (*overlays)->next;
- overlay_free(*overlays);
- *overlays = next;
- }
-}