diff -urN cui34/Makefile cui35/Makefile --- cui34/Makefile Thu Jan 30 23:00:00 2014 +++ cui35/Makefile Fri Jan 31 01:10:00 2014 @@ -1,7 +1,7 @@ CC = gcc -Wall TARG = cui_test -OBJS = cui.o dialog.o button.o label.o panel.o handler.o esc.o key.o rect.o +OBJS = cui.o focus.o dialog.o button.o fill.o label.o panel.o handler.o esc.o key.o rect.o all: $(TARG) diff -urN cui34/button.c cui35/button.c --- cui34/button.c Fri Jan 31 00:10:00 2014 +++ cui35/button.c Fri Jan 31 01:10:00 2014 @@ -33,10 +33,10 @@ /* CUI_EVT_DRAW */ - attr = (val == CUI_DRAW_FOCUS) ? CUI_ESC_ULINE : CUI_ESC_NORMAL; + attr = (val == CUI_DRAW_FOCUS) ? CUI_ATTR_ULINE : CUI_ATTR_NORMAL; cui_label_attr_set(p->lb1, attr); cui_label_attr_set(p->lb3, attr); - attr = (val == CUI_DRAW_ACTIVE) ? CUI_ESC_REVERSE : attr; + attr = (val == CUI_DRAW_ACTIVE) ? CUI_ATTR_REVERSE : attr; cui_label_attr_set(p->lb2, attr); return TRUE; } diff -urN cui34/cui.c cui35/cui.c --- cui34/cui.c Fri Jan 31 01:00:00 2014 +++ cui35/cui.c Fri Jan 31 01:10:00 2014 @@ -1,4 +1,5 @@ #include "cui.h" +#include "focus.h" #include "rect.h" #include "esc.h" #include "key.h" @@ -107,23 +108,22 @@ } x = r2->x; cui_esc_loc(cui_gx(obj) + x, cui_gy(obj) + y); - if(attr != CUI_ESC_NORMAL) cui_esc_attr(attr); + if(attr & CUI_ATTR_ULINE) cui_esc_attr(CUI_ESC_ULINE); + if(attr & CUI_ATTR_REVERSE) cui_esc_attr(CUI_ESC_REVERSE); printf("%s", s); - if(attr != CUI_ESC_NORMAL) cui_esc_attr(CUI_ESC_NORMAL); + if(attr != CUI_ATTR_NORMAL) cui_esc_attr(CUI_ESC_NORMAL); fflush(stdout); if(s2) free(s2); } void -cui_fill_rect(cui obj, int x, int y, int w, int h, char c, int attr) +cui_fill_rect(cui obj, int x, int y, int w, int h, char *s, int attr) { int ix, iy; - char s[4]; + int n = strlen(s); - s[0] = c; - s[1] = '\0'; for(iy=0; iyh; - 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_chain(cui obj, int key, cui old, int *val); - -cui -cui_focus_move_judge(cui obj, int key, cui old, int *val) -{ - int v, jg = FALSE; - cui focus = cui_focus_get(); - - if(obj == NULL) return old; - old = cui_focus_move_judge_chain(obj->children, key, old, val); - - if(obj == focus) return old; - if(!(obj->flags & CUI_FLG_CAN_FOCUS)) return old; - if(!cui_is_visible(obj)) 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(focus){ - switch(key){ - case CUI_KEY_UP: - jg = cui_gy(obj) <= cui_gy(focus); - break; - case CUI_KEY_DOWN: - jg = cui_gy(obj) + obj->h >= cui_gy(focus) + focus->h; - break; - case CUI_KEY_LEFT: - jg = cui_gx(obj) <= cui_gx(focus); - break; - case CUI_KEY_RIGHT: - jg = cui_gx(obj) + obj->w >= cui_gx(focus) + focus->w; - break; - } - if(old) jg = jg && v < *val; - }else if(!old){ - jg = TRUE; - }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; -} - -cui -cui_focus_move_judge_chain(cui obj, int key, cui old, int *val) -{ - if(obj == NULL) return old; - old = cui_focus_move_judge_chain(obj->next, key, old, val); - return cui_focus_move_judge(obj, key, old, val); -} - - void cui_draw(cui obj) { @@ -340,7 +254,6 @@ struct cui_main_stack stk; cui_main_stack sp = (cui_main_stack)&stk; - void *kd; int key, val; cui focus, obj; @@ -350,7 +263,7 @@ main_stack = sp; cui_esc_enter(); - if((kd = cui_key_enter()) == NULL) ERR("No Mem"); + cui_key_enter(); cui_clear(top_obj); cui_draw(top_obj); @@ -367,18 +280,42 @@ cui_draw(obj); } } - cui_key_exit(kd); + cui_key_exit(); cui_esc_exit(); main_stack = sp->prev; } void +cui_del_from(cui obj, cui *from) +{ + if(*from == NULL) return; + if(*from == obj){ + *from = obj->next; + return; + } + cui_del_from(obj, &(*from)->next); +} + +void +cui_del(cui obj) +{ + cui_del_from(obj, &obj->parent->children); +} + +void +cui_free_chain(cui obj) +{ + if(obj == NULL) return; + cui_free_chain(obj->next); + cui_free(obj); +} + +void cui_free(cui obj) { if(obj == NULL) return; - cui_free(obj->next); - cui_free(obj->children); + cui_free_chain(obj->children); cui_handler_list_free(obj->handler_list); free(obj); } diff -urN cui34/cui.h cui35/cui.h --- cui34/cui.h Fri Jan 31 00:30:00 2014 +++ cui35/cui.h Fri Jan 31 01:10:00 2014 @@ -20,6 +20,10 @@ #define CUI_FLG_CAN_FOCUS (1<<0) #define CUI_FLG_HIDE (1<<1) +#define CUI_ATTR_NORMAL 0 +#define CUI_ATTR_ULINE (1<<0) +#define CUI_ATTR_REVERSE (1<<1) + typedef struct cui_handler_list *cui_handler_list; #include "rect.h" @@ -37,12 +41,13 @@ cui cui_base_new(cui parent, int x, int y, int w, int h); void cui_draw_str(cui obj, int x, int y, char *s, int attr); -void cui_fill_rect(cui obj, int x, int y, int w, int h, char c, int attr); +void cui_fill_rect(cui obj, int x, int y, int w, int h, char *s, int attr); void cui_clear_rect(cui obj, int x, int y, int w, int h); void cui_clear(cui obj); int cui_gx(cui obj); int cui_gy(cui obj); +int cui_glen(cui o1, cui o2); void cui_draw(cui obj); void cui_draw_chain(cui obj); void cui_hide(cui obj); @@ -60,6 +65,8 @@ void cui_quit(void); void cui_main(cui top_obj, cui init_focus); +void cui_del(cui obj); +void cui_free_chain(cui obj); void cui_free(cui obj); #endif diff -urN cui34/cui_test.c cui35/cui_test.c --- cui34/cui_test.c Fri Jan 31 00:40:00 2014 +++ cui35/cui_test.c Fri Jan 31 01:10:00 2014 @@ -52,6 +52,8 @@ cui_unbind(obj, CUI_EVT_BUTTON, my_hdr); joke = joke_new(((cui)p)->parent, 0, 4); cui_main(joke, joke->children->next); + cui_del(joke); + cui_free(joke); return TRUE; } diff -urN cui34/esc.c cui35/esc.c --- cui34/esc.c Thu Jan 30 22:00:00 2014 +++ cui35/esc.c Fri Jan 31 01:10:00 2014 @@ -60,9 +60,12 @@ cui_esc(onoff ? "?25h" : "?25l"); } +int cui_esc_cnt = 0; + void cui_esc_enter(void) { + if(cui_esc_cnt++ > 0) return; cui_esc_cursor_pos_save(); cui_esc_exopt(CUI_ESC_CURSOR_ONOFF, 0); } @@ -70,6 +73,7 @@ void cui_esc_exit(void) { + if(--cui_esc_cnt > 0) return; cui_esc_attr(CUI_ESC_NORMAL); cui_esc_exopt(CUI_ESC_CURSOR_ONOFF, 1); cui_esc_cursor_pos_load(); diff -urN cui34/fill.c cui35/fill.c --- cui34/fill.c Thu Jan 1 09:00:00 1970 +++ cui35/fill.c Fri Jan 31 01:10:00 2014 @@ -0,0 +1,31 @@ +#include "fill.h" +#include "handler.h" +#include + +cui +cui_fill_new(cui parent, int x, int y, int w, int h, char *s, int attr) +{ + cui obj = cui_alloc(sizeof(struct cui_fill)); + cui_fill_init(obj, parent, x, y, w, h, s, attr); + return obj; +} + +int +cui_fill_hdr(cui obj, int evt, int val, void *prm) +{ + cui_label lb = (cui_label)obj; + cui_fill_rect(obj, 0, 0, obj->w, obj->h, cui_label_str_get(obj), lb->attr); + return TRUE; +} + +void +cui_fill_init(cui obj, cui parent, int x, int y, int w, int h, char *s, int attr) +{ + cui_label_init(obj, parent, x, y, s); + obj->w = w; + obj->h = h; + cui_bind(obj, CUI_EVT_DRAW, cui_fill_hdr, NULL); + ((cui_label)obj)->attr = attr; +} + +/* EOF */ diff -urN cui34/fill.h cui35/fill.h --- cui34/fill.h Thu Jan 1 09:00:00 1970 +++ cui35/fill.h Fri Jan 31 01:10:00 2014 @@ -0,0 +1,13 @@ +#ifndef __CUI_FILL__ +#define __CUI_FILL__ + +#include "label.h" + +typedef struct cui_fill{ + struct cui_label lable; +} *cui_fill; + +cui cui_fill_new(cui parent, int x, int y, int w, int h, char *s, int attr); +void cui_fill_init(cui obj, cui parent, int x, int y, int w, int h, char *s, int attr); + +#endif diff -urN cui34/focus.c cui35/focus.c --- cui34/focus.c Thu Jan 1 09:00:00 1970 +++ cui35/focus.c Fri Jan 31 01:10:00 2014 @@ -0,0 +1,88 @@ +#include "focus.h" +#include "key.h" +#include + +int +cui_focus_move_val(cui obj, int key) +{ + if(cui_focus_get()) return cui_glen(obj, cui_focus_get()); + + 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_chain(cui obj, int key, cui old, int *val) +{ + if(obj == NULL) return old; + old = cui_focus_move_judge_chain(obj->next, key, old, val); + return cui_focus_move_judge(obj, key, old, val); +} + +cui +cui_focus_move_judge(cui obj, int key, cui old, int *val) +{ + int v, jg = FALSE; + cui focus = cui_focus_get(); + + if(obj == NULL) return old; + old = cui_focus_move_judge_chain(obj->children, key, old, val); + + if(obj == focus) return old; + if(!(obj->flags & CUI_FLG_CAN_FOCUS)) return old; + if(!cui_is_visible(obj)) 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(focus){ + switch(key){ + case CUI_KEY_UP: + jg = cui_gy(obj) <= cui_gy(focus); + break; + case CUI_KEY_DOWN: + jg = cui_gy(obj) + obj->h >= cui_gy(focus) + focus->h; + break; + case CUI_KEY_LEFT: + jg = cui_gx(obj) <= cui_gx(focus); + break; + case CUI_KEY_RIGHT: + jg = cui_gx(obj) + obj->w >= cui_gx(focus) + focus->w; + break; + } + if(old) jg = jg && v < *val; + }else if(!old){ + jg = TRUE; + }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; +} + +/* EOF */ diff -urN cui34/focus.h cui35/focus.h --- cui34/focus.h Thu Jan 1 09:00:00 1970 +++ cui35/focus.h Fri Jan 31 01:10:00 2014 @@ -0,0 +1,8 @@ +#ifndef ___FOCUS_H__ +#define ___FOCUS_H__ + +#include "cui.h" + +cui cui_focus_move_judge(cui obj, int key, cui old, int *val); + +#endif diff -urN cui34/key.c cui35/key.c --- cui34/key.c Fri Jan 31 00:50:00 2014 +++ cui35/key.c Fri Jan 31 01:10:00 2014 @@ -9,26 +9,26 @@ #define KEY_FD 0 -void * +int cui_key_cnt = 0; +static struct termios bak; + +void cui_key_enter(void) { - struct termios raw, *bak; - - if((bak = malloc(sizeof(struct termios))) == NULL) return NULL; + struct termios raw; - tcgetattr(KEY_FD, bak); + if(cui_key_cnt++ > 0) return; + tcgetattr(KEY_FD, &bak); cfmakeraw(&raw); raw.c_lflag &= ~FLUSHO; tcsetattr(KEY_FD, TCSANOW, &raw); - return bak; } void -cui_key_exit(void *kd) +cui_key_exit(void) { - if(!kd) return; - tcsetattr(KEY_FD, TCSANOW, (struct termios *)kd); - free(kd); + if(--cui_key_cnt > 0) return; + tcsetattr(KEY_FD, TCSANOW, &bak); } int diff -urN cui34/key.h cui35/key.h --- cui34/key.h Fri Jan 31 00:50:00 2014 +++ cui35/key.h Fri Jan 31 01:10:00 2014 @@ -9,8 +9,8 @@ #define CUI_KEY_RIGHT 0x14 /* DC4 */ #define CUI_KEY_ESC 0x1b -void *cui_key_enter(void); -void cui_key_exit(void *kd); +void cui_key_enter(void); +void cui_key_exit(void); int cui_key_get(void); int cui_key_get2(void); diff -urN cui34/label.c cui35/label.c --- cui34/label.c Thu Jan 30 23:50:00 2014 +++ cui35/label.c Fri Jan 31 01:10:00 2014 @@ -26,7 +26,7 @@ cui_label p = (cui_label)obj; cui_base_init(obj, parent, x, y, strlen(s), 1); p->s = s; - p->attr = CUI_ESC_NORMAL; + p->attr = CUI_ATTR_NORMAL; cui_bind(obj, CUI_EVT_DRAW, cui_label_hdr, NULL); } diff -urN cui34/panel.c cui35/panel.c --- cui34/panel.c Thu Jan 30 22:00:00 2014 +++ cui35/panel.c Fri Jan 31 01:10:00 2014 @@ -1,7 +1,5 @@ #include "panel.h" -#include "esc.h" -#include "handler.h" -#include +#include "fill.h" cui cui_panel_new(cui parent, int x, int y, int w, int h) @@ -11,25 +9,19 @@ return obj; } -int -cui_panel_hdr(cui obj, int evt, int val, void *prm) -{ - cui_fill_rect(obj, 1, 0, obj->w-2, 1, '-', CUI_ESC_NORMAL); - cui_fill_rect(obj, 1, obj->h-1, obj->w-2, 1, '-', CUI_ESC_NORMAL); - cui_fill_rect(obj, 0, 1, 1, obj->h-2, '|', CUI_ESC_NORMAL); - cui_fill_rect(obj, obj->w-1, 1, 1, obj->h-2, '|', CUI_ESC_NORMAL); - cui_draw_str(obj, 0, 0, "+", CUI_ESC_NORMAL); - cui_draw_str(obj, obj->w-1, 0, "+", CUI_ESC_NORMAL); - cui_draw_str(obj, obj->w-1, obj->h-1, "+", CUI_ESC_NORMAL); - cui_draw_str(obj, 0, obj->h-1, "+", CUI_ESC_NORMAL); - return TRUE; -} - void cui_panel_init(cui obj, cui parent, int x, int y, int w, int h) { cui_base_init(obj, parent, x, y, w, h); - cui_bind(obj, CUI_EVT_DRAW, cui_panel_hdr, NULL); + + cui_fill_new(obj, 1, 0, w-2, 1, "-", CUI_ATTR_NORMAL); + cui_fill_new(obj, 1, h-1, w-2, 1, "-", CUI_ATTR_NORMAL); + cui_fill_new(obj, 0, 1, 1, h-2, "|", CUI_ATTR_NORMAL); + cui_fill_new(obj, w-1, 1, 1, h-2, "|", CUI_ATTR_NORMAL); + cui_fill_new(obj, 0, 0, 1, 1, "+", CUI_ATTR_NORMAL); + cui_fill_new(obj, w-1, 0, 1, 1, "+", CUI_ATTR_NORMAL); + cui_fill_new(obj, w-1, h-1, 1, 1, "+", CUI_ATTR_NORMAL); + cui_fill_new(obj, 0, h-1, 1, 1, "+", CUI_ATTR_NORMAL); } /* EOF */