summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ganv/Circle.hpp7
-rw-r--r--src/circle.c84
-rw-r--r--src/ganv-private.h3
-rw-r--r--src/ganv_bench.cpp4
-rw-r--r--src/module.c3
-rw-r--r--src/node.c1
6 files changed, 84 insertions, 18 deletions
diff --git a/ganv/Circle.hpp b/ganv/Circle.hpp
index 721b153..1ba9ae6 100644
--- a/ganv/Circle.hpp
+++ b/ganv/Circle.hpp
@@ -49,9 +49,7 @@ public:
Circle(Canvas& canvas,
const std::string& name,
double x,
- double y,
- double radius,
- bool show_title)
+ double y)
: Node(&canvas,
GANV_NODE(
ganv_item_new(
@@ -61,7 +59,6 @@ public:
"y", y,
"can-tail", TRUE,
"can-head", TRUE,
- "radius", radius,
"fill-color", FILL_COLOUR,
"border-color", BORDER_COLOUR,
"label", name.c_str(),
@@ -70,6 +67,8 @@ public:
{}
RW_PROPERTY(double, radius);
+ RW_PROPERTY(double, radius_ems);
+ RW_PROPERTY(gboolean, fit_label);
GanvCircle* gobj() { return GANV_CIRCLE(_gobj); }
const GanvCircle* gobj() const { return GANV_CIRCLE(_gobj); }
diff --git a/src/circle.c b/src/circle.c
index eb43166..a912214 100644
--- a/src/circle.c
+++ b/src/circle.c
@@ -16,6 +16,7 @@
#include <math.h>
#include <string.h>
+#include "ganv/canvas.h"
#include "ganv/canvas-base.h"
#include "ganv/circle.h"
@@ -30,7 +31,9 @@ static GanvNodeClass* parent_class;
enum {
PROP_0,
- PROP_RADIUS
+ PROP_RADIUS,
+ PROP_RADIUS_EMS,
+ PROP_FIT_LABEL
};
static void
@@ -40,9 +43,11 @@ ganv_circle_init(GanvCircle* circle)
circle, GANV_TYPE_CIRCLE, GanvCircleImpl);
memset(&circle->impl->coords, '\0', sizeof(GanvCircleCoords));
- circle->impl->coords.radius = 8.0;
- circle->impl->coords.width = 2.0;
- circle->impl->old_coords = circle->impl->coords;
+ circle->impl->coords.radius = 0.0;
+ circle->impl->coords.radius_ems = 1.0;
+ circle->impl->coords.width = 2.0;
+ circle->impl->old_coords = circle->impl->coords;
+ circle->impl->fit_label = TRUE;
}
static void
@@ -57,6 +62,15 @@ ganv_circle_destroy(GtkObject* object)
}
static void
+set_radius_ems(GanvCircle* circle,
+ double ems)
+{
+ GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(circle)->canvas);
+ const double points = ganv_canvas_get_font_size(canvas);
+ circle->impl->coords.radius = points * ems;
+}
+
+static void
ganv_circle_set_property(GObject* object,
guint prop_id,
const GValue* value,
@@ -69,10 +83,16 @@ ganv_circle_set_property(GObject* object,
switch (prop_id) {
SET_CASE(RADIUS, double, circle->impl->coords.radius);
+ SET_CASE(RADIUS_EMS, double, circle->impl->coords.radius_ems);
+ SET_CASE(FIT_LABEL, boolean, circle->impl->fit_label);
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
+
+ if (prop_id == PROP_RADIUS_EMS) {
+ set_radius_ems(circle, circle->impl->coords.radius_ems);
+ }
}
static void
@@ -88,6 +108,8 @@ ganv_circle_get_property(GObject* object,
switch (prop_id) {
GET_CASE(RADIUS, double, circle->impl->coords.radius);
+ GET_CASE(RADIUS_EMS, double, circle->impl->coords.radius_ems);
+ GET_CASE(FIT_LABEL, boolean, circle->impl->fit_label);
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -97,23 +119,53 @@ ganv_circle_get_property(GObject* object,
static void
ganv_circle_resize(GanvNode* self)
{
- GanvNode* node = GANV_NODE(self);
+ GanvNode* node = GANV_NODE(self);
+ GanvCircle* circle = GANV_CIRCLE(self);
+ GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->canvas);
if (node->impl->label) {
if (node->impl->label->impl->needs_layout) {
ganv_text_layout(node->impl->label);
}
+ const double label_w = node->impl->label->impl->coords.width;
+ const double label_h = node->impl->label->impl->coords.height;
+ if (circle->impl->fit_label) {
+ // Resize to fit text
+ const double radius = MAX(label_w, label_h) / 2.0 + 3.0;
+ if (radius != circle->impl->coords.radius) {
+ ganv_item_set(GANV_ITEM(self),
+ "radius", radius,
+ NULL);
+ }
+ }
+
// Center label
ganv_item_set(GANV_ITEM(node->impl->label),
- "x", node->impl->label->impl->coords.width / -2.0,
- "y", node->impl->label->impl->coords.height / -2.0,
+ "x", label_w / -2.0,
+ "y", label_h / -2.0,
NULL);
}
if (parent_class->resize) {
parent_class->resize(self);
}
+
+ ganv_canvas_for_each_edge_on(
+ canvas, node, (GanvEdgeFunc)ganv_edge_update_location, NULL);
+}
+
+static void
+ganv_circle_redraw_text(GanvNode* self)
+{
+ GanvCircle* circle = GANV_CIRCLE(self);
+ if (circle->impl->coords.radius_ems) {
+ set_radius_ems(circle, circle->impl->coords.radius_ems);
+ }
+
+ if (parent_class->redraw_text) {
+ parent_class->redraw_text(self);
+ }
}
static gboolean
@@ -349,12 +401,30 @@ ganv_circle_class_init(GanvCircleClass* klass)
0.0,
G_PARAM_READWRITE));
+ g_object_class_install_property(
+ gobject_class, PROP_RADIUS_EMS, g_param_spec_double(
+ "radius-ems",
+ _("Radius in ems"),
+ _("The radius of the circle in ems."),
+ 0, G_MAXDOUBLE,
+ 1.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(
+ gobject_class, PROP_FIT_LABEL, g_param_spec_boolean(
+ "fit-label",
+ _("Fit label"),
+ _("If true, expand circle to fit its label"),
+ TRUE,
+ (GParamFlags)G_PARAM_READWRITE));
+
object_class->destroy = ganv_circle_destroy;
node_class->resize = ganv_circle_resize;
node_class->is_within = ganv_circle_is_within;
node_class->tail_vector = ganv_circle_vector;
node_class->head_vector = ganv_circle_vector;
+ node_class->redraw_text = ganv_circle_redraw_text;
item_class->update = ganv_circle_update;
item_class->bounds = ganv_circle_bounds;
diff --git a/src/ganv-private.h b/src/ganv-private.h
index ddf6ab5..7bde036 100644
--- a/src/ganv-private.h
+++ b/src/ganv-private.h
@@ -47,13 +47,14 @@ struct _GanvBoxImpl {
/* Circle */
typedef struct {
- double x, y, radius;
+ double x, y, radius, radius_ems;
double width;
} GanvCircleCoords;
struct _GanvCircleImpl {
GanvCircleCoords coords;
GanvCircleCoords old_coords;
+ gboolean fit_label;
};
/* Edge */
diff --git a/src/ganv_bench.cpp b/src/ganv_bench.cpp
index ee2ebfc..be758f0 100644
--- a/src/ganv_bench.cpp
+++ b/src/ganv_bench.cpp
@@ -70,9 +70,7 @@ make_circle(Canvas* canvas)
snprintf(name, 8, "%d", rand() % 10000);
Circle* e(new Circle(*canvas, name,
rand() % (int)canvas->get_width(),
- rand() % (int)canvas->get_height(),
- 32.0,
- 32.0));
+ rand() % (int)canvas->get_height()));
ins.push_back(e);
outs.push_back(e);
diff --git a/src/module.c b/src/module.c
index 654038a..88dbb58 100644
--- a/src/module.c
+++ b/src/module.c
@@ -728,8 +728,7 @@ ganv_module_get_empty_port_breadth(const GanvModule* module)
double
ganv_module_get_empty_port_depth(const GanvModule* module)
{
- GanvCanvas* canvas = GANV_CANVAS(
- GANV_ITEM(module)->canvas);
+ GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(module)->canvas);
return ganv_canvas_get_font_size(canvas);
}
diff --git a/src/node.c b/src/node.c
index aaf78f8..ff214ba 100644
--- a/src/node.c
+++ b/src/node.c
@@ -365,7 +365,6 @@ ganv_node_default_move(GanvNode* node,
ganv_item_move(GANV_ITEM(node), dx, dy);
ganv_canvas_for_each_edge_on(
canvas, node, (GanvEdgeFunc)ganv_edge_update_location, NULL);
-
}
static void