diff options
author | Keith Packard <keithp@keithp.com> | 2004-10-27 20:09:36 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2004-10-27 20:09:36 +0000 |
commit | 143d1a70aab4e551bccece0fe8845f7be77fb8d9 (patch) | |
tree | 0803b77840d76b90a401a83e24b275917fd09765 | |
parent | 4e67aeb9a6aaf0852ab9b6aba46c21cb483cdf54 (diff) |
Add calculator and missing header files
Change type name from twin_layout_t to twin_box_dir_t Create new
twin_widget_layout_t holding layout preferences. Add copy_geom field to
widget to make widgets look the same Add button signals and signal
proc. Fix box layout to sum stretch along axis and minimize normal
Add calculator demo
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | Makefile.am | 7 | ||||
-rw-r--r-- | twin.h | 72 | ||||
-rw-r--r-- | twin_box.c | 133 | ||||
-rw-r--r-- | twin_button.c | 22 | ||||
-rw-r--r-- | twin_calc.c | 239 | ||||
-rw-r--r-- | twin_calc.h | 35 | ||||
-rw-r--r-- | twin_label.c | 20 | ||||
-rw-r--r-- | twin_toplevel.c | 2 | ||||
-rw-r--r-- | twin_widget.c | 47 | ||||
-rw-r--r-- | twinint.h | 6 | ||||
-rw-r--r-- | xtwin.c | 5 |
12 files changed, 494 insertions, 122 deletions
@@ -1,3 +1,31 @@ +2004-10-27 Keith Packard <keithp@keithp.com> + + * Makefile.am: + Add calculator and missing header files + + * twin.h: + * twin_box.c: (_twin_box_init), (_twin_box_query_geometry), + (_twin_box_configure), (_twin_box_dispatch), (twin_box_create): + * twin_button.c: (_twin_button_dispatch), (_twin_button_init): + * twin_toplevel.c: (_twin_toplevel_init): + * twin_widget.c: (_twin_widget_dispatch), (_twin_widget_init), + * twin_label.c: (_twin_label_query_geometry), + (_twin_label_dispatch), (_twin_label_init): + * twinint.h: + (twin_widget_create): + Change type name from twin_layout_t to twin_box_dir_t + Create new twin_widget_layout_t holding layout preferences. + Add copy_geom field to widget to make widgets look the same + Add button signals and signal proc. + Fix box layout to sum stretch along axis and minimize normal + + * twin_calc.c: (_twin_calc_button_to_id), + (_twin_calc_update_value), (_twin_calc_push), (_twin_calc_pop), + (_twin_calc_digit), (_twin_calc_button_signal), (twin_calc_start): + * twin_calc.h: + * xtwin.c: (main): + Add calculator demo + 2004-10-26 Keith Packard <keithp@keithp.com> * twin_button.c: (_twin_button_paint): diff --git a/Makefile.am b/Makefile.am index 78b41b7..547a2f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,11 +44,18 @@ xtwin_SOURCES = \ twin_window.c \ twin_work.c \ twin_x11.c \ + twin_x11.h \ twinint.h \ twin_clock.c \ + twin_clock.h \ + twin_calc.c \ + twin_calc.h \ twin_text.c \ + twin_text.h \ twin_demo.c \ + twin_demo.h \ twin_hello.c \ + twin_hello.h \ xtwin.c xtwin_LDADD = @X_LIBS@ -lm @@ -372,37 +372,42 @@ typedef struct _twin_box twin_box_t; #define _twin_widget_height(w) (((twin_widget_t *)(w))->extents.bottom - \ ((twin_widget_t *)(w))->extents.top) +typedef enum _twin_box_dir { + TwinBoxHorz, TwinBoxVert +} twin_box_dir_t; + typedef enum _twin_dispatch_result { - TwinDispatchNone, - TwinDispatchPaint, - TwinDispatchConfigure, + TwinDispatchDone, + TwinDispatchContinue } twin_dispatch_result_t; -typedef enum _twin_layout { - TwinLayoutHorz, TwinLayoutVert -} twin_layout_t; - typedef twin_dispatch_result_t (*twin_dispatch_proc_t) (twin_widget_t *widget, twin_event_t *event); +typedef struct _twin_widget_layout { + twin_coord_t width; + twin_coord_t height; + twin_stretch_t stretch_width; + twin_stretch_t stretch_height; +} twin_widget_layout_t; + struct _twin_widget { twin_window_t *window; twin_widget_t *next; twin_box_t *parent; + twin_widget_t *copy_geom; twin_bool_t paint; twin_bool_t layout; twin_bool_t want_focus; twin_argb32_t background; twin_rect_t extents; /* current geometry */ - twin_rect_t preferred; /* desired geometry */ - twin_stretch_t hstretch; /* stretch ratio in horizontal dir */ - twin_stretch_t vstretch; /* stretch ratio in vertical dir */ + twin_widget_layout_t preferred; twin_dispatch_proc_t dispatch; }; struct _twin_box { twin_widget_t widget; - twin_layout_t layout; + twin_box_dir_t dir; twin_widget_t *children; twin_widget_t *button_down; twin_widget_t *focus; @@ -421,15 +426,42 @@ typedef struct _twin_label { twin_point_t offset; } twin_label_t; -typedef void (*twin_callback_t) (twin_widget_t *widget, void *closure); +typedef enum _twin_button_signal { + TwinButtonSignalDown, /* sent when button pressed */ + TwinButtonSignalUp, /* send when button released inside widget */ +} twin_button_signal_t; -typedef struct _twin_button { - twin_label_t label; - twin_bool_t pressed; - twin_bool_t active; - twin_callback_t callback; - void *closure; -} twin_button_t; +typedef struct _twin_button twin_button_t; + +typedef void (*twin_button_signal_proc_t) (twin_button_t *button, + twin_button_signal_t signal, + void *closure); + +struct _twin_button { + twin_label_t label; + twin_bool_t pressed; + twin_bool_t active; + twin_button_signal_proc_t signal; + void *closure; +}; + +typedef enum _twin_scroll_signal { + TwinScrollSignalUpArrow, + TwinScrollSignalDownArrow, + TwinScrollSignalThumb, + TwinScrollSignalAboveThumb, + TwinScrollSignalBelowThumb, +} twin_scroll_signal_t; + +typedef struct _twin_scroll twin_scroll_t; + +typedef void (*twin_scroll_signal_proc_t) (twin_scroll_t *scroll, + twin_scroll_signal_t signal, + void *closure); + +struct _twin_scroll { + twin_widget_t widget; +}; /* * twin_box.c @@ -437,7 +469,7 @@ typedef struct _twin_button { twin_box_t * twin_box_create (twin_box_t *parent, - twin_layout_t layout); + twin_box_dir_t dir); /* * twin_button.c @@ -28,58 +28,74 @@ void _twin_box_init (twin_box_t *box, twin_box_t *parent, twin_window_t *window, - twin_layout_t layout, + twin_box_dir_t dir, twin_dispatch_proc_t dispatch) { - static twin_rect_t preferred = { 0, 0, 0, 0 }; - _twin_widget_init (&box->widget, parent, window, preferred, 0, 0, dispatch); - box->layout = layout; - box->children = 0; + static twin_widget_layout_t preferred = { 0, 0, 0, 0 }; + _twin_widget_init (&box->widget, parent, window, preferred, dispatch); + box->dir = dir; + box->children = NULL; + box->button_down = NULL; + box->focus = NULL; } static twin_dispatch_result_t _twin_box_query_geometry (twin_box_t *box) { - twin_widget_t *widget; - twin_event_t ev; - twin_coord_t w, h; - twin_coord_t c_w, c_h; + twin_widget_t *child; + twin_event_t ev; + twin_widget_layout_t preferred; - w = 0; h = 0; + preferred.width = 0; + preferred.height = 0; + if (box->dir == TwinBoxHorz) + { + preferred.stretch_width = 0; + preferred.stretch_height = 10000; + } + else + { + preferred.stretch_width = 10000; + preferred.stretch_height = 0; + } /* * Find preferred geometry */ - for (widget = box->children; widget; widget = widget->next) + for (child = box->children; child; child = child->next) { - ev.kind = TwinEventQueryGeometry; - (*widget->dispatch) (widget, &ev); - c_w = widget->preferred.right - widget->preferred.left; - c_h = widget->preferred.bottom - widget->preferred.top; - if (box->layout == TwinLayoutHorz) + if (child->layout) + { + ev.kind = TwinEventQueryGeometry; + (*child->dispatch) (child, &ev); + } + if (box->dir == TwinBoxHorz) { - w += c_w; - if (c_h > h) - h = c_h; + preferred.width += child->preferred.width; + preferred.stretch_width += child->preferred.stretch_width; + if (child->preferred.height > preferred.height) + preferred.height = child->preferred.height; + if (child->preferred.stretch_height < preferred.stretch_height) + preferred.stretch_height = child->preferred.stretch_height; } else { - h += c_h; - if (c_w > w) - w = c_w; + preferred.height += child->preferred.height; + preferred.stretch_height += child->preferred.stretch_height; + if (child->preferred.width > preferred.width) + preferred.width = child->preferred.width; + if (child->preferred.stretch_width < preferred.stretch_width) + preferred.stretch_width = child->preferred.stretch_width; } } - box->widget.preferred.left = 0; - box->widget.preferred.top = 0; - box->widget.preferred.right = w; - box->widget.preferred.bottom = h; - return TwinDispatchNone; + box->widget.preferred = preferred; + return TwinDispatchContinue; } static twin_dispatch_result_t _twin_box_configure (twin_box_t *box) { - twin_coord_t w = box->widget.extents.right - box->widget.extents.left; - twin_coord_t h = box->widget.extents.bottom - box->widget.extents.top; + twin_coord_t width = _twin_widget_width (box); + twin_coord_t height = _twin_widget_height (box); twin_coord_t actual; twin_coord_t pref; twin_coord_t delta; @@ -87,21 +103,18 @@ _twin_box_configure (twin_box_t *box) twin_coord_t stretch = 0; twin_coord_t pos = 0; twin_widget_t *child; - twin_dispatch_result_t result = TwinDispatchNone; - if (box->layout == TwinLayoutHorz) + if (box->dir == TwinBoxHorz) { - for (child = box->children; child; child = child->next) - stretch += child->hstretch; - actual = w; - pref = box->widget.preferred.right - box->widget.preferred.left; + stretch = box->widget.preferred.stretch_width; + actual = width; + pref = box->widget.preferred.width; } else { - for (child = box->children; child; child = child->next) - stretch += child->vstretch; - actual = h; - pref = box->widget.preferred.bottom - box->widget.preferred.top; + stretch = box->widget.preferred.stretch_height; + actual = height; + pref = box->widget.preferred.height; } if (!stretch) stretch = 1; delta = delta_remain = actual - pref; @@ -116,10 +129,10 @@ _twin_box_configure (twin_box_t *box) delta_this = delta_remain; else { - if (box->layout == TwinLayoutHorz) - stretch_this = child->hstretch; + if (box->dir == TwinBoxHorz) + stretch_this = child->preferred.stretch_width; else - stretch_this = child->vstretch; + stretch_this = child->preferred.stretch_height; delta_this = delta * stretch_this / stretch; } if (delta_remain < 0) @@ -133,30 +146,33 @@ _twin_box_configure (twin_box_t *box) delta_this = delta_remain; } delta_remain -= delta_this; - if (box->layout == TwinLayoutHorz) + if (box->dir == TwinBoxHorz) { - twin_coord_t child_w = (child->preferred.right - - child->preferred.left); + twin_coord_t child_w = child->preferred.width; extents.top = 0; - extents.bottom = h; + extents.bottom = height; extents.left = pos; pos = extents.right = pos + child_w + delta_this; } else { - twin_coord_t child_h = (child->preferred.bottom - - child->preferred.top); + twin_coord_t child_h = child->preferred.height; extents.left = 0; - extents.right = w; + extents.right = width; extents.top = pos; pos = extents.bottom = pos + child_h + delta_this; } - ev.kind = TwinEventConfigure; - ev.u.configure.extents = extents; - (*child->dispatch) (child, &ev); - result = TwinDispatchPaint; + if (extents.left != ev.u.configure.extents.left || + extents.top != ev.u.configure.extents.top || + extents.right != ev.u.configure.extents.right || + extents.bottom != ev.u.configure.extents.bottom) + { + ev.kind = TwinEventConfigure; + ev.u.configure.extents = extents; + (*child->dispatch) (child, &ev); + } } - return result; + return TwinDispatchContinue; } static twin_widget_t * @@ -180,11 +196,12 @@ _twin_box_dispatch (twin_widget_t *widget, twin_event_t *event) twin_event_t ev; twin_widget_t *child; + if (_twin_widget_dispatch (widget, event) == TwinDispatchDone) + return TwinDispatchDone; switch (event->kind) { case TwinEventQueryGeometry: return _twin_box_query_geometry (box); case TwinEventConfigure: - _twin_widget_dispatch (widget, event); return _twin_box_configure (box); case TwinEventButtonDown: box->button_down = _twin_box_xy_to_widget (box, @@ -227,17 +244,17 @@ _twin_box_dispatch (twin_widget_t *widget, twin_event_t *event) default: break; } - return TwinDispatchNone; + return TwinDispatchContinue; } twin_box_t * twin_box_create (twin_box_t *parent, - twin_layout_t layout) + twin_box_dir_t dir) { twin_box_t *box = malloc (sizeof (twin_box_t)); if (!box) return 0; - _twin_box_init (box, parent, 0, layout, _twin_box_dispatch); + _twin_box_init (box, parent, 0, dir, _twin_box_dispatch); return box; } diff --git a/twin_button.c b/twin_button.c index a308abb..b340f10 100644 --- a/twin_button.c +++ b/twin_button.c @@ -52,16 +52,19 @@ _twin_button_dispatch (twin_widget_t *widget, twin_event_t *event) { twin_button_t *button = (twin_button_t *) widget; - _twin_label_dispatch (widget, event); + if (_twin_label_dispatch (widget, event) == TwinDispatchDone) + return TwinDispatchDone; switch (event->kind) { case TwinEventPaint: _twin_button_paint (button); - return TWIN_TRUE; + break; case TwinEventButtonDown: button->pressed = TWIN_TRUE; button->active = TWIN_TRUE; _twin_button_set_label_offset (button); - return TWIN_TRUE; + if (button->signal) + (*button->signal) (button, TwinButtonSignalDown, button->closure); + break; case TwinEventMotion: if (button->pressed) { @@ -74,21 +77,21 @@ _twin_button_dispatch (twin_widget_t *widget, twin_event_t *event) _twin_button_set_label_offset (button); } } - return TWIN_TRUE; + break; case TwinEventButtonUp: button->pressed = TWIN_FALSE; if (button->active) { - if (button->callback) - (*button->callback) (&button->label.widget, button->closure); button->active = TWIN_FALSE; _twin_button_set_label_offset (button); + if (button->signal) + (*button->signal) (button, TwinButtonSignalUp, button->closure); } - return TWIN_TRUE; + break; default: break; } - return TwinDispatchNone; + return TwinDispatchContinue; } void @@ -103,6 +106,9 @@ _twin_button_init (twin_button_t *button, _twin_label_init (&button->label, parent, value, foreground, font_size, font_style, dispatch); button->pressed = TWIN_FALSE; + button->active = TWIN_FALSE; + button->signal = NULL; + button->closure = NULL; _twin_button_set_label_offset (button); } diff --git a/twin_calc.c b/twin_calc.c new file mode 100644 index 0000000..56af91c --- /dev/null +++ b/twin_calc.c @@ -0,0 +1,239 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "twin_calc.h" +#include <stdio.h> + +#define TWIN_CALC_STACK 5 +#define TWIN_CALC_ZERO 0 +#define TWIN_CALC_ONE 1 +#define TWIN_CALC_TWO 2 +#define TWIN_CALC_THREE 3 +#define TWIN_CALC_FOUR 4 +#define TWIN_CALC_FIVE 5 +#define TWIN_CALC_SIX 6 +#define TWIN_CALC_SEVEN 7 +#define TWIN_CALC_EIGHT 8 +#define TWIN_CALC_NINE 9 +#define TWIN_CALC_PLUS 10 +#define TWIN_CALC_MINUS 11 +#define TWIN_CALC_TIMES 12 +#define TWIN_CALC_DIVIDE 13 +#define TWIN_CALC_EQUAL 14 +#define TWIN_CALC_CLEAR 15 +#define TWIN_CALC_NBUTTON 16 + +/* + * Layout: + * + * display + * + * 7 8 9 + + * 4 5 6 - + * 1 2 3 * + * 0 clr = ÷ + */ +#define TWIN_CALC_COLS 4 +#define TWIN_CALC_ROWS 4 + +const static int calc_layout[TWIN_CALC_ROWS][TWIN_CALC_COLS] = { + { TWIN_CALC_SEVEN, TWIN_CALC_EIGHT, TWIN_CALC_NINE, TWIN_CALC_PLUS }, + { TWIN_CALC_FOUR, TWIN_CALC_FIVE, TWIN_CALC_SIX, TWIN_CALC_MINUS }, + { TWIN_CALC_ONE, TWIN_CALC_TWO, TWIN_CALC_THREE, TWIN_CALC_TIMES }, + { TWIN_CALC_ZERO, TWIN_CALC_CLEAR, TWIN_CALC_EQUAL, TWIN_CALC_DIVIDE }, +}; + +typedef struct _twin_calc { + int stack[TWIN_CALC_STACK]; + int pending_op; + twin_bool_t pending_delete; + twin_window_t *window; + twin_toplevel_t *toplevel; + twin_box_t *keys; + twin_box_t *cols[4]; + twin_label_t *display; + twin_button_t *buttons[TWIN_CALC_NBUTTON]; +} twin_calc_t; + +static const char *twin_calc_labels[] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "+", "-", "*", "/", "=", "CLR" +}; + +#define TWIN_CALC_VALUE_SIZE twin_int_to_fixed(24) +#define TWIN_CALC_VALUE_STYLE TWIN_TEXT_BOLD +#define TWIN_CALC_VALUE_FG 0xff000000 +#define TWIN_CALC_VALUE_BG 0xc0c0c0c0 +#define TWIN_CALC_BUTTON_SIZE twin_int_to_fixed(15) +#define TWIN_CALC_BUTTON_STYLE TWIN_TEXT_BOLD +#define TWIN_CALC_BUTTON_FG 0xff000000 +#define TWIN_CALC_BUTTON_BG 0xc0808080 + +static int +_twin_calc_button_to_id (twin_calc_t *calc, twin_button_t *button) +{ + int i; + + for (i = 0; i < TWIN_CALC_NBUTTON; i++) + if (calc->buttons[i] == button) + return i; + return -1; +} + +static void +_twin_calc_update_value (twin_calc_t *calc) +{ + char v[20]; + + sprintf (v, "%d", calc->stack[0]); + twin_label_set (calc->display, v, TWIN_CALC_VALUE_FG, + TWIN_CALC_VALUE_SIZE, TWIN_CALC_VALUE_STYLE); +} + +static void +_twin_calc_push (twin_calc_t *calc) +{ + int i; + + for (i = 0; i < TWIN_CALC_STACK - 1; i++) + calc->stack[i+1] = calc->stack[i]; + calc->pending_delete = TWIN_TRUE; +} + +static int +_twin_calc_pop (twin_calc_t *calc) +{ + int i; + int v = calc->stack[0]; + for (i = 0; i < TWIN_CALC_STACK - 1; i++) + calc->stack[i] = calc->stack[i+1]; + return v; +} + +static void +_twin_calc_digit (twin_calc_t *calc, int digit) +{ + if (calc->pending_delete) + { + calc->stack[0] = 0; + calc->pending_delete = TWIN_FALSE; + } + calc->stack[0] = calc->stack[0] * 10 + digit; + _twin_calc_update_value (calc); +} + +static void +_twin_calc_button_signal (twin_button_t *button, + twin_button_signal_t signal, + void *closure) +{ + twin_calc_t *calc = closure; + int i; + int a, b; + + if (signal != TwinButtonSignalDown) return; + i = _twin_calc_button_to_id (calc, button); + if (i < 0) return; + switch (i) { + case TWIN_CALC_PLUS: + case TWIN_CALC_MINUS: + case TWIN_CALC_TIMES: + case TWIN_CALC_DIVIDE: + calc->pending_op = i; + _twin_calc_push (calc); + break; + case TWIN_CALC_EQUAL: + if (calc->pending_op != 0) + { + b = _twin_calc_pop (calc); + a = _twin_calc_pop (calc); + switch (calc->pending_op) { + case TWIN_CALC_PLUS: a = a + b; break; + case TWIN_CALC_MINUS: a = a - b; break; + case TWIN_CALC_TIMES: a = a * b; break; + case TWIN_CALC_DIVIDE: if (!b) a = 0; else a = a / b; break; + } + _twin_calc_push (calc); + calc->stack[0] = a; + _twin_calc_update_value (calc); + calc->pending_op = 0; + } + calc->pending_delete = TWIN_TRUE; + break; + case TWIN_CALC_CLEAR: + for (i = 0; i < TWIN_CALC_STACK; i++) + calc->stack[i] = 0; + calc->pending_op = 0; + calc->pending_delete = TWIN_TRUE; + _twin_calc_update_value (calc); + break; + default: + _twin_calc_digit (calc, i); + break; + } +} + +void +twin_calc_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h) +{ + twin_calc_t *calc = malloc (sizeof (twin_calc_t)); + int i, j; + + calc->toplevel = twin_toplevel_create (screen, + TWIN_ARGB32, + TwinWindowApplication, + x, y, w, h, name); + calc->display = twin_label_create (&calc->toplevel->box, + "0", + TWIN_CALC_VALUE_FG, + TWIN_CALC_VALUE_SIZE, + TWIN_CALC_VALUE_STYLE); + twin_widget_set (&calc->display->widget, TWIN_CALC_VALUE_BG); + calc->keys = twin_box_create (&calc->toplevel->box, TwinBoxHorz); + for (i = 0; i < TWIN_CALC_COLS; i++) + { + calc->cols[i] = twin_box_create (calc->keys, TwinBoxVert); + for (j = 0; j < TWIN_CALC_ROWS; j++) + { + int b = calc_layout[j][i]; + calc->buttons[b] = twin_button_create (calc->cols[i], + twin_calc_labels[b], + TWIN_CALC_BUTTON_FG, + TWIN_CALC_BUTTON_SIZE, + TWIN_CALC_BUTTON_STYLE); + twin_widget_set (&calc->buttons[b]->label.widget, + TWIN_CALC_BUTTON_BG); + calc->buttons[b]->signal = _twin_calc_button_signal; + calc->buttons[b]->closure = calc; + if (i || j) + calc->buttons[b]->label.widget.copy_geom = &calc->buttons[calc_layout[0][0]]->label.widget; + } + } + + for (i = 0; i < TWIN_CALC_STACK; i++) + calc->stack[i] = 0; + calc->pending_delete = TWIN_TRUE; + calc->pending_op = 0; + twin_toplevel_show (calc->toplevel); +} diff --git a/twin_calc.h b/twin_calc.h new file mode 100644 index 0000000..0d3df7d --- /dev/null +++ b/twin_calc.h @@ -0,0 +1,35 @@ +/* + * $Id$ + * + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include <twin.h> + +#ifndef _TWIN_CALC_H_ +#define _TWIN_CALC_H_ + +#include <twin.h> + +void +twin_calc_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h); + +#endif /* _TWIN_CALC_H_ */ diff --git a/twin_label.c b/twin_label.c index 6d013ee..6d74160 100644 --- a/twin_label.c +++ b/twin_label.c @@ -30,16 +30,14 @@ _twin_label_query_geometry (twin_label_t *label) twin_path_t *path = twin_path_create (); twin_text_metrics_t m; - label->widget.preferred.left = 0; - label->widget.preferred.top = 0; - label->widget.preferred.right = twin_fixed_to_int (label->font_size); - label->widget.preferred.bottom = twin_fixed_to_int (label->font_size) * 2; + label->widget.preferred.width = twin_fixed_to_int (label->font_size) * 2; + label->widget.preferred.height = twin_fixed_to_int (label->font_size) * 2; if (path) { twin_path_set_font_size (path, label->font_size); twin_path_set_font_style (path, label->font_style); twin_text_metrics_utf8 (path, label->label, &m); - label->widget.preferred.right += twin_fixed_to_int (m.width); + label->widget.preferred.width += twin_fixed_to_int (m.width); twin_path_destroy (path); } } @@ -74,18 +72,19 @@ _twin_label_dispatch (twin_widget_t *widget, twin_event_t *event) { twin_label_t *label = (twin_label_t *) widget; - _twin_widget_dispatch (widget, event); + if (_twin_widget_dispatch (widget, event) == TwinDispatchDone) + return TwinDispatchDone; switch (event->kind) { case TwinEventPaint: _twin_label_paint (label); - return TwinDispatchNone; + break; case TwinEventQueryGeometry: _twin_label_query_geometry (label); break; default: break; } - return TwinDispatchNone; + return TwinDispatchContinue; } void @@ -122,9 +121,8 @@ _twin_label_init (twin_label_t *label, twin_style_t font_style, twin_dispatch_proc_t dispatch) { - static const twin_rect_t empty = { 0, 0, 0, 0 }; - _twin_widget_init (&label->widget, parent, 0, - empty, 1, 1, dispatch); + static const twin_widget_layout_t preferred = { 0, 0, 1, 1 }; + _twin_widget_init (&label->widget, parent, 0, preferred, dispatch); label->label = NULL; label->offset.x = 0; label->offset.y = 0; diff --git a/twin_toplevel.c b/twin_toplevel.c index 5527a1e..42de014 100644 --- a/twin_toplevel.c +++ b/twin_toplevel.c @@ -91,7 +91,7 @@ _twin_toplevel_init (twin_toplevel_t *toplevel, window->destroy = _twin_toplevel_destroy; window->event = _twin_toplevel_event; window->client_data = toplevel; - _twin_box_init (&toplevel->box, 0, window, TwinLayoutVert, dispatch); + _twin_box_init (&toplevel->box, 0, window, TwinBoxVert, dispatch); } twin_toplevel_t * diff --git a/twin_widget.c b/twin_widget.c index cc0e12a..c9b0ed9 100644 --- a/twin_widget.c +++ b/twin_widget.c @@ -41,9 +41,19 @@ twin_dispatch_result_t _twin_widget_dispatch (twin_widget_t *widget, twin_event_t *event) { switch (event->kind) { + case TwinEventQueryGeometry: + widget->layout = TWIN_FALSE; + if (widget->copy_geom) + { + twin_widget_t *copy = widget->copy_geom; + if (copy->layout) + (*copy->dispatch) (copy, event); + widget->preferred = copy->preferred; + return TwinDispatchDone; + } + break; case TwinEventConfigure: widget->extents = event->u.configure.extents; - widget->layout = TWIN_FALSE; break; case TwinEventPaint: _twin_widget_paint (widget); @@ -52,16 +62,14 @@ _twin_widget_dispatch (twin_widget_t *widget, twin_event_t *event) default: break; } - return TwinDispatchNone; + return TwinDispatchContinue; } void _twin_widget_init (twin_widget_t *widget, twin_box_t *parent, twin_window_t *window, - twin_rect_t preferred, - twin_stretch_t hstretch, - twin_stretch_t vstretch, + twin_widget_layout_t preferred, twin_dispatch_proc_t dispatch) { if (parent) @@ -77,13 +85,15 @@ _twin_widget_init (twin_widget_t *widget, widget->next = NULL; widget->window = window; widget->parent = parent; + widget->copy_geom = NULL; widget->paint = TWIN_TRUE; + widget->layout = TWIN_TRUE; + widget->want_focus = TWIN_FALSE; + widget->background = 0x00000000; + widget->extents.left = widget->extents.top = 0; + widget->extents.right = widget->extents.bottom = 0; widget->preferred = preferred; - widget->extents = preferred; - widget->hstretch = hstretch; - widget->vstretch = vstretch; widget->dispatch = dispatch; - widget->background = 0x00000000; } void @@ -171,20 +181,19 @@ twin_widget_create (twin_box_t *parent, twin_argb32_t background, twin_coord_t width, twin_coord_t height, - twin_stretch_t hstretch, - twin_stretch_t vstretch) + twin_stretch_t stretch_width, + twin_stretch_t stretch_height) { - twin_widget_t *widget = malloc (sizeof (twin_widget_t)); - twin_rect_t extents; + twin_widget_t *widget = malloc (sizeof (twin_widget_t)); + twin_widget_layout_t preferred; if (!widget) return NULL; - extents.left = 0; - extents.top = 0; - extents.right = width; - extents.bottom = height; - _twin_widget_init (widget, parent, 0, extents, hstretch, vstretch, - _twin_widget_dispatch); + preferred.width = width; + preferred.height = height; + preferred.stretch_width = stretch_width; + preferred.stretch_height = stretch_height; + _twin_widget_init (widget, parent, 0, preferred, _twin_widget_dispatch); widget->background = background; return widget; } @@ -455,7 +455,7 @@ void _twin_box_init (twin_box_t *box, twin_box_t *parent, twin_window_t *window, - twin_layout_t layout, + twin_box_dir_t dir, twin_dispatch_proc_t dispatch); twin_dispatch_result_t @@ -465,9 +465,7 @@ void _twin_widget_init (twin_widget_t *widget, twin_box_t *parent, twin_window_t *window, - twin_rect_t preferred, - twin_stretch_t hstretch, - twin_stretch_t vstretch, + twin_widget_layout_t preferred, twin_dispatch_proc_t dispatch); twin_dispatch_result_t @@ -33,6 +33,7 @@ #include <twin_text.h> #include <twin_demo.h> #include <twin_hello.h> +#include <twin_calc.h> #define WIDTH 512 #define HEIGHT 512 @@ -49,9 +50,11 @@ main (int argc, char **argv) twin_clock_start (x11->screen, "Clock", 10, 10, 200, 200); twin_text_start (x11->screen, "Gettysburg Address", 0, 0, 300, 300); -#endif twin_hello_start (x11->screen, "Hello, World", 0, 0, 200, 200); +#endif + twin_calc_start (x11->screen, "Calculator", + 100, 100, 200, 200); twin_dispatch (); return 0; } |