Amiga: Implement a simple listbrowser log in the GUI

Can be revealed/hidden with F12 and is currently undocumented.
This commit is contained in:
Chris Young 2019-08-10 14:29:58 +01:00
parent 78199c0177
commit bf9ccc57c8
4 changed files with 282 additions and 8 deletions

View File

@ -72,6 +72,7 @@
#include <proto/clicktab.h>
#include <proto/label.h>
#include <proto/layout.h>
#include <proto/listbrowser.h>
#include <proto/scroller.h>
#include <proto/space.h>
#include <proto/speedbar.h>
@ -83,6 +84,7 @@
#include <gadgets/chooser.h>
#include <gadgets/clicktab.h>
#include <gadgets/layout.h>
#include <gadgets/listbrowser.h>
#include <gadgets/scroller.h>
#include <gadgets/space.h>
#include <gadgets/speedbar.h>
@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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