From bf9ccc57c8787e4b8d4f8d717e9cfbfccdc8fc73 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sat, 10 Aug 2019 14:29:58 +0100 Subject: Amiga: Implement a simple listbrowser log in the GUI Can be revealed/hidden with F12 and is currently undocumented. --- frontends/amiga/gui.c | 271 ++++++++++++++++++++++++++++++++++++++++++- frontends/amiga/libs.c | 10 +- frontends/amiga/libs.h | 1 + frontends/amiga/os3support.h | 8 ++ 4 files changed, 282 insertions(+), 8 deletions(-) diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c index cff727b54..0346ac230 100644 --- a/frontends/amiga/gui.c +++ b/frontends/amiga/gui.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,7 @@ #include #include #include +#include #include #include #include @@ -230,6 +232,8 @@ enum GID_HSCROLLLAYOUT, GID_VSCROLL, GID_VSCROLLLAYOUT, + GID_LOGLAYOUT, + GID_LOG, GID_LAST }; @@ -303,6 +307,8 @@ struct gui_window APTR deferred_rects_pool; struct MinList *deferred_rects; struct browser_window *bw; + struct ColumnInfo *logcolumns; + struct List loglist; }; struct ami_gui_tb_userdata { @@ -1771,6 +1777,7 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie) case RAWKEY_F8: case RAWKEY_F9: case RAWKEY_F10: + case RAWKEY_F12: case RAWKEY_HELP: // don't translate nskey = keycode; @@ -2232,6 +2239,213 @@ static void ami_gui_scroller_update(struct gui_window_2 *gwin) } } +static void ami_gui_console_log_clear(struct gui_window *g) +{ + if(g->shared->objects[GID_LOG] != NULL) { + SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL, + LISTBROWSER_Labels, NULL, + TAG_DONE); + } + + FreeListBrowserList(&g->loglist); + + NewList(&g->loglist); + + if(g->shared->objects[GID_LOG] != NULL) { + SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL, + LISTBROWSER_Labels, &g->loglist, + TAG_DONE); + } +} + +static void ami_gui_console_log_add(struct gui_window *g) +{ + struct TagItem attrs[2]; + + if(g->shared->objects[GID_LOG] != NULL) return; + + attrs[0].ti_Tag = CHILD_MinHeight; + attrs[0].ti_Data = 50; + attrs[1].ti_Tag = TAG_DONE; + attrs[1].ti_Data = 0; + + g->shared->objects[GID_LOG] = ListBrowserObj, + GA_ID, GID_LOG, + LISTBROWSER_ColumnInfo, g->logcolumns, + LISTBROWSER_ColumnTitles, TRUE, + LISTBROWSER_Labels, &g->loglist, + LISTBROWSER_Striping, LBS_ROWS, + ListBrowserEnd; + +#ifdef __amigaos4__ + IDoMethod(g->shared->objects[GID_LOGLAYOUT], LM_ADDCHILD, + g->shared->win, g->shared->objects[GID_LOG], NULL); +#else + SetAttrs(g->shared->objects[GID_LOGLAYOUT], + LAYOUT_AddChild, g->shared->objects[GID_LOG], TAG_MORE, &attrs); +#endif + + FlushLayoutDomainCache((struct Gadget *)g->shared->objects[GID_MAIN]); + + RethinkLayout((struct Gadget *)g->shared->objects[GID_MAIN], + g->shared->win, NULL, TRUE); + + ami_schedule_redraw(g->shared, true); +} + +static void ami_gui_console_log_remove(struct gui_window *g) +{ + if(g->shared->objects[GID_LOG] == NULL) return; + +#ifdef __amigaos4__ + IDoMethod(g->shared->objects[GID_LOGLAYOUT], LM_REMOVECHILD, + g->shared->win, g->shared->objects[GID_LOG]); +#else + SetAttrs(g->shared->objects[GID_LOGLAYOUT], + LAYOUT_RemoveChild, g->shared->objects[GID_LOG], TAG_DONE); +#endif + + g->shared->objects[GID_LOG] = NULL; + + FlushLayoutDomainCache((struct Gadget *)g->shared->objects[GID_MAIN]); + + RethinkLayout((struct Gadget *)g->shared->objects[GID_MAIN], + g->shared->win, NULL, TRUE); + + ami_schedule_redraw(g->shared, true); +} + +static bool ami_gui_console_log_toggle(struct gui_window *g) +{ + if(g->shared->objects[GID_LOG] == NULL) { + ami_gui_console_log_add(g); + return true; + } else { + ami_gui_console_log_remove(g); + return false; + } +} + +static void ami_gui_console_log_switch(struct gui_window *g) +{ + if(g->shared->objects[GID_LOG] == NULL) return; + + RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL, + LISTBROWSER_ColumnInfo, g->logcolumns, + LISTBROWSER_Labels, &g->loglist, + TAG_DONE); +} + +static void +gui_window_console_log(struct gui_window *g, + browser_window_console_source src, + const char *msg, + size_t msglen, + browser_window_console_flags flags) +{ + bool foldable = !!(flags & BW_CS_FLAG_FOLDABLE); + const char *src_text; + const char *level_text; + struct Node *node; + ULONG style = 0; + ULONG fgpen = FOREGROUNDPEN; + ULONG lbflags = LBFLG_READONLY; + char timestamp[256]; + time_t now = time(NULL); + struct tm *timedata = localtime(&now); + + strftime(timestamp, 256, "%c", timedata); + + if(foldable) lbflags |= LBFLG_HASCHILDREN; + + switch (src) { + case BW_CS_INPUT: + src_text = "client-input"; + break; + case BW_CS_SCRIPT_ERROR: + src_text = "scripting-error"; + break; + case BW_CS_SCRIPT_CONSOLE: + src_text = "scripting-console"; + break; + default: + assert(0 && "Unknown scripting source"); + src_text = "unknown"; + break; + } + + switch (flags & BW_CS_FLAG_LEVEL_MASK) { + case BW_CS_FLAG_LEVEL_DEBUG: + level_text = "DEBUG"; + fgpen = DISABLEDTEXTPEN; + lbflags |= LBFLG_CUSTOMPENS; + break; + case BW_CS_FLAG_LEVEL_LOG: + level_text = "LOG"; + fgpen = DISABLEDTEXTPEN; + lbflags |= LBFLG_CUSTOMPENS; + break; + case BW_CS_FLAG_LEVEL_INFO: + level_text = "INFO"; + break; + case BW_CS_FLAG_LEVEL_WARN: + level_text = "WARN"; + break; + case BW_CS_FLAG_LEVEL_ERROR: + level_text = "ERROR"; + style = FSF_BOLD; + break; + default: + assert(0 && "Unknown console logging level"); + level_text = "unknown"; + break; + } + + if(g->shared->objects[GID_LOG] != NULL) { + SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL, + LISTBROWSER_Labels, NULL, + TAG_DONE); + } + + /* Add log entry to list irrespective of whether the log is open. */ + if((node = AllocListBrowserNode(4, + LBNA_Flags, lbflags, + LBNA_Column, 0, + LBNCA_SoftStyle, style, + LBNCA_FGPen, fgpen, + LBNCA_CopyText, TRUE, + LBNCA_Text, timestamp, + LBNA_Column, 1, + LBNCA_SoftStyle, style, + LBNCA_FGPen, fgpen, + LBNCA_CopyText, TRUE, + LBNCA_Text, src_text, + LBNA_Column, 2, + LBNCA_SoftStyle, style, + LBNCA_FGPen, fgpen, + LBNCA_CopyText, TRUE, + LBNCA_Text, level_text, + LBNA_Column, 3, + LBNCA_SoftStyle, style, + LBNCA_FGPen, fgpen, + LBNCA_CopyText, TRUE, + LBNCA_Text, msg, + TAG_DONE))) { + AddTail(&g->loglist, node); + } + + if(g->shared->objects[GID_LOG] != NULL) { + RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_LOG], g->shared->win, NULL, + LISTBROWSER_Labels, &g->loglist, + TAG_DONE); + } + + DebugPrintF("NETSURF: CONSOLE_LOG SOURCE %s %sFOLDABLE %s %.*s\n", + src_text, foldable ? "" : "NOT-", level_text, + (int)msglen, msg); +} + + /** * function to add retrieved favicon to gui */ @@ -2905,6 +3119,10 @@ static BOOL ami_gui_event(void *w) ami_gui_adjust_scale(gwin->gw, +0.1); break; + case RAWKEY_F12: // console log + ami_gui_console_log_toggle(gwin->gw); + break; + case RAWKEY_HELP: // help ami_help_open(AMI_HELP_GUI, scrn); break; @@ -3320,6 +3538,8 @@ static void ami_switch_tab(struct gui_window_2 *gwin, bool redraw) TAG_DONE); cur_gw = gwin->gw; + ami_gui_console_log_switch(gwin->gw); + if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) { amiga_warn_user("NoMemory", ""); return; @@ -4355,6 +4575,38 @@ gui_window_create(struct browser_window *bw, g->deferred_rects_pool = ami_memory_itempool_create(sizeof(struct rect)); g->bw = bw; + NewList(&g->loglist); +#ifdef __amigaos4__ + g->logcolumns = AllocLBColumnInfo(4, + LBCIA_Column, 0, + // LBCIA_CopyTitle, TRUE, + LBCIA_Title, "time", /**\TODO: add these to Messages */ + LBCIA_Weight, 10, + LBCIA_DraggableSeparator, TRUE, + LBCIA_Separator, TRUE, + LBCIA_Column, 1, + // LBCIA_CopyTitle, TRUE, + LBCIA_Title, "source", /**\TODO: add these to Messages */ + LBCIA_Weight, 10, + LBCIA_DraggableSeparator, TRUE, + LBCIA_Separator, TRUE, + LBCIA_Column, 2, + // LBCIA_CopyTitle, TRUE, + LBCIA_Title, "level", /**\TODO: add these to Messages */ + LBCIA_Weight, 5, + LBCIA_DraggableSeparator, TRUE, + LBCIA_Separator, TRUE, + LBCIA_Column, 3, + // LBCIA_CopyTitle, TRUE, + LBCIA_Title, "message", /**\TODO: add these to Messages */ + LBCIA_Weight, 75, + LBCIA_DraggableSeparator, TRUE, + LBCIA_Separator, TRUE, + TAG_DONE); +#else + /**\TODO write OS3-compatible version */ +#endif + if((flags & GW_CREATE_TAB) && existing) { g->shared = existing->shared; @@ -4806,6 +5058,10 @@ gui_window_create(struct browser_window *bw, EndGroup, EndGroup, EndGroup, +// LAYOUT_WeightBar, TRUE, + LAYOUT_AddChild, g->shared->objects[GID_LOGLAYOUT] = LayoutVObj, + EndGroup, + CHILD_WeightedHeight, 0, #ifndef __amigaos4__ LAYOUT_AddChild, g->shared->objects[GID_STATUS] = StringObj, GA_ID, GID_STATUS, @@ -5051,6 +5307,11 @@ static void gui_window_destroy(struct gui_window *g) if((g->shared->tabs == 1) && (nsoption_bool(tab_always_show) == false)) ami_toggletabbar(g->shared, false); + FreeListBrowserList(&g->loglist); +#ifdef __amigaos4__ + FreeLBColumnInfo(g->logcolumns); +#endif + if(g->tabtitle) free(g->tabtitle); free(g); return; @@ -5084,6 +5345,11 @@ static void gui_window_destroy(struct gui_window *g) ami_ctxmenu_release_hook(g->shared->ctxmenu_hook); ami_gui_menu_free(g->shared); + FreeListBrowserList(&g->loglist); +#ifdef __amigaos4__ + FreeLBColumnInfo(g->logcolumns); +#endif + free(g->shared->wintitle); ami_utf8_free(g->shared->status); free(g->shared->svbuffer); @@ -6016,6 +6282,7 @@ static char *ami_gui_get_user_dir(STRPTR current_user) return current_user_dir; } + static struct gui_window_table amiga_window_table = { .create = gui_window_create, .destroy = gui_window_destroy, @@ -6036,9 +6303,11 @@ static struct gui_window_table amiga_window_table = { .create_form_select_menu = gui_create_form_select_menu, .file_gadget_open = gui_file_gadget_open, .drag_save_object = gui_drag_save_object, - .drag_save_selection =gui_drag_save_selection, + .drag_save_selection = gui_drag_save_selection, .start_selection = gui_start_selection, + .console_log = gui_window_console_log, + /* from theme */ .set_pointer = gui_window_set_pointer, .start_throbber = gui_window_start_throbber, diff --git a/frontends/amiga/libs.c b/frontends/amiga/libs.c index 7de768b6a..109baa44e 100644 --- a/frontends/amiga/libs.c +++ b/frontends/amiga/libs.c @@ -280,6 +280,7 @@ bool ami_libs_open(void) AMINS_CLASS_OPEN("gadgets/integer.gadget", 41, Integer, INTEGER, false) AMINS_CLASS_OPEN("images/label.image", 41, Label, LABEL, false) AMINS_CLASS_OPEN("gadgets/layout.gadget", 43, Layout, LAYOUT, true) + AMINS_CLASS_OPEN("gadgets/listbrowser.gadget", 41, ListBrowser, LISTBROWSER, true) AMINS_CLASS_OPEN("gadgets/radiobutton.gadget", 41, RadioButton, RADIOBUTTON, false) AMINS_CLASS_OPEN("gadgets/scroller.gadget", 42, Scroller, SCROLLER, false) AMINS_CLASS_OPEN("gadgets/space.gadget", 41, Space, SPACE, false) @@ -287,10 +288,7 @@ bool ami_libs_open(void) AMINS_CLASS_OPEN("gadgets/string.gadget", 41, String, STRING, false) AMINS_CLASS_OPEN("window.class", 42, Window, WINDOW, false) -#ifdef __amigaos4__ - /* BOOPSI classes only required on OS4 */ - AMINS_CLASS_OPEN("gadgets/listbrowser.gadget", 45, ListBrowser, LISTBROWSER, true) -#else +#ifndef __amigaos4__ /* BOOPSI classes only required prior to OS4 */ PageClass = PAGE_GetClass(); #endif @@ -317,15 +315,13 @@ void ami_libs_close(void) AMINS_CLASS_CLOSE(Integer) AMINS_CLASS_CLOSE(Label) AMINS_CLASS_CLOSE(Layout) + AMINS_CLASS_CLOSE(ListBrowser) AMINS_CLASS_CLOSE(RadioButton) AMINS_CLASS_CLOSE(Scroller) AMINS_CLASS_CLOSE(Space) AMINS_CLASS_CLOSE(SpeedBar) AMINS_CLASS_CLOSE(String) AMINS_CLASS_CLOSE(Window) -#ifdef __amigaos4__ - AMINS_CLASS_CLOSE(ListBrowser) -#endif /* Libraries */ AMINS_LIB_CLOSE(GuiGFX) diff --git a/frontends/amiga/libs.h b/frontends/amiga/libs.h index aa3622af2..db5b65c75 100644 --- a/frontends/amiga/libs.h +++ b/frontends/amiga/libs.h @@ -63,6 +63,7 @@ extern Class *WindowClass; #define LabelObj NewObject(LabelClass, NULL #define LayoutHObj NewObject(LayoutClass, NULL, LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ #define LayoutVObj NewObject(LayoutClass, NULL, LAYOUT_Orientation, LAYOUT_ORIENT_VERT +#define ListBrowserObj NewObject(ListBrowserClass, NULL #ifdef __amigaos4__ #define PageObj NewObject(NULL, "page.gadget" #else diff --git a/frontends/amiga/os3support.h b/frontends/amiga/os3support.h index aa3027d36..fde032a18 100644 --- a/frontends/amiga/os3support.h +++ b/frontends/amiga/os3support.h @@ -78,6 +78,8 @@ #define GAUGEIA_Level TAG_IGNORE #define IA_InBorder TAG_IGNORE #define IA_Label TAG_IGNORE +#define LBNCA_SoftStyle TAG_IGNORE +#define LISTBROWSER_Striping TAG_IGNORE #define SA_Compositing TAG_IGNORE #define SBNA_Text TAG_IGNORE #define SBNA_HintInfo TAG_IGNORE @@ -104,10 +106,15 @@ #define RAWKEY_F8 0x57 #define RAWKEY_F9 0x58 #define RAWKEY_F10 0x59 +#define RAWKEY_F12 0x6F #define RAWKEY_HELP 0x5F #define RAWKEY_HOME 0x70 #define RAWKEY_END 0x71 +/* New pens - these may not be equivalent */ +#define DISABLEDTEXTPEN HIGHLIGHTTEXTPEN +#define TITLEPEN FILLPEN + /* Other constants */ #define BVS_DISPLAY BVS_NONE #define IDCMP_EXTENDEDMOUSE 0 @@ -117,6 +124,7 @@ #define OFF_OPEN 0 #define AFF_OTAG 0 #define ML_SEPARATOR NM_BARLABEL +#define LBS_ROWS 0 /* Renamed structures */ #define AnchorPathOld AnchorPath -- cgit v1.2.3