diff -urN cui4/cui.c cui5/cui.c --- cui4/cui.c Thu Jan 30 03:40:00 2014 +++ cui5/cui.c Thu Jan 30 03:50:00 2014 @@ -1,4 +1,5 @@ #include "cui.h" +#include "key.h" #include #include #include @@ -6,6 +7,12 @@ #define MSG(s) fprintf(stderr, "%s() %s L%d : %s\n", __func__, __FILE__, __LINE__, s) #define ERR(s) do{ fprintf(stderr, "ERR "); MSG(s); exit(1); }while(0) +#define FALSE 0 +#define TRUE 1 + +cui cui_focus = NULL; +int cui_running = FALSE; + cui cui_alloc(int size) { @@ -28,6 +35,7 @@ if(parent) cui_base_child_add(parent, obj); obj->handler_list = NULL; + obj->flags = 0; } void @@ -80,6 +88,7 @@ { cui_label_init(obj, parent, x, y, s); obj->w += 2; + obj->flags |= CUI_FLG_CAN_FOCUS; } cui_handler_list @@ -99,6 +108,136 @@ cui_bind(cui obj, int evt, cui_handler hdr, void *prm) { obj->handler_list = cui_handler_list_new(hdr, evt, prm, obj->handler_list); +} + +int +cui_handler_call(cui obj, cui_handler_list list, int evt, int val) +{ + if(list == NULL) return FALSE; + if(cui_handler_call(obj, list->next, evt, val)) return TRUE; + if(evt != list->evt) return FALSE; + return (*list->hdr)(obj, evt, val, list->prm); +} + +int +cui_gx(cui obj) +{ + return obj == NULL ? 0 : cui_gx(obj->parent) + obj->x; +} + +int +cui_gy(cui obj) +{ + return obj == NULL ? 0 : cui_gy(obj->parent) + obj->y; +} + +int +cui_glen(cui o1, cui o2) +{ + int dx, dy; + + dx = (cui_gx(o1) + o1->w / 2) - (cui_gx(o2) + o2->w / 2); + dy = (cui_gy(o1) + o1->h / 2) - (cui_gy(o2) + o2->h / 2); + return dx * dx + dy * dy; +} + +int +cui_focus_move_val(cui obj, int key) +{ + if(cui_focus) return cui_glen(obj, cui_focus); + + switch(key){ + case CUI_KEY_UP: + return cui_gy(obj); + case CUI_KEY_DOWN: + return cui_gy(obj) + obj->h; + case CUI_KEY_LEFT: + return cui_gx(obj); + case CUI_KEY_RIGHT: + return cui_gx(obj) + obj->w; + } + return 0; +} + +cui +cui_focus_move_judge(cui obj, int key, cui old, int *val) +{ + int v, jg = FALSE; + + if(obj == NULL) return old; + old = cui_focus_move_judge(obj->next, key, old, val); + old = cui_focus_move_judge(obj->children, key, old, val); + + if(!(obj->flags & CUI_FLG_CAN_FOCUS)) return old; + switch(key){ + case CUI_KEY_UP: + case CUI_KEY_DOWN: + case CUI_KEY_LEFT: + case CUI_KEY_RIGHT: + break; + default: + return old; + } + + v = cui_focus_move_val(obj, key); + if(!old){ + jg = TRUE; + }else if(cui_focus){ + switch(key){ + case CUI_KEY_UP: + jg = cui_gy(obj) <= cui_gy(cui_focus); + break; + case CUI_KEY_DOWN: + jg = cui_gy(obj) >= cui_gy(cui_focus); + break; + case CUI_KEY_LEFT: + jg = cui_gx(obj) <= cui_gx(cui_focus); + break; + case CUI_KEY_RIGHT: + jg = cui_gx(obj) >= cui_gx(cui_focus); + break; + } + jg = jg && v < *val; + }else{ + switch(key){ + case CUI_KEY_UP: + case CUI_KEY_LEFT: + jg = v < *val; + break; + case CUI_KEY_DOWN: + case CUI_KEY_RIGHT: + jg = v > *val; + break; + } + } + if(jg) *val = v; + return jg ? obj : old; +} + +void +cui_quit(void) +{ + cui_running = FALSE; +} + +void +cui_main(cui top_obj) +{ + int key, val; + cui obj; + + cui_key_enter(); + + cui_running = TRUE; + while(cui_running){ + key = cui_key_get2(); + if(cui_focus){ + if(cui_handler_call(cui_focus, cui_focus->handler_list, CUI_EVT_KEY, key)) continue; + } + obj = cui_focus_move_judge(top_obj, key, NULL, &val); + if(obj) cui_focus = obj; + } + cui_key_exit(); } /* EOF */ diff -urN cui4/cui.h cui5/cui.h --- cui4/cui.h Thu Jan 30 03:40:00 2014 +++ cui5/cui.h Thu Jan 30 03:50:00 2014 @@ -7,7 +7,9 @@ #define CUI_EVT_DRAW (1<<1) #define CUI_EVT_BUTTON (1<<2) -typedef void (*cui_handler)(cui obj, int evt, void *prm); +#define CUI_FLG_CAN_FOCUS (1<<0) + +typedef int (*cui_handler)(cui obj, int evt, int val, void *prm); typedef struct cui_handler_list *cui_handler_list; @@ -22,6 +24,7 @@ cui parent, children, next; int x, y, w, h; cui_handler_list handler_list; + int flags; }; typedef struct cui_panel{