• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

作図ソフト dia の改良版


Commit MetaInfo

Revisión2946acb4b603dfe5abe2b2dce056f439d3c0752a (tree)
Tiempo2014-06-08 17:58:11
AutorHans Breuer <hans@breu...>
CommiterHans Breuer

Log Message

Misc - Ngon: add density parameter for mote star variants

The n-gon density value depends on num_rays. Only a limited set of values
can be supported, where min/max/step is not enough to reflect it.
So this object is the first user of PropEventHandler to keep density in
valid range (or better it's edit control).

Cambiar Resumen

Diferencia incremental

--- a/lib/propdialogs.c
+++ b/lib/propdialogs.c
@@ -200,8 +200,23 @@ property_signal_handler(GObject *obj,
200200 for (j = 0; j < dialog->prop_widgets->len; j++) {
201201 PropWidgetAssoc *pwa =
202202 &g_array_index(dialog->prop_widgets,PropWidgetAssoc,j);
203+ /* The event handler above might have changed every property
204+ * so we would have to mark them all as set (aka. to be applied).
205+ * But doing so would not work well with multiple/grouped objects
206+ * with unchanged and unequal object properties. Idea: keep as
207+ * set, what was before calling reset (but it's too late after get_props).
208+ *
209+ * See also commonprop_reset_widget() for more information
210+ */
211+ gboolean was_set = (pwa->prop->experience & PXP_NOTSET == 0);
203212 pwa->prop->ops->reset_widget(pwa->prop,pwa->widget);
213+ if (was_set)
214+ pwa->prop->experience &= ~PXP_NOTSET;
204215 }
216+ /* once more at least for _this_ property otherwise a property with
217+ * signal handler attached would not be changed at all ...
218+ */
219+ prop->experience &= ~PXP_NOTSET;
205220 } else {
206221 g_assert_not_reached();
207222 }
--- a/objects/Misc/n_gon.c
+++ b/objects/Misc/n_gon.c
@@ -24,6 +24,7 @@
2424 #include "diarenderer.h"
2525 #include "attributes.h"
2626 #include "properties.h"
27+#include "prop_inttypes.h" /* PropEventHandler needs internals */
2728 #include "boundingbox.h"
2829 #include "element.h"
2930 #include "pattern.h"
@@ -55,6 +56,9 @@ struct _Ngon {
5556
5657 int num_rays;
5758 NgonKind kind;
59+ int density;
60+ int last_density; /*!< last value to decide direction */
61+
5862 LineStyle line_style;
5963 LineJoin line_join;
6064 real dashlength;
@@ -102,6 +106,10 @@ static PropEnumData _ngon_type_data[] = {
102106 { NULL, }
103107 };
104108 static PropNumData _num_rays_range_data = { 3, 360, 1 };
109+static PropNumData _density_range_data = { 2, 180, 1 };
110+
111+/* PropEventHandler to keep the density property valid */
112+static gboolean _ngon_density_constraints_handler (DiaObject *obj, Property *prop);
105113
106114 static PropDescription _ngon_props[] = {
107115 ELEMENT_COMMON_PROPERTIES,
@@ -109,6 +117,9 @@ static PropDescription _ngon_props[] = {
109117 N_("N-gon kind"), NULL, &_ngon_type_data },
110118 { "num_rays", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
111119 N_("Number of rays"), NULL, &_num_rays_range_data },
120+ { "density", PROP_TYPE_INT, PROP_FLAG_VISIBLE|PROP_FLAG_OPTIONAL,
121+ N_("Density"), N_("Winding number for Crossing"), &_density_range_data,
122+ &_ngon_density_constraints_handler },
112123 { "center", PROP_TYPE_POINT, PROP_FLAG_NO_DEFAULTS, /* no property widget, but still to be serialized */
113124 N_("Center position"), NULL, NULL },
114125 { "ray_len", PROP_TYPE_REAL, PROP_FLAG_NO_DEFAULTS, /* no property widget, but still to be serialized */
@@ -136,6 +147,7 @@ static PropOffset _ngon_offsets[] = {
136147 ELEMENT_COMMON_PROPERTIES_OFFSETS,
137148 { "ngon_kind", PROP_TYPE_ENUM, offsetof(Ngon, kind) },
138149 { "num_rays", PROP_TYPE_INT, offsetof(Ngon, num_rays) },
150+ { "density", PROP_TYPE_INT, offsetof(Ngon, density) },
139151 { "center", PROP_TYPE_POINT, offsetof(Ngon, center) },
140152 { "ray_len", PROP_TYPE_REAL, offsetof(Ngon, ray_len) },
141153 { PROP_STDNAME_LINE_WIDTH, PROP_STDTYPE_LINE_WIDTH, offsetof(Ngon, line_width) },
@@ -150,12 +162,13 @@ static PropOffset _ngon_offsets[] = {
150162 };
151163 static void
152164 _ngon_get_props(Ngon *ng, GPtrArray *props)
153-{
165+{
154166 object_get_props_from_offsets(&ng->element.object, _ngon_offsets, props);
155167 }
156168 static void
157169 _ngon_set_props(Ngon *ng, GPtrArray *props)
158170 {
171+ ng->last_density = ng->density;
159172 object_set_props_from_offsets(&ng->element.object, _ngon_offsets, props);
160173 _ngon_update_data(ng);
161174 }
@@ -254,10 +267,46 @@ _gcd (int a, int b)
254267 static int
255268 _calc_step (int a, int b)
256269 {
270+ if (b > a / 2)
271+ b = a / 2;
257272 while (_gcd (a, b) != 1)
258273 --b;
259274 return b;
260275 }
276+static int
277+_calc_step_up (int a, int b)
278+{
279+ while (_gcd (a, b) != 1)
280+ ++b;
281+ return b;
282+}
283+
284+/*!
285+ * \brief Event handler called for property change by user
286+ *
287+ * The n-gon density value depends on num_rays. Only a limited set of values
288+ * can be supported, where min/max/step is not enough to reflect it.
289+ *
290+ * This function gets called between Ngon::set_props() and
291+ * Ngon::get_props(). It does need to do anything cause Ngon::update_data()
292+ * already ensured data consistency. The pure existance of this of this
293+ * property handler leads to bidirectional communication between property
294+ * dialog and object's property change.
295+ */
296+static gboolean
297+_ngon_density_constraints_handler (DiaObject *obj, Property *prop)
298+{
299+ Ngon *ng = (Ngon *)obj;
300+ IntProperty *p = (IntProperty *)prop;
301+ int maxDensity = _calc_step (ng->num_rays, ng->num_rays / 2);
302+
303+ g_return_val_if_fail (strcmp(prop->descr->type, PROP_TYPE_INT) == 0, FALSE);
304+
305+ if (p->int_data > maxDensity) {
306+ ng->density = maxDensity;
307+ }
308+ return TRUE;
309+}
261310
262311 static void
263312 _ngon_make_name (Ngon *ng)
@@ -309,8 +358,7 @@ _ngon_make_name (Ngon *ng)
309358 if (ng->kind == NGON_CONVEX)
310359 ng->name = g_strdup_printf ("%s {%d}", name, ng->num_rays);
311360 else
312- ng->name = g_strdup_printf ("%s {%d/%d}", name, ng->num_rays,
313- _calc_step (ng->num_rays, ng->num_rays / 2));
361+ ng->name = g_strdup_printf ("%s {%d/%d}", name, ng->num_rays, ng->density);
314362 }
315363
316364 /*!
@@ -324,7 +372,7 @@ _ngon_make_name (Ngon *ng)
324372 static void
325373 _ngon_adjust_for_crossing (Ngon *ng)
326374 {
327- int n = ng->points->len, i, step = _calc_step (ng->points->len, ng->points->len / 2);
375+ int n = ng->points->len, i, step = _calc_step (ng->num_rays, ng->density);
328376 GArray *points = g_array_new (FALSE /* zero_terminated */,
329377 FALSE /* clear_ */, sizeof(Point));
330378
@@ -356,6 +404,12 @@ _ngon_update_data (Ngon *ng)
356404 else
357405 n = ng->num_rays * 2;
358406
407+ /* ensure density stays in range */
408+ if (ng->last_density > ng->density)
409+ ng->density = _calc_step (ng->num_rays, ng->density);
410+ else
411+ ng->density = _calc_step_up (ng->num_rays, ng->density);
412+
359413 _ngon_make_name (ng);
360414 if (1 || n != ng->points->len) {
361415 /* recalculate all points */
@@ -454,7 +508,7 @@ static ObjectOps _ngon_ops = {
454508 DiaObjectType _ngon_type =
455509 {
456510 "Misc - Ngon", /* name */
457- 0, /* version */
511+ 1, /* version */
458512 n_gon_xpm, /* pixmap */
459513 &_ngon_type_ops, /* ops */
460514 NULL, /* pixmap_file */
@@ -498,6 +552,7 @@ _ngon_create (Point *startpoint,
498552 FALSE /* clear_ */, sizeof(Point));
499553 ng->kind = NGON_CONVEX;
500554 ng->num_rays = 5;
555+ ng->last_density = ng->density = _calc_step (ng->num_rays, ng->num_rays / 2);
501556 ng->ray_len = 1.0; /* for intial object size */
502557 ng->center = *startpoint;
503558
@@ -520,7 +575,14 @@ _ngon_load (ObjectNode obj_node, int version, DiaContext *ctx)
520575 Ngon *ng;
521576
522577 obj = object_load_using_properties (&_ngon_type, obj_node, version, ctx);
523- /* XXX: do some sanity check? */
578+ ng = (Ngon *)obj;
579+ if (version == 0) { /* default to maximum */
580+ ng->last_density = ng->density = _calc_step (ng->num_rays, ng->num_rays/2);
581+ _ngon_update_data(ng);
582+ }
583+ /* the density value is optional, so calculate if not valid */
584+ if (_calc_step (ng->num_rays, ng->density) != ng->density)
585+ ng->density = _calc_step (ng->num_rays, ng->num_rays/2);
524586 return obj;
525587 }
526588