From 77d2e9d82dc6d8dea26fe13eacaeb63554b97094 Mon Sep 17 00:00:00 2001 From: bernie Date: Fri, 4 Nov 2005 18:26:38 +0000 Subject: [PATCH] Import into DevLib. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@441 38d2e660-2303-0410-9eaa-f027e97ec537 --- dt/dnotifier.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++ dt/dnotifier.h | 145 ++++++++++++++++++++++++++++++++++++++++++++ dt/dtag.h | 85 ++++++++++++++++++++++++++ dt/dwidget.c | 49 +++++++++++++++ dt/dwidget.h | 57 ++++++++++++++++++ dt/editbool.c | 92 ++++++++++++++++++++++++++++ dt/editbool.h | 48 +++++++++++++++ dt/editint.c | 131 ++++++++++++++++++++++++++++++++++++++++ dt/editint.h | 66 ++++++++++++++++++++ 9 files changed, 833 insertions(+) create mode 100755 dt/dnotifier.c create mode 100755 dt/dnotifier.h create mode 100755 dt/dtag.h create mode 100755 dt/dwidget.c create mode 100755 dt/dwidget.h create mode 100755 dt/editbool.c create mode 100755 dt/editbool.h create mode 100755 dt/editint.c create mode 100755 dt/editint.h diff --git a/dt/dnotifier.c b/dt/dnotifier.c new file mode 100755 index 00000000..d415c8db --- /dev/null +++ b/dt/dnotifier.c @@ -0,0 +1,160 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Notifier obj (implementation). + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.5 2005/06/09 13:49:22 batt + *#* Reformat; correct some comments. + *#* + *#* Revision 1.4 2005/06/09 13:23:58 batt + *#* Add some comments. + *#* + *#* Revision 1.3 2005/06/08 17:32:33 batt + *#* Switch to new messaging system. + *#* + *#* Revision 1.2 2005/06/06 11:04:12 batt + *#* Add some comments. + *#* + *#* Revision 1.1 2005/05/26 08:32:53 batt + *#* Add new Develer widget system :) + *#* + *#*/ + +#include + +#include
+#include
+#include + +/*! + * Default update used to notify target: notify all trasparently all + * targets in the list. + */ +static void notifier_update(DNotifier *n, dtag_t tag, dval_t val) +{ + dnotify_targets(n, tag, val); +} + +/*! + * Init. + */ +void notifier_init(DNotifier *n) +{ + // Init instance + n->update = notifier_update; + LIST_INIT(&n->targets); +} + +/*! + * Search in the map a tag and a val corresponding to the ones supplied. + * If a match is found change them to the corresponding ones in the map. + * If map is NULL the filter is trasparent and all messages sent to filter + * will be forwarded to its target. + */ +void filter_update(DFilter *f, dtag_t tag, dval_t val) +{ + + const DFilterMap *map = f->map; + + if (map) + { + while (map->src.tag != TAG_END) + { + if ((map->src.tag == tag) && (map->src.val == val)) + { + tag = map->dst.tag; + val = map->dst.val; + break; + } + /* TAG_ANY matches anything */ + if (map->src.tag == TAG_ANY) + break; + map++; + } + + if (map->src.tag != TAG_END) + dnotify(f->target, tag, val); + } + else + dnotify(f->target, tag, val); +} + + +/*! + * Search in the table a tag corresponding to the one supplied and a val + * that has at least the mask map supplied bits to one. + * If a match is found change them to the corresponding ones in the map. + * If map is NULL the filter is trasparent and all messages sent to filter + * will be forwarded to its target. + */ +void filter_mask_update(DFilter *f, dtag_t tag, dval_t val) +{ + + const DFilterMap *map = f->map; + dfilter_mask_t mask; + + if (map) + { + while (map->src.tag != TAG_END) + { + mask = (dfilter_mask_t) map->src.val; + if ((map->src.tag == tag) && ((mask & (dfilter_mask_t)val) == mask)) + { + tag = map->dst.tag; + val = map->dst.val; + break; + } + /* TAG_ANY matches anything */ + if (map->src.tag == TAG_ANY) + break; + map++; + } + + + if (map->src.tag != TAG_END) + dnotify(f->target, tag, val); + } + else + dnotify(f->target, tag, val); +} + + +#define FILTER_MAGIC_ACTIVE 0xAA +/*! + * Init filter. + * If \a masked is true, all the fields value in \a map must be interpreted as a mask of bits. + */ +void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target) +{ + // Init instance + if (masked) + f->update = (update_filter_ptr)filter_mask_update; + else + f->update = (update_filter_ptr)filter_update; + + /* set filter map and target */ + f->map = map; + f->target = target; + + /* these ensure that the filter is not inserted in more than one list */ + ASSERT(f->magic != FILTER_MAGIC_ACTIVE); + DB(f->magic = FILTER_MAGIC_ACTIVE;) + + /* Add the filter to source filter list */ + ADDTAIL(&source->targets, &f->link); +} diff --git a/dt/dnotifier.h b/dt/dnotifier.h new file mode 100755 index 00000000..0724b82b --- /dev/null +++ b/dt/dnotifier.h @@ -0,0 +1,145 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Notifier obj (interface). + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.4 2005/06/09 13:23:58 batt + *#* Add some comments. + *#* + *#* Revision 1.3 2005/06/08 17:32:33 batt + *#* Switch to new messaging system. + *#* + *#* Revision 1.2 2005/06/06 11:04:12 batt + *#* Add some comments. + *#* + *#* Revision 1.1 2005/05/26 08:32:53 batt + *#* Add new Develer widget system :) + *#* + *#*/ +#ifndef DT_DNOTIFIER_H +#define DT_DNOTIFIER_H + +#include +#include
+#include + +//Fwd declaretion. +struct DNotifier; +struct DFilter; + +typedef void (* update_func_ptr)(struct DNotifier *, dtag_t, dval_t); +typedef void (* update_filter_ptr)(struct DFilter *, dtag_t, dval_t); + +/*! + * Base object for receive and forward messages. + * It contains an update function used to update itslef and a list to + * notify other DNotifer eventually connected. + */ +typedef struct DNotifier +{ + //! Receive new attributes from other notifiers. + update_func_ptr update; + + //! List of target notifiers to set new attributes to. + List targets; +} DNotifier; + +/*! + * Map for messages. + * Used to translate src message to dst message. + */ +typedef struct DFilterMap +{ + DTagItem src; + DTagItem dst; +} DFilterMap; + + +/*! + * A filter is an interface between two notifier. + * It can translate messages between them through a map (if it is not null). + */ +typedef struct DFilter +{ + //! Allow creating a list of dfilter objects. + Node link; + + //! Target of the filter + DNotifier *target; + + //! Update function called by the source dnotifier + update_filter_ptr update; + + //!Map for translating messages for target + const DFilterMap *map; + + //!Used in debug to prevent inserting this filter in more than one list + DB(uint8_t magic;) +} DFilter; + +//! Type for filter-mask checking +typedef uint16_t dfilter_mask_t; + +//! Filter init +void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target); + +//! Filter update function without masking capabilities. +void filter_update(DFilter *f, dtag_t tag, dval_t val); + +//! Filter update function with masking capabilities. +void filter_mask_update(DFilter *f, dtag_t tag, dval_t val); + +//! Notifier init +void notifier_init(DNotifier *n); + + +/*! + * Macro to notify the target object. + */ +INLINE void dnotify(DNotifier *target, dtag_t tag, dval_t val) +{ + if (target) + target->update(target, tag, val); +} + +/*! + * Macro to notify all the targets of \a target object. + */ +INLINE void dnotify_targets(DNotifier *target, dtag_t tag, dval_t val) +{ + DFilter *f; + if (!ISLISTEMPTY(&target->targets)) + FOREACHNODE(f, &target->targets) + f->update(f, tag, val); +} + + +/*! + * Macro that connect \a src notifier to \a tgt using \a map and passing \a opt for filtering option. + * It declares a static filter to achieve connection and messages translation. + * \note Due its static filter declaration, DCONNECT MUST NOT be used inside loops or in functions called multiple times. + * Failing to do so will lead to unpredictable connections between notifiers. + */ +#define DCONNECT(src, tgt, map, opt) \ + do { \ + static DFilter _filter_; /* Declare a filter */ \ + filter_init(&(_filter_), map, opt, src, tgt); /* Init it. */ \ + } while (0) + + +#endif /* DT_DNOTIFIER_H */ diff --git a/dt/dtag.h b/dt/dtag.h new file mode 100755 index 00000000..01e34f80 --- /dev/null +++ b/dt/dtag.h @@ -0,0 +1,85 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Tags interface. + * This module contains the base message definitions and the list of all available tags. + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.8 2005/06/07 15:22:29 batt + *#* Add const_dval_t. + *#* + *#* Revision 1.7 2005/06/06 17:42:23 batt + *#* Add error tag TAG_ERROR. + *#* + *#* Revision 1.6 2005/06/06 12:45:33 batt + *#* Add TAG_NONE tag. + *#* + *#* Revision 1.5 2005/06/06 11:04:12 batt + *#* Add some comments. + *#* + *#* Revision 1.4 2005/05/31 11:09:52 batt + *#* Add some tags. + *#* + *#* Revision 1.3 2005/05/26 14:55:12 batt + *#* Add form_processTime; change form_kbdProcess to form_processKey. + *#* + *#* Revision 1.2 2005/05/26 14:43:33 batt + *#* Add new message filter interface. + *#* + *#* Revision 1.1 2005/05/26 08:32:53 batt + *#* Add new Develer widget system :) + *#* + *#*/ + +#ifndef DT_DTAG_H +#define DT_DTAG_H + +#include + +/*! Type for values associated with tags. */ +typedef iptr_t dval_t; + +/*! Type for constant values associated with tags. */ +typedef const_iptr_t const_dval_t; + +/*! Type for tag */ +typedef enum dtag_t +{ + TAG_END = 0, + TAG_NONE, + TAG_ANY, + TAG_SETVALUE, + TAG_UP, + TAG_DOWN, + TAG_START, + TAG_STOP, + TAG_TOGGLE, + TAG_KEY, + TAG_TIME, + TAG_ERROR, +} dtag_t; + +/*! This is the basic message structure used by all dnotifiers. */ +typedef struct DTagItem +{ + dtag_t tag; + dval_t val; +} DTagItem; + +/*! Marker to indicate the end of a map for message filtering/translating */ +#define TAG_END_MARKER {{TAG_END, 0}, {TAG_END, 0}} +#endif diff --git a/dt/dwidget.c b/dt/dwidget.c new file mode 100755 index 00000000..970c1d64 --- /dev/null +++ b/dt/dwidget.c @@ -0,0 +1,49 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Widget (implementation). + * A widget is typically a graphic object on a device. + * Its proproperties are the position, the size and a context on which the widget is drawn. + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.3 2005/06/06 11:04:12 batt + *#* Add some comments. + *#* + *#* Revision 1.2 2005/05/26 14:44:10 batt + *#* Abstract widget from layer: use context. + *#* + *#* Revision 1.1 2005/05/26 08:32:53 batt + *#* Add new Develer widget system :) + *#* + *#*/ + +#include
+#include
+ +/*! + * Init the widget of \a pos and \a size on the drawing \a context. + */ +void widget_init(DWidget *w, dpos_t pos, dpos_t size, dcontext_t *context) +{ + // Init superclass + notifier_init(&w->notifier); + + // Init instance + w->pos = pos; + w->size = size; + w->context = context; +} diff --git a/dt/dwidget.h b/dt/dwidget.h new file mode 100755 index 00000000..a6726378 --- /dev/null +++ b/dt/dwidget.h @@ -0,0 +1,57 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Widget (interface). + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.3 2005/06/06 11:04:12 batt + *#* Add some comments. + *#* + *#* Revision 1.2 2005/05/26 14:44:10 batt + *#* Abstract widget from layer: use context. + *#* + *#* Revision 1.1 2005/05/26 08:32:53 batt + *#* Add new Develer widget system :) + *#* + *#*/ + +#ifndef DT_DWIDGET_H +#define DT_DWIDGET_H + +#include
+#include + +/*! Widget position. */ +typedef uint8_t dpos_t; + +/*! Widget drawing context. */ +typedef iptr_t dcontext_t; + +/*! Widget definition. */ +typedef struct DWidget +{ + DNotifier notifier; + + dpos_t pos; + dpos_t size; + dcontext_t *context; +} DWidget; + + +void widget_init(DWidget *w, dpos_t pos, dpos_t size, dcontext_t *context); + +#endif diff --git a/dt/editbool.c b/dt/editbool.c new file mode 100755 index 00000000..94a2d89c --- /dev/null +++ b/dt/editbool.c @@ -0,0 +1,92 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Edit bool widget (implementation). + * This widget handles boolean editing. + * The boolean value will be displayed using two strings: + * one when the bool is false and one when it's true. + * + * \version $Id$ + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.3 2005/06/08 17:32:33 batt + *#* Switch to new messaging system. + *#* + *#* Revision 1.2 2005/06/06 11:04:12 batt + *#* Add some comments. + *#* + *#* Revision 1.1 2005/05/31 11:11:37 batt + *#* Edit bool: first release. + *#* + *#*/ + +#include +#include
+ +#include + +/*! + * Init widget. + */ +void editbool_init(DEditBool *e, dpos_t pos, dpos_t size, dcontext_t *context, bool *value, const char *true_string, const char *false_string) +{ + // Initialize superclass + widget_init(&e->widget, pos, size, context); + + // Override superclass methods + e->widget.notifier.update = (update_func_ptr)editbool_update; + + // Init instance + e->value = value; + e->true_string = true_string; + e->false_string = false_string; + e->draw = editbool_draw; +} + +/*! + * Handle the messages (edit the bool). + */ +void editbool_update(DEditBool *e, dtag_t tag, dval_t _val) +{ + bool changed = false; + + switch (tag) + { + case TAG_SETVALUE: + *e->value = (bool)_val; + changed = true; + break; + + case TAG_TOGGLE: + *e->value = !*e->value; + changed = true; + break; + default: + break; + } + + if (changed) + { + e->draw(e); + dnotify_targets(&e->widget.notifier, TAG_SETVALUE, (dval_t)*e->value); + } +} + +/*! + * Draw the string on the context. + */ +void editbool_draw(DEditBool *e) +{ + lcd_printf((Layer *)e->widget.context, (lcdpos_t)e->widget.pos, LCD_NORMAL, "%*s", (int)e->widget.size , *e->value? e->true_string: e->false_string); +} diff --git a/dt/editbool.h b/dt/editbool.h new file mode 100755 index 00000000..3f723a32 --- /dev/null +++ b/dt/editbool.h @@ -0,0 +1,48 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Edit bool widget (interface). + * + * \version $Id$ + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.2 2005/06/06 11:04:12 batt + *#* Add some comments. + *#* + *#* Revision 1.1 2005/05/31 11:11:37 batt + *#* Edit bool: first release. + *#* + *#*/ + +#ifndef DT_EDITBOOL_H +#define DT_EDITBOOL_H + +#include
+#include
+ +typedef struct DEditBool +{ + DWidget widget; + bool *value; + const char *true_string; + const char *false_string; + void (*draw)(struct DEditBool *); +} DEditBool; + +void editbool_init(DEditBool *e, dpos_t pos, dpos_t size, dcontext_t *context, bool *val, const char *true_str, const char *false_str); +void editbool_update(DEditBool *e, dtag_t tag, dval_t val); +void editbool_draw(DEditBool *e); + + +#endif diff --git a/dt/editint.c b/dt/editint.c new file mode 100755 index 00000000..2b95d565 --- /dev/null +++ b/dt/editint.c @@ -0,0 +1,131 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Integer edit widget (implementation). + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.7 2005/06/10 15:46:09 batt + *#* Add EDIS_WRAP style that wrap around min and max. + *#* + *#* Revision 1.6 2005/06/08 17:32:33 batt + *#* Switch to new messaging system. + *#* + *#* Revision 1.5 2005/06/06 11:04:12 batt + *#* Add some comments. + *#* + *#* Revision 1.4 2005/05/31 11:09:34 batt + *#* Fix sending pointer instead of value bug. + *#* + *#* Revision 1.3 2005/05/26 14:46:20 batt + *#* Use correct tag; remove warning. + *#* + *#* Revision 1.2 2005/05/26 14:44:10 batt + *#* Abstract widget from layer: use context. + *#* + *#* Revision 1.1 2005/05/26 08:32:53 batt + *#* Add new Develer widget system :) + *#* + *#*/ + +#include +#include
+#include
+#include
+ +#include + +#include + +/*! + * Init. + */ +void editint_init(DEditInt *e, dpos_t pos, dpos_t size, dcontext_t *context, int *value, int min, int max) +{ + // Initialize superclass + widget_init(&e->widget, pos, size, context); + + // Override superclass methods + e->widget.notifier.update = (update_func_ptr)editint_update; + + // Init instance + e->value = value; + e->min = min; + e->max = max; + e->style = EDIS_DEFAULT; + e->draw = editint_draw; +} + +/*! + * Handle the messages (edit the int). + */ +void editint_update(DEditInt *e, dtag_t tag, dval_t _val) +{ + bool changed = false; + int val = (int)_val; + + switch (tag) + { + case TAG_SETVALUE: + *e->value = MINMAX(e->min, val, e->max); + changed = true; + break; + + /* Increments the integer by val */ + case TAG_UP: + if (e->style & EDIS_WRAP) + { + if (*e->value + val > e->max) + *e->value = (*e->value + val - e->min) % (e->max - e->min + 1) + e->min; + else + *e->value += val; + } + else + *e->value = MIN(*e->value + val, e->max); + changed = true; + break; + /* Decrements the integer by val */ + case TAG_DOWN: + if (e->style & EDIS_WRAP) + { + if (*e->value - val < e->min) + *e->value = e->max - (e->max - (*e->value - val)) % (e->max - e->min + 1); + else + *e->value -= val; + } + else + *e->value = MAX(*e->value - val, e->min); + changed = true; + break; + + default: + break; + } + + if (changed) + { + e->draw(e); + dnotify_targets(&e->widget.notifier, TAG_SETVALUE, (dval_t)*e->value); + } +} + +/*! + * Draw the integer on the context. + */ +void editint_draw(DEditInt *e) +{ + lcd_printf((Layer *)e->widget.context, (lcdpos_t)e->widget.pos, LCD_NORMAL,"%*d", (int)e->widget.size, *e->value); +} diff --git a/dt/editint.h b/dt/editint.h new file mode 100755 index 00000000..af3c3964 --- /dev/null +++ b/dt/editint.h @@ -0,0 +1,66 @@ +/*! + * \file + * + * + * \version $Id$ + * + * \brief Integer edit (interface). + * + * \version $Id$ + * \author Bernardo Innocenti + * \author Francesco Sacchi + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2005/11/04 18:26:38 bernie + *#* Import into DevLib. + *#* + *#* Revision 1.3 2005/06/10 15:46:09 batt + *#* Add EDIS_WRAP style that wrap around min and max. + *#* + *#* Revision 1.2 2005/05/26 14:44:10 batt + *#* Abstract widget from layer: use context. + *#* + *#* Revision 1.1 2005/05/26 08:32:53 batt + *#* Add new Develer widget system :) + *#* + *#*/ + +#ifndef DT_EDITINT_H +#define DT_EDITINT_H + +#include
+#include
+#include + +#include +#include + + +#define EDIS_DEFAULT 0 +#define EDIS_CURSORLEFT BV(0) +#define EDIS_WRAP BV(1) + +/*! Type for edit style */ +typedef uint16_t dstyle_t; + +typedef struct DEditInt +{ + DWidget widget; + + int *value; + int min; + int max; + dstyle_t style; + void (*draw)(struct DEditInt *); + +} DEditInt; + +void editint_init(DEditInt *e, dpos_t pos, dpos_t size, dcontext_t *context, int *value, int min, int max); +void editint_update(DEditInt *e, dtag_t tag, dval_t val); +void editint_draw(DEditInt *e); + +#endif -- 2.25.1