ui: add cairo-text widget
This commit is contained in:
parent
1219ec1563
commit
98885e34a3
@ -60,6 +60,7 @@ src = [
|
||||
'src/widgets/cairo-box.c',
|
||||
'src/widgets/cairo-window.c',
|
||||
'src/widgets/cairo-image.c',
|
||||
'src/widgets/cairo-text.c',
|
||||
'src/main.c',
|
||||
wayland_targets]
|
||||
|
||||
|
@ -13,10 +13,19 @@
|
||||
#include "widgets/cairo-window.h"
|
||||
#include "widgets/cairo-box.h"
|
||||
#include "widgets/cairo-image.h"
|
||||
#include "widgets/cairo-text.h"
|
||||
|
||||
#define DEF_SURF_W 600
|
||||
#define DEF_SURF_H 400
|
||||
|
||||
#define LOREM "Lorem ipsum dolor sit amet, consectetur adipiscing elit,\n" \
|
||||
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n" \
|
||||
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris \n" \
|
||||
"nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in \n" \
|
||||
"reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n" \
|
||||
"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia \n" \
|
||||
"deserunt mollit anim id est laborum."
|
||||
|
||||
struct _DiyaLockSession
|
||||
{
|
||||
DiyaObject parent;
|
||||
@ -314,13 +323,13 @@ static void diya_lock_session_ui(DiyaCairoWindow * window)
|
||||
NULL);
|
||||
diya_cairo_container_add(box, hbox);
|
||||
|
||||
|
||||
hbox = g_object_new(DIYA_TYPE_CAIRO_BOX,
|
||||
"mode", DIYA_CAIRO_BOX_HORIZONTAL,
|
||||
"vspace", DIYA_CAIRO_WIDGET_FILL_CONTENT,
|
||||
"hspace", DIYA_CAIRO_WIDGET_FILL_CONTENT,
|
||||
"stroke", &stroke,
|
||||
"padding", &padding,
|
||||
"corner-radius", 10.0,
|
||||
NULL);
|
||||
diya_cairo_container_add(box, hbox);
|
||||
|
||||
@ -328,7 +337,26 @@ static void diya_lock_session_ui(DiyaCairoWindow * window)
|
||||
2.0,
|
||||
{ 0.0, 0.0, 1.0, 1.0 }
|
||||
};
|
||||
DiyaCairoImage * image = g_object_new(DIYA_TYPE_CAIRO_IMAGE,
|
||||
diya_color_t fill = { 1.0,1.0,1.0,1.0 };
|
||||
diya_color_t color = { 0.0,0.0,0.0,1.0 };
|
||||
|
||||
DiyaCairoText *text = g_object_new(DIYA_TYPE_CAIRO_TEXT,
|
||||
"vspace", DIYA_CAIRO_WIDGET_FILL_NONE,
|
||||
"hspace", DIYA_CAIRO_WIDGET_FILL_NONE,
|
||||
"stroke", &stroke,
|
||||
"padding", &padding,
|
||||
"corner-radius", 5.0,
|
||||
"fill", &fill,
|
||||
"color", &color,
|
||||
"font-size", 11,
|
||||
"font-family", "Monospace",
|
||||
"halign", DIYA_CAIRO_WIDGET_ALIGN_START,
|
||||
"valign", DIYA_CAIRO_WIDGET_ALIGN_START,
|
||||
NULL);
|
||||
diya_cairo_text_set_text(text, LOREM);
|
||||
diya_cairo_widget_set_size(text, 600, 400);
|
||||
diya_cairo_container_add(hbox, text);
|
||||
/*DiyaCairoImage * image = g_object_new(DIYA_TYPE_CAIRO_IMAGE,
|
||||
"file",
|
||||
"/home/diya/test.jpg",
|
||||
"stroke",
|
||||
@ -336,7 +364,7 @@ static void diya_lock_session_ui(DiyaCairoWindow * window)
|
||||
"vspace", DIYA_CAIRO_WIDGET_FILL_NONE,
|
||||
"hspace", DIYA_CAIRO_WIDGET_FILL_NONE,
|
||||
NULL);
|
||||
diya_cairo_container_add(hbox, image);
|
||||
diya_cairo_container_add(hbox, image);*/
|
||||
|
||||
hbox = g_object_new(DIYA_TYPE_CAIRO_BOX,
|
||||
"mode", DIYA_CAIRO_BOX_HORIZONTAL,
|
||||
|
@ -92,6 +92,7 @@ static void cairo_box_update(gpointer object)
|
||||
diya_rect_t space = diya_cairo_widget_get_extent(object);
|
||||
diya_offset_t * padding;
|
||||
diya_stroke_t * stroke;
|
||||
diya_rect_t * default_extent;
|
||||
g_object_get(object,"padding", &padding, "stroke", &stroke, NULL);
|
||||
gint stroke_size = ceil(stroke->size);
|
||||
gpointer item;
|
||||
@ -110,7 +111,7 @@ static void cairo_box_update(gpointer object)
|
||||
}
|
||||
G_LIST_FOREACH(item, children)
|
||||
{
|
||||
g_object_get(item, "vspace", &vspace, "hspace", &hspace, NULL);
|
||||
g_object_get(item, "vspace", &vspace, "hspace", &hspace, "default-extent", &default_extent, NULL);
|
||||
DIYA_CAIRO_WIDGET_GET_CLASS(item)->content_size(item, &cwidth, &cheight);
|
||||
if(self->mode == DIYA_CAIRO_BOX_HORIZONTAL)
|
||||
{
|
||||
@ -120,9 +121,11 @@ static void cairo_box_update(gpointer object)
|
||||
n_extended++;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_CONTENT:
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
occupied_space += cwidth;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
occupied_space += default_extent->width;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -135,9 +138,11 @@ static void cairo_box_update(gpointer object)
|
||||
n_extended++;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_CONTENT:
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
occupied_space += cheight;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
occupied_space += default_extent->height;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -149,7 +154,7 @@ static void cairo_box_update(gpointer object)
|
||||
|
||||
G_LIST_FOREACH(item, children)
|
||||
{
|
||||
g_object_get(item, "vspace", &vspace, "hspace", &hspace, NULL);
|
||||
g_object_get(item, "vspace", &vspace, "hspace", &hspace, "default-extent", &default_extent, NULL);
|
||||
DIYA_CAIRO_WIDGET_GET_CLASS(item)->content_size(item, &cwidth, &cheight);
|
||||
|
||||
diya_rect_t rect = {0};
|
||||
@ -166,7 +171,6 @@ static void cairo_box_update(gpointer object)
|
||||
off_x += rect.width;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_CONTENT:
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
rect.width = cwidth;
|
||||
if(!DIYA_IS_CAIRO_BOX(item))
|
||||
{
|
||||
@ -174,6 +178,14 @@ static void cairo_box_update(gpointer object)
|
||||
}
|
||||
off_x += cwidth;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
rect.width = default_extent->width;
|
||||
if(!DIYA_IS_CAIRO_BOX(item))
|
||||
{
|
||||
rect.height = default_extent->height;
|
||||
}
|
||||
off_x += default_extent->width;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -188,7 +200,6 @@ static void cairo_box_update(gpointer object)
|
||||
off_y += rect.height;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_CONTENT:
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
rect.height = cheight;
|
||||
if(!DIYA_IS_CAIRO_BOX(item))
|
||||
{
|
||||
@ -196,6 +207,14 @@ static void cairo_box_update(gpointer object)
|
||||
}
|
||||
off_y += cheight;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
rect.height = default_extent->height;
|
||||
if(!DIYA_IS_CAIRO_BOX(item))
|
||||
{
|
||||
rect.width = default_extent->width;
|
||||
}
|
||||
off_y += default_extent->height;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ static gboolean diya_cairo_image_draw(gpointer object, cairo_t * context)
|
||||
break;
|
||||
}
|
||||
|
||||
g_warning("Global position %d %d offset %d %d", gpos.x, gpos.y, off_x, off_y);
|
||||
//g_warning("Global position %d %d offset %d %d", gpos.x, gpos.y, off_x, off_y);
|
||||
|
||||
if(color->a > 0)
|
||||
{
|
||||
|
367
src/widgets/cairo-text.c
Normal file
367
src/widgets/cairo-text.c
Normal file
@ -0,0 +1,367 @@
|
||||
#include <assert.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <math.h>
|
||||
#include "cairo-text.h"
|
||||
|
||||
#define FONT "Sans Bold 10"
|
||||
|
||||
enum
|
||||
{
|
||||
NO_PROP,
|
||||
C_TEXT,
|
||||
C_FONT_FAMILY,
|
||||
C_FONT_SIZE,
|
||||
C_FONT_STYLE,
|
||||
C_FONT_WEIGHT,
|
||||
C_COLOR,
|
||||
C_WRAP,
|
||||
N_PROPERTIES
|
||||
};
|
||||
static GParamSpec *g_prop[N_PROPERTIES] = {0};
|
||||
|
||||
typedef struct _DiyaCairoTextPrivate
|
||||
{
|
||||
DiyaCairoWidget parent_object;
|
||||
|
||||
gchar *text;
|
||||
gchar *family;
|
||||
int size;
|
||||
guint style;
|
||||
guint wrap;
|
||||
guint weight;
|
||||
diya_color_t color;
|
||||
} DiyaCairoTextPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(DiyaCairoText, diya_cairo_text, DIYA_TYPE_CAIRO_WIDGET)
|
||||
|
||||
static void diya_cairo_text_dispose(GObject *object)
|
||||
{
|
||||
DiyaCairoText *self = DIYA_CAIRO_TEXT(object);
|
||||
DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self);
|
||||
g_debug("diya_cairo_text_dispose: %s", diya_object_to_string(object));
|
||||
if (priv->text)
|
||||
{
|
||||
g_free(priv->text);
|
||||
}
|
||||
if (priv->family)
|
||||
{
|
||||
g_free(priv->family);
|
||||
}
|
||||
G_OBJECT_CLASS(diya_cairo_text_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void diya_cairo_text_init(DiyaCairoText *self)
|
||||
{
|
||||
DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self);
|
||||
priv->text = NULL;
|
||||
priv->family = NULL;
|
||||
priv->size = 10;
|
||||
priv->style = DIYA_CAIRO_FONT_STYLE_NORMAL;
|
||||
priv->weight = DIYA_CAIRO_FONT_WEIGHT_NORMAL;
|
||||
priv->wrap = DIYA_CAIRO_TEXT_WRAP_WORD;
|
||||
}
|
||||
|
||||
static void diya_cairo_text_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
DiyaCairoText *self = DIYA_CAIRO_TEXT(object);
|
||||
DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self);
|
||||
switch (property_id)
|
||||
{
|
||||
case C_TEXT:
|
||||
if (priv->text)
|
||||
{
|
||||
g_free(priv->text);
|
||||
}
|
||||
priv->text = g_strdup(g_value_get_pointer(value));
|
||||
break;
|
||||
case C_FONT_FAMILY:
|
||||
if (priv->family)
|
||||
{
|
||||
g_free(priv->family);
|
||||
}
|
||||
priv->family = g_strdup(g_value_get_pointer(value));
|
||||
break;
|
||||
case C_FONT_SIZE:
|
||||
priv->size = g_value_get_int(value);
|
||||
break;
|
||||
case C_FONT_STYLE:
|
||||
priv->style = g_value_get_uint(value);
|
||||
break;
|
||||
case C_WRAP:
|
||||
priv->wrap = g_value_get_uint(value);
|
||||
break;
|
||||
case C_FONT_WEIGHT:
|
||||
priv->weight = g_value_get_uint(value);
|
||||
break;
|
||||
case C_COLOR:
|
||||
memcpy(&priv->color,g_value_get_pointer(value), sizeof(priv->color));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void diya_cairo_text_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
DiyaCairoText *self = DIYA_CAIRO_TEXT(object);
|
||||
DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self);
|
||||
switch (property_id)
|
||||
{
|
||||
case C_TEXT:
|
||||
g_value_set_pointer(value, priv->text);
|
||||
break;
|
||||
case C_FONT_FAMILY:
|
||||
g_value_set_pointer(value, priv->family);
|
||||
break;
|
||||
case C_FONT_SIZE:
|
||||
g_value_set_int(value, priv->size);
|
||||
break;
|
||||
case C_FONT_STYLE:
|
||||
g_value_set_uint(value, priv->style);
|
||||
break;
|
||||
case C_WRAP:
|
||||
g_value_set_uint(value, priv->wrap);
|
||||
break;
|
||||
case C_FONT_WEIGHT:
|
||||
g_value_set_uint(value, priv->weight);
|
||||
break;
|
||||
case C_COLOR:
|
||||
g_value_set_pointer(value, &priv->color);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static PangoFontDescription *diya_cairo_text_get_pango_font_desc(DiyaCairoText *self)
|
||||
{
|
||||
PangoFontDescription *desc = pango_font_description_new();
|
||||
DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self);
|
||||
if (priv->family)
|
||||
{
|
||||
pango_font_description_set_family(desc, priv->family);
|
||||
}
|
||||
pango_font_description_set_size(desc, priv->size * PANGO_SCALE);
|
||||
pango_font_description_set_style(desc, priv->style);
|
||||
pango_font_description_set_weight(desc, priv->weight);
|
||||
return desc;
|
||||
}
|
||||
|
||||
static gboolean diya_cairo_text_draw(gpointer object, cairo_t *context)
|
||||
{
|
||||
DiyaCairoText *self = DIYA_CAIRO_TEXT(object);
|
||||
DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self);
|
||||
if(!diya_cairo_widget_is_damaged(object) || !diya_cairo_widget_is_visible(object))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
DIYA_CAIRO_WIDGET_CLASS(diya_cairo_text_parent_class)->draw(object, context);
|
||||
diya_rect_t view_port = diya_cairo_widget_get_view_port(object);
|
||||
diya_rect_dump("diya_cairo_text_draw: ", &view_port);
|
||||
|
||||
if(diya_rect_is_empty(&view_port))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
cairo_save(context);
|
||||
cairo_rectangle(context, view_port.x, view_port.y, view_port.width, view_port.height);
|
||||
cairo_clip(context);
|
||||
|
||||
diya_rect_t extent = diya_cairo_widget_get_extent(object);
|
||||
g_warning("diya_cairo_widget_get_extent: width %d, %d", extent.width, extent.height);
|
||||
diya_offset_t * padding, *margin;
|
||||
diya_stroke_t *stroke;
|
||||
diya_color_t *color;
|
||||
guint halign, valign;
|
||||
g_object_get(object,
|
||||
"stroke", &stroke,
|
||||
"halign", &halign,
|
||||
"valign", &valign,
|
||||
"margin", &margin,
|
||||
"padding", &padding,
|
||||
"color", &color,
|
||||
NULL);
|
||||
gint stroke_size = ceil(stroke->size);
|
||||
diya_point_t gpos = diya_cairo_widget_get_global_position(object);
|
||||
|
||||
PangoFontDescription *desc = diya_cairo_text_get_pango_font_desc(object);
|
||||
cairo_set_source_rgba(context, color->r, color->g, color->b, color->a);
|
||||
int display_w = extent.width - padding->left - padding->right - margin->left - margin->right - 2*stroke_size;
|
||||
int display_h = extent.height - padding->top - padding->bottom - margin->top - margin->bottom - 2*stroke_size;
|
||||
int off_x = padding->left + margin->left + stroke_size;
|
||||
int off_y = padding->top + margin->top + stroke_size;
|
||||
|
||||
PangoLayout *layout = pango_cairo_create_layout(context);
|
||||
// take into account my padding setting
|
||||
pango_layout_set_text(layout, priv->text, -1);
|
||||
pango_layout_set_font_description(layout, desc);
|
||||
pango_layout_set_width(layout,display_w*PANGO_SCALE);
|
||||
pango_layout_set_height(layout, display_h*PANGO_SCALE);
|
||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
||||
pango_layout_set_wrap(layout, priv->wrap);
|
||||
switch(halign)
|
||||
{
|
||||
case DIYA_CAIRO_WIDGET_ALIGN_START:
|
||||
pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_ALIGN_MIDDLE:
|
||||
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_ALIGN_END:
|
||||
pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
|
||||
break;
|
||||
}
|
||||
PangoRectangle text_rect = {0};
|
||||
pango_layout_get_extents(layout, NULL, &text_rect);
|
||||
pango_extents_to_pixels(&text_rect, NULL);
|
||||
// draw text
|
||||
switch (valign)
|
||||
{
|
||||
case DIYA_CAIRO_WIDGET_ALIGN_MIDDLE:
|
||||
off_y += (display_h - text_rect.height)/ 2;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_ALIGN_END:
|
||||
off_y += display_h - text_rect.height;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cairo_move_to(context, gpos.x + off_x, gpos.y + off_y);
|
||||
pango_cairo_update_layout(context, layout);
|
||||
pango_cairo_show_layout(context, layout);
|
||||
|
||||
cairo_restore(context);
|
||||
pango_font_description_free(desc);
|
||||
g_object_unref(layout);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void diya_cairo_text_content_size(gpointer object, int *width, int *height)
|
||||
{
|
||||
diya_offset_t* padding, *margin;
|
||||
diya_stroke_t * stroke;
|
||||
diya_rect_t * def_xtent;
|
||||
guint hspace,vspace;
|
||||
g_object_get(object,
|
||||
"padding", &padding,
|
||||
"margin", &margin,
|
||||
"stroke", &stroke,
|
||||
"hspace", &hspace,
|
||||
"vspace", &vspace,
|
||||
"default-extent", &def_xtent,
|
||||
NULL);
|
||||
gint stroke_size = ceil(stroke->size) * 2;
|
||||
*width = padding->left + padding->right + margin->left + margin->right + stroke_size;
|
||||
*height = padding->top + padding->bottom + margin->top + margin->bottom + stroke_size;
|
||||
DiyaCairoText *self = DIYA_CAIRO_TEXT(object);
|
||||
DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self);
|
||||
// diya_rect_t default_extent = DIYA_CAIRO_WIDGET_GET_CLASS(object)->default_extent(object);
|
||||
int text_width = 0;
|
||||
int text_height = 0;
|
||||
if (priv->text)
|
||||
{
|
||||
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
|
||||
cairo_t *context = cairo_create(surface);
|
||||
PangoLayout *layout = pango_cairo_create_layout(context);
|
||||
PangoFontDescription *desc = diya_cairo_text_get_pango_font_desc(object);
|
||||
pango_layout_set_font_description(layout, desc);
|
||||
pango_layout_set_text(layout, priv->text, -1);
|
||||
pango_layout_set_width(layout, -1);
|
||||
pango_layout_set_height(layout, -1);
|
||||
pango_layout_set_single_paragraph_mode(layout, FALSE);
|
||||
//pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_MIDDLE);
|
||||
PangoRectangle rect = {0};
|
||||
pango_layout_get_extents(layout, NULL, &rect);
|
||||
pango_extents_to_pixels(&rect, NULL);
|
||||
//rect.width += 4;
|
||||
text_width = rect.width;
|
||||
text_height = rect.height;
|
||||
cairo_destroy(context);
|
||||
cairo_surface_destroy(surface);
|
||||
pango_font_description_free(desc);
|
||||
g_object_unref(layout);
|
||||
}
|
||||
|
||||
switch (hspace)
|
||||
{
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
*width = def_xtent->width;
|
||||
break;
|
||||
default:
|
||||
*width += text_width;
|
||||
break;
|
||||
}
|
||||
switch (vspace)
|
||||
{
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
*height = def_xtent->height;
|
||||
break;
|
||||
default:
|
||||
*height += text_height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void diya_cairo_text_class_init(DiyaCairoTextClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
DiyaCairoWidgetClass *wclass = DIYA_CAIRO_WIDGET_CLASS(class);
|
||||
|
||||
class->set_text = diya_cairo_text_set_text;
|
||||
class->get_text = diya_cairo_text_get_text;
|
||||
|
||||
wclass->draw = diya_cairo_text_draw;
|
||||
wclass->content_size = diya_cairo_text_content_size;
|
||||
|
||||
DIYA_CAIRO_WIDGET_SET_NAME(class, "DiyaCairoText");
|
||||
gobject_class->dispose = diya_cairo_text_dispose;
|
||||
gobject_class->set_property = diya_cairo_text_set_property;
|
||||
gobject_class->get_property = diya_cairo_text_get_property;
|
||||
|
||||
g_prop[C_TEXT] = g_param_spec_pointer("text", NULL, "text content", G_PARAM_READWRITE);
|
||||
g_prop[C_FONT_FAMILY] = g_param_spec_pointer("font-family", NULL, "text font face", G_PARAM_READWRITE);
|
||||
g_prop[C_COLOR] = g_param_spec_pointer("color", NULL, "text color", G_PARAM_READWRITE);
|
||||
|
||||
g_prop[C_FONT_STYLE] = g_param_spec_uint(
|
||||
"font-style", NULL, "text font style",
|
||||
DIYA_CAIRO_FONT_STYLE_NORMAL,
|
||||
DIYA_CAIRO_FONT_STYLE_ITALIC,
|
||||
DIYA_CAIRO_FONT_STYLE_NORMAL,
|
||||
G_PARAM_READWRITE);
|
||||
g_prop[C_FONT_WEIGHT] = g_param_spec_uint(
|
||||
"font-weight", NULL, "text font weight",
|
||||
PANGO_WEIGHT_THIN,
|
||||
PANGO_WEIGHT_ULTRAHEAVY,
|
||||
DIYA_CAIRO_FONT_WEIGHT_NORMAL,
|
||||
G_PARAM_READWRITE);
|
||||
g_prop[C_FONT_SIZE] = g_param_spec_int(
|
||||
"font-size", NULL, "text font size",
|
||||
0,
|
||||
G_MAXINT,
|
||||
10,
|
||||
G_PARAM_READWRITE);
|
||||
g_prop[C_WRAP] = g_param_spec_uint(
|
||||
"wrap", NULL, "text wrap mode",
|
||||
DIYA_CAIRO_TEXT_WRAP_WORD,
|
||||
DIYA_CAIRO_TEXT_WRAP_WORD_CHAR,
|
||||
DIYA_CAIRO_TEXT_WRAP_WORD,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties(gobject_class, N_PROPERTIES, g_prop);
|
||||
}
|
||||
|
||||
void diya_cairo_text_set_text(gpointer object, const gchar *text)
|
||||
{
|
||||
assert(DIYA_IS_CAIRO_TEXT(object));
|
||||
g_object_set(object, "text", text, NULL);
|
||||
}
|
||||
const gchar *diya_cairo_text_get_text(gpointer object)
|
||||
{
|
||||
assert(DIYA_IS_CAIRO_TEXT(object));
|
||||
DiyaCairoText *self = DIYA_CAIRO_TEXT(object);
|
||||
DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self);
|
||||
return priv->text;
|
||||
}
|
31
src/widgets/cairo-text.h
Normal file
31
src/widgets/cairo-text.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef CAIRO_TEXT_H
|
||||
#define CAIRO_TEXT_H
|
||||
#include <pango/pangocairo.h>
|
||||
#include "cairo-widget.h"
|
||||
|
||||
|
||||
#define DIYA_CAIRO_FONT_STYLE_NORMAL PANGO_STYLE_NORMAL
|
||||
#define DIYA_CAIRO_FONT_STYLE_ITALIC PANGO_STYLE_ITALIC
|
||||
#define DIYA_CAIRO_FONT_STYLE_OBLIQUE PANGO_STYLE_OBLIQUE
|
||||
|
||||
#define DIYA_CAIRO_FONT_WEIGHT_NORMAL PANGO_WEIGHT_NORMAL
|
||||
#define DIYA_CAIRO_FONT_WEIGHT_BOLD PANGO_WEIGHT_BOLD
|
||||
|
||||
#define DIYA_CAIRO_TEXT_WRAP_WORD PANGO_WRAP_WORD
|
||||
#define DIYA_CAIRO_TEXT_WRAP_CHAR PANGO_WRAP_CHAR
|
||||
#define DIYA_CAIRO_TEXT_WRAP_WORD_CHAR PANGO_WRAP_WORD_CHAR
|
||||
|
||||
#define DIYA_TYPE_CAIRO_TEXT (diya_cairo_text_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (DiyaCairoText, diya_cairo_text, DIYA, CAIRO_TEXT, DiyaCairoWidget)
|
||||
|
||||
|
||||
struct _DiyaCairoTextClass
|
||||
{
|
||||
DiyaCairoWidgetClass parent_class;
|
||||
void (*set_text)(gpointer object, const gchar* text);
|
||||
const gchar* (*get_text)(gpointer object);
|
||||
};
|
||||
|
||||
void diya_cairo_text_set_text(gpointer object, const gchar* text);
|
||||
const gchar* diya_cairo_text_get_text(gpointer object);
|
||||
#endif
|
@ -51,6 +51,7 @@ enum
|
||||
CW_MARGIN,
|
||||
CW_FILL,
|
||||
CW_STROKE,
|
||||
CW_CORNER_RADIUS,
|
||||
CW_N_PROPERTIES
|
||||
};
|
||||
static GParamSpec *g_cw_prop[CW_N_PROPERTIES] = {0};
|
||||
@ -70,6 +71,8 @@ typedef struct _DiyaCairoWidgetPrivate
|
||||
guint16 hspace;
|
||||
guint16 vspace;
|
||||
|
||||
gdouble corner_radius;
|
||||
|
||||
diya_offset_t margin;
|
||||
diya_offset_t padding;
|
||||
|
||||
@ -166,6 +169,9 @@ static void diya_cairo_widget_set_property(GObject *object, guint property_id, c
|
||||
assert(ptr);
|
||||
priv->stroke = *(diya_stroke_t*) ptr;
|
||||
break;
|
||||
case CW_CORNER_RADIUS:
|
||||
priv->corner_radius = g_value_get_double(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@ -214,6 +220,9 @@ static void diya_cairo_widget_get_property(GObject *object, guint property_id, G
|
||||
case CW_STROKE:
|
||||
g_value_set_pointer(value, &priv->stroke);
|
||||
break;
|
||||
case CW_CORNER_RADIUS:
|
||||
g_value_set_double(value, priv->corner_radius);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@ -241,6 +250,7 @@ static void diya_cairo_widget_init(DiyaCairoWidget *self)
|
||||
memset(&priv->fill, 0, sizeof(priv->fill));
|
||||
|
||||
priv->damaged = TRUE;
|
||||
priv->corner_radius = 0;
|
||||
}
|
||||
|
||||
static const gchar *diya_cairo_widget_to_string(DiyaObject *object)
|
||||
@ -277,6 +287,12 @@ diya_rect_t diya_cairo_widget_get_view_port(gpointer object)
|
||||
if(priv->parent_widget)
|
||||
{
|
||||
diya_rect_t parent_view = diya_cairo_widget_get_view_port(priv->parent_widget);
|
||||
diya_offset_t* padding;
|
||||
g_object_get(priv->parent_widget,"padding", &padding, NULL);
|
||||
parent_view.x += padding->left;
|
||||
parent_view.y += padding->top;
|
||||
parent_view.width -= (padding->left + padding->right);
|
||||
parent_view.height -= (padding->top + padding->bottom);
|
||||
if(!diya_rect_overlap(&view, &parent_view))
|
||||
{
|
||||
view.x = view.y = view.width = view.height = 0;
|
||||
@ -298,8 +314,6 @@ diya_rect_t diya_cairo_widget_get_view_port(gpointer object)
|
||||
|
||||
static gboolean diya_cairo_widget_draw(gpointer object, cairo_t* context)
|
||||
{
|
||||
(void) context;
|
||||
|
||||
DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object);
|
||||
DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self);
|
||||
if(!priv->damaged)
|
||||
@ -325,11 +339,25 @@ static gboolean diya_cairo_widget_draw(gpointer object, cairo_t* context)
|
||||
//cairo_move_to(context, (double)gpos.x +, (double)gpos.y);
|
||||
guint stroke_size = ceil(priv->stroke.size);
|
||||
guint half_stroke_size = ceil(priv->stroke.size / 2.0);
|
||||
cairo_rectangle(context,
|
||||
gpos.x + priv->margin.left + half_stroke_size,
|
||||
gpos.y + priv->margin.top + half_stroke_size,
|
||||
priv->extent.width - priv->margin.left - priv->margin.right - stroke_size,
|
||||
priv->extent.height - priv->margin.bottom - priv->margin.top - stroke_size);
|
||||
|
||||
double width = (double)(priv->extent.width - priv->margin.left - priv->margin.right - stroke_size);
|
||||
int height = (double)(priv->extent.height - priv->margin.bottom - priv->margin.top - stroke_size);
|
||||
int x = (double)(gpos.x + priv->margin.left + half_stroke_size);
|
||||
int y = (double)(gpos.y + priv->margin.top + half_stroke_size);
|
||||
if(priv->corner_radius > 0)
|
||||
{
|
||||
double degrees = M_PI / 180.0;
|
||||
cairo_new_sub_path(context);
|
||||
cairo_arc (context, x + width - priv->corner_radius, y + priv->corner_radius, priv->corner_radius, -90 * degrees, 0);
|
||||
cairo_arc (context, x + width - priv->corner_radius, y + height - priv->corner_radius, priv->corner_radius, 0, 90 * degrees);
|
||||
cairo_arc (context, x + priv->corner_radius, y + height - priv->corner_radius, priv->corner_radius, 90 * degrees, 180 * degrees);
|
||||
cairo_arc (context, x + priv->corner_radius, y + priv->corner_radius, priv->corner_radius, 180 * degrees, 270 * degrees);
|
||||
cairo_close_path (context);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_rectangle(context,x,y,width,height);
|
||||
}
|
||||
if(priv->fill.a > 0)
|
||||
{
|
||||
cairo_set_source_rgba(context, priv->fill.r, priv->fill.g, priv->fill.b, priv->fill.a);
|
||||
@ -361,7 +389,7 @@ static void diya_cairo_widget_update(gpointer object)
|
||||
assert(DIYA_IS_CAIRO_WIDGET(object));
|
||||
DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object);
|
||||
DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self);
|
||||
|
||||
gint stroke_size = ceil(priv->stroke.size) *2;
|
||||
if(priv->visibility == DIYA_CAIRO_WIDGET_VISIBLE_HIDDEN)
|
||||
{
|
||||
/**
|
||||
@ -394,11 +422,10 @@ static void diya_cairo_widget_update(gpointer object)
|
||||
width = space.width;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_CONTENT:
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
width = cwidth;
|
||||
break;
|
||||
default:
|
||||
width = priv->default_extent.width + priv->margin.left + priv->margin.right;
|
||||
width = priv->default_extent.width + priv->margin.left + priv->margin.right + stroke_size;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -408,11 +435,10 @@ static void diya_cairo_widget_update(gpointer object)
|
||||
height = space.height;
|
||||
break;
|
||||
case DIYA_CAIRO_WIDGET_FILL_CONTENT:
|
||||
case DIYA_CAIRO_WIDGET_FILL_NONE:
|
||||
height = cheight;
|
||||
break;
|
||||
default:
|
||||
height = priv->default_extent.height + priv->margin.top + priv->margin.bottom;
|
||||
height = priv->default_extent.height + priv->margin.top + priv->margin.bottom + stroke_size;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -576,6 +602,12 @@ static void diya_cairo_widget_class_init(DiyaCairoWidgetClass *class)
|
||||
INT_MAX,
|
||||
0,
|
||||
G_PARAM_WRITABLE);
|
||||
g_cw_prop[CW_CORNER_RADIUS] = g_param_spec_double(
|
||||
"corner-radius", NULL, "Corner radius",
|
||||
0,
|
||||
DBL_MAX,
|
||||
0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
base_class->to_string = diya_cairo_widget_to_string;
|
||||
|
||||
@ -717,7 +749,7 @@ static void diya_cairo_container_dispose(GObject* object)
|
||||
DiyaCairoContainerPrivate* priv = diya_cairo_container_get_instance_private(self);
|
||||
g_debug("diya_cairo_container_dispose: %s", diya_object_to_string(object));
|
||||
g_list_free_full(priv->children, g_object_unref);
|
||||
G_OBJECT_CLASS(diya_cairo_widget_parent_class)->dispose(object);
|
||||
G_OBJECT_CLASS(diya_cairo_container_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void diya_cairo_container_init(DiyaCairoContainer *self)
|
||||
|
@ -102,7 +102,6 @@ struct _DiyaCairoWidgetClass
|
||||
diya_rect_t (*default_extent)(gpointer);
|
||||
diya_rect_t (*view_port)(gpointer);
|
||||
gboolean (*damaged)(gpointer);
|
||||
|
||||
const gchar* name;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user