diff examples/calculator/main.c @ 88:dd813dcc232c

New example, calculator.
author Thinker K.F. Li <thinker@branda.to>
date Sat, 23 Aug 2008 15:26:47 +0800
parents
children 90428161fc61
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/calculator/main.c	Sat Aug 23 15:26:47 2008 +0800
@@ -0,0 +1,199 @@
+#include <stdio.h>
+#include <mb_types.h>
+#include <X_supp.h>
+#include <shapes.h>
+#include <tools.h>
+#include "calculator_scr.h"
+
+typedef struct _ex_rt ex_rt_t;
+struct _ex_rt {
+    X_MB_runtime_t *rt;
+    calculator_scr_t *code;
+};
+
+static struct {
+    int c;
+    int off;
+} tgt_list[] = {
+    { 0, OFFSET(calculator_scr_t, but_0) },
+    { 1, OFFSET(calculator_scr_t, but_1) },
+    { 2, OFFSET(calculator_scr_t, but_2) },
+    { 3, OFFSET(calculator_scr_t, but_3) },
+    { 4, OFFSET(calculator_scr_t, but_4) },
+    { 5, OFFSET(calculator_scr_t, but_5) },
+    { 6, OFFSET(calculator_scr_t, but_6) },
+    { 7, OFFSET(calculator_scr_t, but_7) },
+    { 8, OFFSET(calculator_scr_t, but_8) },
+    { 9, OFFSET(calculator_scr_t, but_9) },
+    { '+', OFFSET(calculator_scr_t, but_add) },
+    { '-', OFFSET(calculator_scr_t, but_minus) },
+    { '*', OFFSET(calculator_scr_t, but_mul) },
+    { '/', OFFSET(calculator_scr_t, but_div) },
+    { '=', OFFSET(calculator_scr_t, but_eq) },
+    { 'c', OFFSET(calculator_scr_t, but_clr) }
+};
+
+static int real_compute(int op, int v1, int v2) {
+    int r = v2;
+
+    switch(op) {
+    case '+':
+	r = v1 + v2;
+	break;
+    case '-':
+	r = v1 - v2;
+	break;
+    case '*':
+	r = v1 * v2;
+	break;
+    case '/':
+	r = v1 / v2;
+	break;
+    }
+
+    return r;
+}
+
+static void show_text(ex_rt_t *ex_rt, int num) {
+    char buf[20];
+
+    sprintf(buf, "%d", num);
+    sh_text_set_text(ex_rt->code->screen_text, buf);
+    rdman_shape_changed(ex_rt->rt->rdman, ex_rt->code->screen_text);
+}
+
+static void compute(ex_rt_t *ex_rt, coord_t *tgt) {
+    int i;
+    coord_t **coord_p;
+    static int num = 0;
+    static int saved = 0;
+    static int op = 0;
+
+    for(i = 0; i < 16; i++) {
+	coord_p = (coord_t **)((void *)ex_rt->code + tgt_list[i].off);
+	if(*coord_p == (void *)tgt)
+	    break;
+    }
+    if(i >= 16) return;
+
+    if(i < 10) {
+	num = num * 10 + i;
+	show_text(ex_rt, num);
+    } else {
+	switch(tgt_list[i].c) {
+	case 'c':
+	    saved = num = 0;
+	    show_text(ex_rt, 0);
+	    break;
+
+	case '+':
+	    saved = real_compute(op, saved, num);
+	    show_text(ex_rt, saved);
+	    op = '+';
+	    num = 0;
+	    break;
+
+	case '-':
+	    saved = real_compute(op, saved, num);
+	    show_text(ex_rt, saved);
+	    op = '-';
+	    num = 0;
+	    break;
+
+	case '*':
+	    saved = real_compute(op, saved, num);
+	    show_text(ex_rt, saved);
+	    op = '*';
+	    num = 0;
+	    break;
+
+	case '/':
+	    saved = real_compute(op, saved, num);
+	    show_text(ex_rt, saved);
+	    op = '/';
+	    num = 0;
+	    break;
+
+	case '=':
+	    saved = real_compute(op, saved, num);
+	    show_text(ex_rt, saved);
+	    num = 0;
+	    break;
+	}
+    }
+    rdman_redraw_changed(ex_rt->rt->rdman);
+}
+
+static void buttons_handler(event_t *evt, void *arg) {
+    ex_rt_t *ex_rt = (ex_rt_t *)arg;
+
+    switch(evt->type) {
+    case EVT_MOUSE_BUT_PRESS:
+	compute(ex_rt, (coord_t *)evt->cur_tgt);
+	break;
+    }
+}
+
+static void setup_observers(ex_rt_t *ex_rt) {
+    calculator_scr_t *calculator_scr;
+    ob_factory_t *factory;
+    subject_t *subject;
+
+    calculator_scr = ex_rt->code;
+    factory = rdman_get_ob_factory(ex_rt->rt->rdman);
+
+    subject = coord_get_mouse_event(calculator_scr->but_0);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_1);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_2);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_3);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_4);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_5);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_6);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_7);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_8);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_9);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_add);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_minus);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_mul);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_div);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_eq);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+    subject = coord_get_mouse_event(calculator_scr->but_clr);
+    subject_add_observer(factory, subject, buttons_handler, ex_rt);
+}
+
+int main(int argc, char * const argv[]) {
+    X_MB_runtime_t rt;
+    calculator_scr_t *calculator_scr;
+    ex_rt_t ex_rt;
+    int r;
+
+    r = X_MB_init(":0.0", 300, 400, &rt);
+
+    calculator_scr = calculator_scr_new(rt.rdman);
+
+    ex_rt.rt = &rt;
+    ex_rt.code = calculator_scr;
+    setup_observers(&ex_rt);
+
+    X_MB_handle_connection(&rt);
+
+    calculator_scr_free(calculator_scr);
+    X_MB_destroy(&rt);
+
+    return 0;
+}