diff --git a/assets-fx/img/opt_mem.png b/assets-fx/img/opt_mem.png index 44ba00b..695517b 100644 Binary files a/assets-fx/img/opt_mem.png and b/assets-fx/img/opt_mem.png differ diff --git a/include/gintctl/widgets/gscreen.h b/include/gintctl/widgets/gscreen.h index e9d2177..526cace 100644 --- a/include/gintctl/widgets/gscreen.h +++ b/include/gintctl/widgets/gscreen.h @@ -30,6 +30,8 @@ typedef struct { /* Fixed widets */ jlabel *title; jfkeys *fkeys; + /* Current function bar level */ + int8_t fkey_level; } gscreen; @@ -55,6 +57,17 @@ gscreen *gscreen_create(char const *title, char const *fkeys); #define gscreen_create2(short, img, long, fkeys) gscreen_create(long, fkeys) #endif +//--- +// Function bar settings +//--- + +/* gscreen_set_fkeys_level(): Select the function key bar */ +void gscreen_set_fkeys_level(gscreen *s, int level); + +//--- +// Tab settings +//--- + /* gscreen_add_tab(): Add a tab to the stacked layout The child's parent will be changed. The widget will also have a stretch of (1, 1, false) set by default. If not NULL, the last parameter indicates @@ -65,6 +78,16 @@ void gscreen_add_tab(gscreen *scene, void *widget, void *focus); void gscreen_add_tabs(gscreen *s, ...); #define gscreen_add_tabs(...) gscreen_add_tabs(__VA_ARGS__, NULL) +/* gscreen_set_tab_title_visible(): Set whether title bar is shown on a tab */ +void gscreen_set_tab_title_visible(gscreen *s, int tab, bool visible); + +/* gscreen_set_tab_fkeys_visible(): Set whether fkeys are shown on a tab */ +void gscreen_set_tab_fkeys_visible(gscreen *s, int tab, bool visible); + +//--- +// Tab navigation +//--- + /* gscreen_show_tab(): Show a tab from the stack Returns true if the tab changed, false if it was already active or if it is an invalid tab widget. */ @@ -76,12 +99,6 @@ int gscreen_current_tab(gscreen *s); /* gscreen_in(): Check if we're in a specific tab */ bool gscreen_in(gscreen *s, int tab); -/* gscreen_set_tab_title_visible(): Set whether title bar is shown on a tab */ -void gscreen_set_tab_title_visible(gscreen *s, int tab, bool visible); - -/* gscreen_set_tab_fkeys_visible(): Set whether fkeys are shown on a tab */ -void gscreen_set_tab_fkeys_visible(gscreen *s, int tab, bool visible); - //--- // Focus management //--- diff --git a/src/libs/justui.c b/src/libs/justui.c index 4144016..9cef506 100644 --- a/src/libs/justui.c +++ b/src/libs/justui.c @@ -103,11 +103,11 @@ void gintctl_libs_justui(void) jwidget_set_border(c1, J_BORDER_SOLID, 1, C_BLACK); jwidget_set_stretch(c1, 1, 1, false); - jwidget_set_stretch(c3, 2, 0, false); + jwidget_set_stretch(c3, 2, 1, false); gtable_set_rows(c3, 5); gtable_set_column_titles(c3, "C1", "C2", "Column 3"); gtable_set_column_sizes(c3, 1, 1, 3); - gtable_set_font(c3, &font_mini); + gtable_set_font(c3, _(&font_mini, dfont_default())); jinput *input = jinput_create("Prompt:" _(," "), 12, tab1); jwidget_set_stretch(input, 1, 0, false); @@ -118,8 +118,8 @@ void gintctl_libs_justui(void) gtable *tree = gtable_create(3, widget_tree_gen, scr->scene, NULL); gtable_set_column_titles(tree, "Type", "Size", "Content"); gtable_set_column_sizes(tree, 3, 2, 2); - gtable_set_row_spacing(tree, 2); - gtable_set_font(tree, &font_mini); + gtable_set_row_spacing(tree, _(2,3)); + gtable_set_font(tree, _(&font_mini, dfont_default())); // Scene setup @@ -127,15 +127,12 @@ void gintctl_libs_justui(void) gscreen_add_tab(scr, tree, tree); jscene_set_focused_widget(scr->scene, c3); gtable_set_rows(tree, recursive_widget_count(scr->scene)); - gscreen_set_tab_title_visible(scr, 1, false); + gscreen_set_tab_title_visible(scr, 1, _(false,true)); - jevent e; - key_event_t k; int key = 0; - while(key != KEY_EXIT) { - jscene_run(scr->scene, &e, &k); + jevent e = jscene_run(scr->scene); if(e.type == JSCENE_PAINT) { @@ -154,8 +151,8 @@ void gintctl_libs_justui(void) gscreen_focus(scr, c3); } - if(k.type != KEYEV_DOWN) continue; - key = k.key; + if(e.type != JSCENE_KEY || e.key.type != KEYEV_DOWN) continue; + key = e.key.key; if(key == KEY_F3 && gscreen_in(scr, 0)) { diff --git a/src/mem/mem.c b/src/mem/mem.c index e877909..e5bb6fc 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -5,6 +5,17 @@ #include #include +#include + +#include +#include +#include + +struct view { + uint32_t base; + bool ascii; + int lines; +}; /* Code of exception that occurs during a memory access */ static uint32_t exception = 0; @@ -29,10 +40,7 @@ int line(uint8_t *mem, char *header, char *bytes, char *ascii, int n) exception = 0; gint_exc_catch(catch_exc); uint8_t z; - __asm__ volatile( - "mov.l %1, %0" - : "=r"(z) - : "m"(*mem)); + __asm__ volatile("mov.l %1, %0" : "=r"(z) : "m"(*mem)); gint_exc_catch(NULL); sprintf(header, "%08X:", (uint32_t)mem); @@ -72,194 +80,119 @@ int line(uint8_t *mem, char *header, char *bytes, char *ascii, int n) ascii[n] = 0; for(int k = 0; 2 * k < n; k++) - { sprintf(bytes + 5 * k, "%02X%02X ", mem[2*k], mem[2*k+1]); - } + return 0; } -void draw_input(int x, int y, char *text, int cursor_pos) +static void paint_mem(int x, int y, struct view *v) { - int w, h; - int next = text[cursor_pos]; - text[cursor_pos] = 0; - dsize(text, NULL, &w, &h); - text[cursor_pos] = next; + char header[12], bytes[48], ascii[24]; + uint32_t addr = v->base; + uint8_t *mem = (void *)addr; - dtext(x, y, C_BLACK, text); - dline(x+w, y, x+w, y+h-1, C_BLACK); + for(int i = 0; i < v->lines; i++, mem += 8, addr += 8) + { + GUNUSED int status = line(mem, header, bytes, ascii, 8); + + #ifdef FX9860G + font_t const *old_font = dfont(&font_hexa); + dtext(x, y + 6*i, C_BLACK, v->ascii ? ascii : header); + dtext(x + 40, y + 6*i, C_BLACK, bytes); + dfont(old_font); + #endif + + #ifdef FXCG50 + dtext(x, y + 12*i, C_BLACK, header); + dtext(x + 85, y + 12*i, status ? C_RED : C_BLACK, bytes); + + for(int k = 7; k >= 0; k--) + { + ascii[k+1] = 0; + dtext(x + 250 + 9*k, y + 12*i, C_BLACK, ascii+k); + } + #endif + } } /* gintctl_mem(): Memory browser */ void gintctl_mem(void) { - uint32_t base = 0x88000000; - key_event_t ev; + struct view v = { .base = 0x88000000, .ascii = false, .lines = _(9,14) }; + + gscreen *s = gscreen_create2(NULL, &img_opt_mem, + "Memory browser", "@JUMP;;#ROM;#RAM;#ILRAM;#ADDIN"); + jwidget *tab = jwidget_create(NULL); + jpainted *mem = jpainted_create(paint_mem, &v, _(115,321), _(53,167), tab); + jinput *input = jinput_create("Go to:" _(," "), 12, tab); + + jwidget_set_margin(mem, _(0,8), 0, _(0,8), 0); + jwidget_set_margin(input, 0, 0, 0, _(1,4)); + jwidget_set_stretch(input, 1, 0, false); + jwidget_set_visible(input, false); + jlayout_set_vbox(tab)->spacing = _(3,4); + gscreen_add_tab(s, tab, NULL); + int key = 0; - - #ifdef FX9860G - extern font_t font_hexa; - font_t const *old_font = dfont(&font_hexa); - int view_ascii = 0; - #endif - - char header[12]; - char bytes[48]; - char ascii[24]; - - int size = 8; - int lines = _(9,14); - - char input[9]; - int input_pos = -1; - int input_len = -1; - int input_keys[16] = { - KEY_0, KEY_1, KEY_2, KEY_3, - KEY_4, KEY_5, KEY_6, KEY_7, - KEY_8, KEY_9, KEY_XOT, KEY_LOG, - KEY_LN, KEY_SIN, KEY_COS, KEY_TAN, - }; - while(key != KEY_EXIT) { - dclear(C_WHITE); + bool input_focus = (jscene_focused_widget(s->scene) == input); + jevent e = jscene_run(s->scene); - uint32_t addr = base; - uint8_t *mem = (void *)addr; - - for(int i = 0; i < lines; i++) + if(e.type == JSCENE_PAINT) { - GUNUSED int status = line(mem,header,bytes,ascii,size); - - #ifdef FX9860G - dtext( 5, 6*i + 1, C_BLACK, view_ascii?ascii:header); - dtext(45, 6*i + 1, C_BLACK, bytes); - #endif - - #ifdef FXCG50 - dtext(25, 26 + 12*i, C_BLACK, header); - dtext(110, 26 + 12*i, status ? C_RED : C_BLACK, bytes); - - for(int k = size - 1; k >= 0; k--) - { - ascii[k+1] = 0; - dtext(275 + 9*k, 26 + 12*i, C_BLACK, ascii+k); - } - #endif - - mem += size; - addr += size; + dclear(C_WHITE); + jscene_render(s->scene); + dupdate(); } - - #ifdef FX9860G - if(input_pos < 0) - { - extern bopti_image_t img_opt_mem; - dsubimage(0, 56, &img_opt_mem, 0, 0, 128, 8, - DIMAGE_NONE); - if(view_ascii) dsubimage(23, 56, &img_opt_mem, 23, 9, - 21, 8, DIMAGE_NONE); - } - else - { - extern font_t font_mini; - font_t const *old_font = dfont(&font_mini); - - dtext(1, 57, C_BLACK, "Go to:"); - draw_input(24, 57, input, input_pos); - - dfont(old_font); - } - #endif - - #ifdef FXCG50 - row_title("Memory browser"); - if(input_pos < 0) - { - fkey_button(1, "JUMP"); - fkey_action(3, "ROM"); - fkey_action(4, "RAM"); - fkey_action(5, "ILRAM"); - fkey_action(6, "ADDIN"); - } - else - { - dtext(4, 210, C_BLACK, "Go to:"); - draw_input(52, 210, input, input_pos); - } - #endif - - dupdate(); - ev = getkey(); - key = ev.key; - - int move_speed = 1; - if(ev.shift || keydown(KEY_SHIFT)) move_speed = 8; - - if(key == KEY_UP) base -= move_speed * size * lines; - if(key == KEY_DOWN) base += move_speed * size * lines; - - if(key == KEY_F1 && input_pos < 0) - { - input[0] = 0; - input_pos = 0; - input_len = 0; - } - if(key == KEY_EXIT && input_pos >= 0) - { - input_pos = -1; - input_len = -1; - /* Don't quit the memory viewer */ - key = 0; - } - if(key == KEY_EXE && input_pos >= 0) + if(e.type == JINPUT_VALIDATED) { /* Parse string into hexa */ uint32_t target = 0; - for(int k = 0; k < input_len; k++) + char const *str = jinput_value(input); + + for(int k = 0; k < str[k]; k++) { target <<= 4; - if(input[k] <= '9') target += (input[k] - '0'); - else target += (input[k] - 'A' + 10); - - base = target & ~7; + if(str[k] <= '9') target += (str[k] - '0'); + else target += ((str[k]|0x20) - 'a' + 10); } - - input_pos = -1; - input_len = -1; + v.base = target & ~7; + } + if(e.type == JINPUT_VALIDATED || e.type == JINPUT_CANCELED) + { + jwidget_set_visible(input, false); + gscreen_set_tab_fkeys_visible(s, 0, true); + gscreen_focus(s, NULL); } - for(int i = 0; i < 16; i++) - if(key == input_keys[i] && input_pos >= 0 && input_len < 8) + if(e.type != JSCENE_KEY || e.key.type == KEYEV_UP) continue; + key = e.key.key; + + int move_speed = (e.key.shift ? 8 : 1); + if(key == KEY_UP) v.base -= move_speed * 8 * v.lines; + if(key == KEY_DOWN) v.base += move_speed * 8 * v.lines; + + if(key == KEY_F1 && !input_focus) { - /* Insert at input_pos, shift everything else right */ - for(int k = 8; k >= input_pos; k--) - input[k + 1] = input[k]; - input[input_pos++] = i + '0' + 7 * (i > 9); - input_len++; + jinput_clear(input); + jwidget_set_visible(input, true); + gscreen_set_tab_fkeys_visible(s, 0, false); + gscreen_focus(s, input); } - if(key == KEY_DEL && input_pos > 0) - { - /* Shift everything after input_pos left one place */ - for(int k = input_pos - 1; k < 8; k++) - input[k] = input[k + 1]; - input_pos--; - input_len--; - } - if(key == KEY_LEFT && input_pos > 0) input_pos--; - if(key == KEY_RIGHT && input_pos < input_len) input_pos++; #ifdef FX9860G - if(key == KEY_F2 && input_pos < 0) view_ascii = !view_ascii; + if(key == KEY_F2 && !input_focus) + { + v.ascii = !v.ascii; + jfkeys_set_level(s->fkeys, v.ascii); + } #endif - if(key == KEY_F3 && input_pos < 0) base = 0x80000000; - if(key == KEY_F4 && input_pos < 0) base = 0x88000000; - if(key == KEY_F5 && input_pos < 0) base = 0xe5200000; - if(key == KEY_F6 && input_pos < 0) base = 0x00300000; + if(key == KEY_F3 && !input_focus) v.base = 0x80000000; + if(key == KEY_F4 && !input_focus) v.base = 0x88000000; + if(key == KEY_F5 && !input_focus) v.base = 0xe5200000; + if(key == KEY_F6 && !input_focus) v.base = 0x00300000; + mem->widget.update = 1; } - - #ifdef FX9860G - dfont(old_font); - #endif } diff --git a/src/widgets/gscreen.c b/src/widgets/gscreen.c index 772fac1..34bf225 100644 --- a/src/widgets/gscreen.c +++ b/src/widgets/gscreen.c @@ -23,6 +23,7 @@ gscreen *gscreen_create(char const *name, char const *labels) g->scene = s; g->tabs = NULL; g->tab_count = 0; + g->fkey_level = 0; jlabel *title = name ? jlabel_create(name, s) : NULL; jwidget *stack = jwidget_create(s); @@ -63,6 +64,27 @@ gscreen *gscreen_create(char const *name, char const *labels) return g; } +/* tab_stack(): Stacked widget where the tabs are located */ +static jwidget *tab_stack(gscreen *s) +{ + int index = (s->title != NULL) ? 1 : 0; + return s->scene->widget.children[index]; +} + +//--- +// Function bar settings +//--- + +/* gscreen_set_fkeys_level(): Select the function key bar */ +void gscreen_set_fkeys_level(gscreen *s, int level) +{ + s->fkey_level = level; +} + +//--- +// Tab settings +//--- + void gscreen_add_tab(gscreen *s, void *widget, void *focus) { struct gscreen_tab *t = realloc(s->tabs, (s->tab_count+1) * sizeof *t); @@ -74,8 +96,7 @@ void gscreen_add_tab(gscreen *s, void *widget, void *focus) s->tabs[s->tab_count].focus = focus; s->tab_count++; - jwidget *stack = s->scene->widget.children[1]; - jwidget_add_child(stack, widget); + jwidget_add_child(tab_stack(s), widget); jwidget_set_stretch(widget, 1, 1, false); } @@ -92,9 +113,31 @@ void gscreen_add_tabs(gscreen *s, ...) va_end(args); } +void gscreen_set_tab_title_visible(gscreen *s, int tab, bool visible) +{ + if(!s->title || tab < 0 || tab >= s->tab_count) return; + s->tabs[tab].title_visible = visible; + + if(gscreen_current_tab(s) == tab) + jwidget_set_visible(s->title, visible); +} + +void gscreen_set_tab_fkeys_visible(gscreen *s, int tab, bool visible) +{ + if(!s->fkeys || tab < 0 || tab >= s->tab_count) return; + s->tabs[tab].fkeys_visible = visible; + + if(gscreen_current_tab(s) == tab) + jwidget_set_visible(s->fkeys, visible); +} + +//--- +// Tab navigation +//--- + bool gscreen_show_tab(gscreen *s, int tab) { - jwidget *stack = s->scene->widget.children[1]; + jwidget *stack = tab_stack(s); jlayout_stack *l = jlayout_get_stack(stack); /* Find widget ID in the stack @@ -119,7 +162,7 @@ bool gscreen_show_tab(gscreen *s, int tab) int gscreen_current_tab(gscreen *s) { - jwidget *stack = s->scene->widget.children[1]; + jwidget *stack = tab_stack(s); jlayout_stack *l = jlayout_get_stack(stack); return l->active; } @@ -129,17 +172,9 @@ bool gscreen_in(gscreen *s, int tab) return gscreen_current_tab(s) == tab; } -void gscreen_set_tab_title_visible(gscreen *s, int tab, bool visible) -{ - if(tab < 0 || tab >= s->tab_count) return; - s->tabs[tab].title_visible = visible; -} - -void gscreen_set_tab_fkeys_visible(gscreen *s, int tab, bool visible) -{ - if(tab < 0 || tab >= s->tab_count) return; - s->tabs[tab].fkeys_visible = visible; -} +//--- +// Focus management +//--- void gscreen_focus(gscreen *s, void *widget) { diff --git a/src/widgets/gtable.c b/src/widgets/gtable.c index 12b6330..443e0fd 100644 --- a/src/widgets/gtable.c +++ b/src/widgets/gtable.c @@ -311,17 +311,16 @@ static bool gtable_poly_event(void *t0, jevent e) if(e.type != JWIDGET_KEY) return false; - key_event_t kev = e.data.key; - if(kev.type == KEYEV_UP) return false; + if(e.key.type == KEYEV_UP) return false; - if(kev.key == KEY_DOWN && t->offset < end) { - if(kev.shift) t->offset = end; + if(e.key.key == KEY_DOWN && t->offset < end) { + if(e.key.shift) t->offset = end; else t->offset++; t->widget.update = 1; return true; } - if(kev.key == KEY_UP && t->offset > 0) { - if(kev.shift) t->offset = 0; + if(e.key.key == KEY_UP && t->offset > 0) { + if(e.key.shift) t->offset = 0; else t->offset--; t->widget.update = 1; return true;