• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

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

作図ソフト dia の改良版


Commit MetaInfo

修訂2946acb4b603dfe5abe2b2dce056f439d3c0752a (tree)
時間2014-06-08 17:58:11
作者Hans 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).

Change Summary

差異

--- 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