On 31/12/2007, Jonathan Gordon <[EMAIL PROTECTED]> wrote:
<snip>
Attached is a patch which should apply cleanly after applying the
viewports patch. compile the e200 sim and have a look at the
windowmanager plugin, its basically a simple example of what I was
talking about in the last email.
Its not perfect and needs more work, but I think it shows enough to at
least get some more discussion happening.
When you start the plugin you have the "status bar" at the top which
refreshes every 100 ticks and shows the counter to prove it. the green
part is where the "list" screens would go, thats only redrawn when it
needs to.
If you press Num-1 (power) the statusbar will disappear and the list
wil use the whole screen, but the list doesn't know anything about the
statusbar.. thats completely controlled by the WM.
lastly, press NUM-5 and a splash will come up which will either
disappear when you press any button (possibly a bug.. its because it
doesn't have a button function so the list gets the focus still, but
this can be fixed if this behaviour isn't wanted....) or after about
5s.
So, already with this simple example you remove one big annoyance in
the current code that each screen has to manually redraw the
statusbar, and know about the other stuff on the screen.
Now, targets without a suitable screen (or when some define isnt
defined) the plugin is pretty much the extent of how the code would
look in the core, so you only ever have one screen and the statusbar,
and they take up the full screen. But on the rest, we can go nuts and
allow stuff like having the menu screen have the status bar at the
top, menu in the middle, AA on the right and track info at the bottom
(example.....)
does my first post make slightly more sense with this patch?
Jonathan
Index: CATEGORIES
===================================================================
--- CATEGORIES (revision 15984)
+++ CATEGORIES (working copy)
@@ -90,6 +91,7 @@
wavplay,viewers
wavrecord,apps
wavview,viewers
+windowmanager,demos
wormlet,games
xobox,games
zxbox,viewers
Index: windowmanager.c
===================================================================
--- windowmanager.c (revision 0)
+++ windowmanager.c (revision 0)
@@ -0,0 +1,289 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: helloworld.c 12807 2007-03-16 21:56:08Z amiconn $
+ *
+ * Copyright (C) 2002 Bj�rn Stenberg
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "plugin.h"
+
+PLUGIN_HEADER
+
+#define MAX_WINDOWS 8
+#define WINDOW_BUTTON_TIMEOUT HZ/5
+enum return_codes {
+ Redraw_Window = -1,
+ Status_OK = 1,
+};
+
+struct Window {
+ struct viewport vp;
+// struct screen *display;
+
+ void *data;
+ void (*draw_func)(struct viewport *vp,/* struct screen *display, */void *data);
+ int (*button_func)(void *data);
+
+ int refresh_ticks; /* # of ticks minimum between redraws, -1 means no refresh */
+ unsigned last_refresh;
+ bool force_refresh;
+};
+
+static struct Window *window_stack[MAX_WINDOWS];
+static int stacktop = 0;
+
+static struct plugin_api* rb;
+
+void push_window(struct Window *w)
+{
+ /* maybe check to make sure each window can only be there once? */
+ if (stacktop < MAX_WINDOWS)
+ {
+ window_stack[stacktop++] = w;
+ w->draw_func(&w->vp, /*w->display,*/ w->data);
+ w->last_refresh = *rb->current_tick;
+ w->force_refresh = false;
+ }
+}
+
+void remove_window(struct Window *w)
+{
+ int i;
+ bool found = false;
+ for (i=0; i<stacktop; i++)
+ {
+ if (w == window_stack[i] || found)
+ {
+ window_stack[i] = window_stack[i+1];
+ }
+ }
+ stacktop--;
+ /* redraw all windows in case the removed one overlapped */
+ for (i=0; i<stacktop; i++)
+ {
+ w = window_stack[i];
+ w->draw_func(&w->vp,/* w->display,*/ w->data);
+ w->last_refresh = *rb->current_tick;
+ w->force_refresh = false;
+ }
+}
+
+void main_loop(void)
+{
+ int i, ret;
+ struct Window *w;
+ while (1)
+ {
+ if (!stacktop)
+ rb->yield();
+ /* redraw windows */
+ for (i=0; i<stacktop; i++)
+ {
+ w = window_stack[i];
+ if (w->force_refresh ||
+ (w->refresh_ticks != -1 &&
+ TIME_AFTER(*rb->current_tick,
+ w->last_refresh + w->refresh_ticks)))
+ {
+ w->draw_func(&w->vp,/* w->display,*/ w->data);
+ w->last_refresh = *rb->current_tick;
+ w->force_refresh = false;
+ }
+ }
+ /* find the top-mos window which acepts input */
+ i = stacktop-1;
+ while (i>=0 && window_stack[i]->button_func == NULL)
+ i--;
+ w = window_stack[i];
+ if (w->button_func)
+ {
+ ret = w->button_func(w->data);
+ switch (ret)
+ {
+ /* proper return codes will be added */
+ case Redraw_Window:
+ w->force_refresh = true;
+ break;
+ default:
+ rb->sleep(ret);
+ }
+ }
+ }
+}
+
+/* SPLASH */
+void draw_splash(struct viewport *vp, /*struct screen *display,*/ void *data);
+static int remove_splash = 0;
+struct Window splash = {
+{
+ .x = 2,
+ .y = (LCD_HEIGHT-30)/2,
+ .width = LCD_WIDTH-4,
+ .height = 30,
+ .font = FONT_UI,
+ .drawmode = DRMODE_SOLID,
+ .xmargin = 0,
+ .ymargin = 0,
+#if LCD_DEPTH > 1
+ .fg_pattern = LCD_DEFAULT_FG,
+ .bg_pattern = LCD_RGBPACK(255,0,0),
+#ifdef HAVE_LCD_COLOR
+ .lss_pattern = LCD_DEFAULT_BG,
+ .lse_pattern = LCD_DEFAULT_BG,
+ .lst_pattern = LCD_DEFAULT_BG,
+#endif
+#endif
+}, /*NULL,*/ &remove_splash, draw_splash,NULL, 5*HZ, 0, false};
+void draw_splash(struct viewport *vp, /*struct screen *display,*/ void *data)
+{
+ if (*(int*)data)
+ {
+ remove_window(&splash);
+ }
+ else
+ {
+ int *remove = (int*)data;
+ *remove = 1;
+ rb->lcd_set_viewport(vp);
+ rb->lcd_clear_display();
+ rb->lcd_puts_scroll(0,0,"Surprise!!!!");
+ rb->lcd_update_rect(vp->x, vp->y, vp->width, vp->height);
+ /* Restore the default viewport */
+ rb->lcd_set_viewport(NULL);
+ }
+}
+void show_splash(void)
+{
+ remove_splash = 0;
+ push_window(&splash);
+}
+/* "status bar" section */
+
+void draw_statusbar(struct viewport *vp, /*struct screen *display,*/ void *data)
+{
+ char msg[128];
+ rb->lcd_set_viewport(vp);
+ rb->lcd_clear_display();
+ rb->snprintf(msg, 128, "Statusbar: %d", *rb->current_tick);
+ rb->lcd_puts_scroll(0,0,msg);
+ rb->lcd_puts_scroll(0,1,"refresh every sec or so");
+ rb->lcd_update_rect(vp->x, vp->y, vp->width, vp->height);
+ /* Restore the default viewport */
+ rb->lcd_set_viewport(NULL);
+}
+struct Window statusbar = {
+{
+ .x = 2,
+ .y = 2,
+ .width = LCD_WIDTH-4,
+ .height = 20,
+ .font = FONT_UI,
+ .drawmode = DRMODE_SOLID,
+ .xmargin = 0,
+ .ymargin = 0,
+#if LCD_DEPTH > 1
+ .fg_pattern = LCD_DEFAULT_FG,
+ .bg_pattern = LCD_RGBPACK(255,255,0),
+#ifdef HAVE_LCD_COLOR
+ .lss_pattern = LCD_DEFAULT_BG,
+ .lse_pattern = LCD_DEFAULT_BG,
+ .lst_pattern = LCD_DEFAULT_BG,
+#endif
+#endif
+}, /*NULL,*/ NULL, draw_statusbar,NULL, HZ, 0, false};
+
+/* browser/menu section */
+void draw_list(struct viewport *vp, /*struct screen *display,*/ void *data)
+{
+ char msg[128];
+ rb->lcd_set_viewport(vp);
+ rb->lcd_clear_display();
+ rb->snprintf(msg, 128, "List.. right pressed %d times", *(int*)data);
+ rb->lcd_puts_scroll(0,0,msg);
+ rb->lcd_puts_scroll(0,1,"refresh when >> pressed");
+ rb->lcd_puts_scroll(0,2,"press SELECT to pop up a splash");
+ rb->lcd_puts_scroll(0,3," which stays for 5 sec");
+ rb->lcd_update_rect(vp->x, vp->y, vp->width, vp->height);
+ /* Restore the default viewport */
+ rb->lcd_set_viewport(NULL);
+}
+
+int button_list(void *data)
+{
+ int button = rb->button_get_w_tmo(WINDOW_BUTTON_TIMEOUT);
+ int *count = (int*)data;
+ if (button & BUTTON_RIGHT)
+ {
+ (*count)++;
+ return Redraw_Window;
+ }
+ else if (button == BUTTON_SELECT)
+ {
+ show_splash();
+ }
+ else if (button == BUTTON_POWER)
+ {
+ toggle_statusbar();
+ return Redraw_Window;
+ }
+ return Status_OK;
+}
+static int up_count = 0;
+struct Window list = {
+{
+ .x = 2,
+ .y = 22,
+ .width = LCD_WIDTH-4,
+ .height = LCD_HEIGHT-24,
+ .font = FONT_UI,
+ .drawmode = DRMODE_SOLID,
+ .xmargin = 0,
+ .ymargin = 0,
+#if LCD_DEPTH > 1
+ .fg_pattern = LCD_DEFAULT_FG,
+ .bg_pattern = LCD_RGBPACK(0xab,255,0xcd),
+#ifdef HAVE_LCD_COLOR
+ .lss_pattern = LCD_DEFAULT_BG,
+ .lse_pattern = LCD_DEFAULT_BG,
+ .lst_pattern = LCD_DEFAULT_BG,
+#endif
+#endif
+}, /*NULL,*/ &up_count, draw_list,button_list, -1, 0, false};
+void toggle_statusbar(void)
+{
+ static bool is_visible = true;
+ is_visible = !is_visible;
+ if (is_visible)
+ {
+ list.vp.height = LCD_HEIGHT-24;
+ list.vp.y = 22;
+ push_window(&statusbar);
+ }
+ else
+ {
+ list.vp.height = LCD_HEIGHT-4;
+ list.vp.y = 2;
+ remove_window(&statusbar);
+ }
+}
+/* this is the plugin entry point */
+enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+{
+ (void)parameter;
+ rb = api;
+ push_window(&statusbar);
+ push_window(&list);
+ main_loop();
+ return PLUGIN_OK;
+}
Index: SOURCES
===================================================================
--- SOURCES (revision 15984)
+++ SOURCES (working copy)
@@ -7,6 +8,7 @@
firmware_flash.c
jackpot.c
logo.c
+windowmanager.c
mosaique.c
properties.c
random_folder_advance_config.c