Usermode/AxWin3 - Adding decorator to widget renderer
authorJohn Hodge <[email protected]>
Sat, 5 Nov 2011 09:44:44 +0000 (17:44 +0800)
committerJohn Hodge <[email protected]>
Sat, 5 Nov 2011 09:44:44 +0000 (17:44 +0800)
TODO: Implement inter-window messaging, needed to get the new size
 for the element calculations

Usermode/Applications/axwin3_src/WM/Makefile
Usermode/Applications/axwin3_src/WM/include/renderer_widget.h
Usermode/Applications/axwin3_src/WM/include/wm.h
Usermode/Applications/axwin3_src/WM/include/wm_messages.h
Usermode/Applications/axwin3_src/WM/renderer_background.c
Usermode/Applications/axwin3_src/WM/renderer_classes.c
Usermode/Applications/axwin3_src/WM/renderer_widget.c
Usermode/Applications/axwin3_src/WM/renderer_widget_decorator.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/wm.c

index 5afff6f..8354413 100644 (file)
@@ -8,7 +8,8 @@ DIR := Apps/AxWin/3.0
 BIN := AxWinWM
 OBJ := main.o wm.o input.o video.o ipc.o
 OBJ += messageio.o
-OBJ += renderer_classes.o renderer_passthru.o renderer_widget.o renderer_background.o
+OBJ += renderer_classes.o renderer_passthru.o renderer_background.o
+OBJ += renderer_widget.o renderer_widget_decorator.o
 
 LDFLAGS += -limage_sif -luri -lnet
 
index 35b767d..700540d 100644 (file)
 
 #include <widget_messages.h>
 
+// === TYPES ===
+typedef struct sWidgetWin      tWidgetWin;
+typedef struct sAxWin_Element  tElement;
+
+// === STRUCTURES ===
+struct sAxWin_Element
+{
+       enum eElementTypes      Type;
+
+       uint32_t        ID;     //!< Application provided ID number
+       tElement        *ListNext;      //!< Next element in bucket
+       
+       // Element Tree
+       tElement        *Parent;
+       tElement        *FirstChild;
+       tElement        *LastChild;
+       tElement        *NextSibling;
+       
+       // User modifiable attributes   
+       short   PaddingL, PaddingR;
+       short   PaddingT, PaddingB;
+       short   GapSize;
+       
+       uint32_t        Flags;
+       
+       short   FixedWith;      //!< Fixed lengthways Size attribute (height)
+       short   FixedCross;     //!< Fixed Cross Size attribute (width)
+       
+       tColour BackgroundColour;
+
+       char    *Text;
+       
+       // -- Attributes maitained by the element code
+       // Not touched by the user
+       short   MinWith;        //!< Minimum long size
+       short   MinCross;       //!< Minimum cross size
+       void    *Data;  //!< Per-type data
+       
+       // -- Render Cache
+       short   CachedX, CachedY;
+       short   CachedW, CachedH;
+       
+       char    DebugName[];
+};
+struct sWidgetWin
+{
+       tElement        RootElement;
+       
+        int    TableSize;      //!< Number of entries, anything over will wrap
+       tElement        *ElementTable[];        //!< Hash table essentially
+};
+
+// === FUNCTIONS === 
+extern void    Widget_Decorator_RenderWidget(tWindow *Window, tElement *Element);
+
 #endif
 
index 2766c68..a96061e 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _WM_H_
 #define _WM_H_
 
+#include <image.h>
+
 // === CONSTANTS ===
 /**
  * \brief Window Flags
@@ -40,7 +42,10 @@ extern int   WM_ResizeWindow(tWindow *Window, int W, int H);
 extern int     WM_MoveWindow(tWindow *Window, int X, int Y);
 extern int     WM_SendMessage(tWindow *Window, int MessageID, int Length, void *Data);
 // --- Rendering
-extern void    WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W, int H);
+extern void    WM_Render_FillRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour);
+extern void    WM_Render_DrawRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour);
+extern void    WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, void *Font, tColour Colour, const char *Text);
+extern void    WM_Render_DrawImage(tWindow *Window, int X, int Y, int W, int H, tImage *Image);
 
 #endif
 
index 0bebfda..d37097f 100644 (file)
@@ -8,6 +8,9 @@
 #ifndef _WM_MESSAGES_H_
 #define _WM_MESSAGES_H_
 
+/**
+ * \brief Messages delivered to windows
+ */
 enum eWM_WindowMessages
 {
        WNDMSG_NULL,
@@ -16,6 +19,8 @@ enum eWM_WindowMessages
        WNDMSG_DESTROY,
        WNDMSG_FOCUS,   // Called on change
        WNDMSG_SHOW,    // Called on change
+
+       WNDMSG_RESIZE,
        
        WNDMSG_MOUSEMOVE,
        WNDMSG_MOUSEBTN,
@@ -27,4 +32,9 @@ enum eWM_WindowMessages
        WNDMSG_CLASS_MAX = 0x2000,
 };
 
+struct sWndMsg_Resize
+{
+       uint16_t        W, H;
+};
+
 #endif
index df28c83..7772cdd 100644 (file)
@@ -51,7 +51,7 @@ void Renderer_Background_Redraw(tWindow *Window)
 {
        struct sBgWin   *info = Window->RendererInfo;
        
-       WM_Render_FilledRect(Window, info->Colour, 0, 0, 0xFFFF, 0xFFFF);
+       WM_Render_FillRect(Window, 0, 0, 0xFFFF, 0xFFFF, info->Colour);
 }
 
 int Renderer_Background_HandleMessage(tWindow *Target, int Msg, int Len, void *Data)
index 439adaa..4b0f3c6 100644 (file)
@@ -44,7 +44,7 @@ tWindow       *Renderer_Class_Create(int Flags)
 void Renderer_Class_Redraw(tWindow *Window)
 {
        tClassfulInfo   *info = Window->RendererInfo;
-       WM_Render_FilledRect(Window, info->BGColour, 0, 0, Window->W, Window->H);
+       WM_Render_FillRect(Window, 0, 0, Window->W, Window->H, info->BGColour);
 }
 
 int Renderer_Class_HandleMessage(tWindow *Target, int Msg, int Len, void *Data)
index 3fbe3cb..00debed 100644 (file)
 #include <renderer_widget.h>
 #include <string.h>
 
-// === TYPES ===
-typedef struct sWidgetWin      tWidgetWin;
-typedef struct sAxWin_Element  tElement;
-
-// === STRUCTURES ===
-struct sAxWin_Element
-{
-       enum eElementTypes      Type;
-
-       uint32_t        ID;     //!< Application provided ID number
-       tElement        *ListNext;      //!< Next element in bucket
-       
-       // Element Tree
-       tElement        *Parent;
-       tElement        *FirstChild;
-       tElement        *LastChild;
-       tElement        *NextSibling;
-       
-       // User modifiable attributes   
-       short   PaddingL, PaddingR;
-       short   PaddingT, PaddingB;
-       short   GapSize;
-       
-       uint32_t        Flags;
-       
-       short   FixedWith;      //!< Fixed lengthways Size attribute (height)
-       short   FixedCross;     //!< Fixed Cross Size attribute (width)
-       
-       tColour BackgroundColour;
-
-       char    *Text;
-       
-       // -- Attributes maitained by the element code
-       // Not touched by the user
-       short   MinWith;        //!< Minimum long size
-       short   MinCross;       //!< Minimum cross size
-       void    *Data;  //!< Per-type data
-       
-       // -- Render Cache
-       short   CachedX, CachedY;
-       short   CachedW, CachedH;
-       
-       char    DebugName[];
-};
-struct sWidgetWin
-{
-       tElement        RootElement;
-       
-        int    TableSize;      //!< Number of entries, anything over will wrap
-       tElement        *ElementTable[];        //!< Hash table essentially
-};
-
 // === PROTOTYPES ===
+ int   Renderer_Widget_Init(void);
 tWindow        *Renderer_Widget_Create(int Flags);
 void   Renderer_Widget_Redraw(tWindow *Window);
-int    Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data);
+void   Widget_RenderWidget(tWindow *Window, tElement *Element);
+ int   Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data);
+void   Widget_UpdateDimensions(tElement *Element);
+void   Widget_UpdatePosition(tElement *Element);
+tElement       *Widget_GetElementById(tWidgetWin *Info, uint32_t ID);
+void   Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg);
 
 // === GLOBALS ===
 tWMRenderer    gRenderer_Widget = {
@@ -98,10 +52,30 @@ tWindow     *Renderer_Widget_Create(int Flags)
 void Renderer_Widget_Redraw(tWindow *Window)
 {
        tWidgetWin      *info = Window->RendererInfo;
-       WM_Render_FilledRect(Window, info->RootElement.BackgroundColour, 0, 0, 0xFFF, 0xFFF);
+       WM_Render_FillRect(Window, 0, 0, 0xFFF, 0xFFF, info->RootElement.BackgroundColour);
+
+       Widget_UpdateDimensions(&info->RootElement);
+       Widget_UpdatePosition(&info->RootElement);
+
+       Widget_RenderWidget(Window, &info->RootElement);
 }
 
 // --- Render / Resize ---
+void Widget_RenderWidget(tWindow *Window, tElement *Element)
+{
+       tElement        *child;
+       
+       if( Element->Flags & ELEFLAG_NORENDER ) return ;
+       if( Element->Flags & ELEFLAG_INVISIBLE )        return ;
+       
+       Widget_Decorator_RenderWidget(Window, Element);
+       
+       for(child = Element->FirstChild; child; child = child->NextSibling)
+       {
+               Widget_RenderWidget(Window, child);
+       }
+}
+
 void Widget_UpdateDimensions(tElement *Element)
 {
        tElement        *child;
@@ -267,6 +241,9 @@ void Widget_UpdatePosition(tElement *Element)
 tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID)
 {
        tElement        *ele;
+
+       if(ID == -1)
+               return &Info->RootElement;
        
        if( ID < Info->TableSize )      return Info->ElementTable[ID];
 
@@ -297,6 +274,14 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data)
        tWidgetWin      *info = Target->RendererInfo;
        switch(Msg)
        {
+       case WNDMSG_RESIZE: {
+               struct sWndMsg_Resize   *msg = Data;
+               if(Len < sizeof(*msg))  return -1;              
+
+               info->RootElement.CachedW = msg->W;             
+               info->RootElement.CachedH = msg->H;
+               return 0; }
+
        // New Widget
        case MSG_WIDGET_CREATE:
                Widget_NewWidget(info, Len, Data);
diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget_decorator.c b/Usermode/Applications/axwin3_src/WM/renderer_widget_decorator.c
new file mode 100644 (file)
index 0000000..ec70a56
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ * 
+ * renderer_widget_decorator.c
+ * - Widget Decorator
+ */
+#include <common.h>
+#include <wm.h>
+#include <renderer_widget.h>
+
+#define BORDER_EVERYTHING      1
+
+#define BOX_BGCOLOUR    0xC0C0C0
+#define BOX_BORDER      0xA0A0A0
+#define BUTTON_BGCOLOUR 0xD0D0D0
+#define BUTTON_BORDER   0xF0F0F0
+#define        TEXT_COLOUR     0x000000
+
+// === CODE ===
+void Widget_Decorator_RenderWidget(tWindow *Window, tElement *Element)
+{
+       _SysDebug("Widget_Decorator_RenderWidget: (Element={Type:%i,(%i,%i) %ix%i})",
+               Element->Type,
+               Element->CachedX, Element->CachedY,
+               Element->CachedW, Element->CachedH
+               );
+       
+       #if BORDER_EVERYTHING
+       WM_Render_DrawRect(
+               Window,
+               Element->CachedX, Element->CachedY,
+               Element->CachedW, Element->CachedH,
+               0
+               );
+       #endif
+       
+       switch(Element->Type)
+       {
+       case ELETYPE_NONE:
+       case ELETYPE_BOX:       break;  // Box is a meta-element
+       
+       case ELETYPE_TABBAR:    // Tab Bar
+               WM_Render_DrawRect(
+                       Window,
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW, Element->CachedH,
+                       BOX_BORDER
+                       );
+               WM_Render_FillRect(
+                       Window,
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       BOX_BGCOLOUR
+                       );
+               // Enumerate Items.
+               break;
+       case ELETYPE_TOOLBAR:   // Tool Bar
+               WM_Render_DrawRect(
+                       Window,
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW, Element->CachedH,
+                       BOX_BORDER
+                       );
+               WM_Render_FillRect(
+                       Window,
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       BOX_BGCOLOUR
+                       );
+               break;
+       
+       case ELETYPE_SPACER:    // Spacer (subtle line)
+               WM_Render_FillRect(
+                       Window,
+                       Element->CachedX+3, Element->CachedY+3,
+                       Element->CachedW-6, Element->CachedH-6,
+                       BOX_BORDER
+                       );
+               break;
+       
+       case ELETYPE_BUTTON:    // Button
+               WM_Render_FillRect(
+                       Window,
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       BUTTON_BGCOLOUR
+                       );
+               WM_Render_DrawRect(
+                       Window,
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW-1, Element->CachedH-1,
+                       BUTTON_BORDER
+                       );
+               break;
+       
+       case ELETYPE_TEXT:
+               WM_Render_DrawText(
+                       Window,
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       NULL,
+                       TEXT_COLOUR,
+                       Element->Text
+                       );
+               break;
+       
+       case ELETYPE_IMAGE:
+               WM_Render_DrawImage(
+                       Window,
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW, Element->CachedH,
+                       Element->Data
+                       );
+               break;
+               
+       default:
+               _SysDebug(" ERROR: Unknown type %i", Element->Type);
+               break;
+       }
+}
index b40d1c6..eddd12d 100644 (file)
@@ -201,7 +201,7 @@ void WM_Update(void)
 
 // --- WM Render Routines
 // TODO: Move to another file?
-void WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W, int H)
+void WM_Render_FillRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour)
 {
        uint32_t        *dest;
         int    i;
@@ -232,3 +232,107 @@ void WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W,
        }
 }
 
+void WM_Render_DrawRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour)
+{      
+       WM_Render_FillRect(Window, X, Y, W, 1, Colour);
+       WM_Render_FillRect(Window, X, Y+H-1, W, 1, Colour);
+       WM_Render_FillRect(Window, X, Y, 1, H, Colour);
+       WM_Render_FillRect(Window, X+W-1, Y, 1, H, Colour);
+}
+
+void WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, void *Font, tColour Colour, const char *Text)
+{
+       // TODO: Implement
+}
+
+/**
+ * \brief Draw an image to the screen
+ * \todo Maybe have support for an offset in the image
+ */
+void WM_Render_DrawImage(tWindow *Window, int X, int Y, int W, int H, tImage *Image)
+{
+        int    x, y;
+       uint32_t        *dest;
+       uint8_t *data;
+       
+       // Sanity please
+       if( !Image )    return ;
+
+       // Allocate
+       if(!Window->RenderBuffer) {
+               Window->RenderBuffer = malloc(Window->W*Window->H*4);
+       }
+       
+       // Bounds Check
+       if( X >= Window->W )    return ;
+       if( Y >= Window->H )    return ;
+       
+       // Wrap to image size
+       if( W > Image->Width )  W = Image->Width;
+       if( H > Image->Height ) H = Image->Height;
+       
+       // Wrap to screen size
+       if( X + W > Window->W ) W = Window->W - X;
+       if( Y + H > Window->H ) H = Window->H - Y;
+
+       dest = (uint32_t*)Window->RenderBuffer + Y * Window->W + X;
+       data = Image->Data;
+
+       // Do the render
+       switch( Image->Format )
+       {
+       case IMGFMT_BGRA:
+               for( y = 0; y < H; y ++ )
+               {
+                        int    r, g, b, a;     // New
+                        int    or, og, ob;     // Original
+                       for( x = 0; x < W; x ++ )
+                       {
+                               b = data[x*4+0]; g = data[x*4+1]; r = data[x*4+2]; a = data[x*4+3];
+                               if( a == 0 )    continue;       // 100% transparent
+                               ob = dest[x]&0xFF; og = (dest[x] >> 8)&0xFF; or = (dest[x] >> 16)&0xFF;
+                               // Handle Alpha
+                               switch(a)
+                               {
+                               // Transparent: Handled above
+                               // Solid
+                               case 0xFF:      break;
+                               // Half
+                               case 0x80:
+                                       r = (or + r) / 2;
+                                       g = (og + g) / 2;
+                                       b = (ob + b) / 2;
+                                       break;
+                               // General
+                               default:
+                                       r = (or * (255-a) + r * a) / 255;
+                                       g = (og * (255-a) + g * a) / 255;
+                                       b = (ob * (255-a) + b * a) / 255;
+                                       break;
+                               }
+                               dest[x] = b | (g << 8) | (r << 16);
+                       }
+                       data += Image->Width * 4;
+                       dest += Window->W;
+               }
+               break;
+       
+       // RGB
+       case IMGFMT_RGB:
+               for( y = 0; y < H; y ++ )
+               {
+                       for( x = 0; x < W; x ++ )
+                       {
+                               //        Blue           Green                Red
+                               dest[x] = data[x*3+2] | (data[x*3+1] << 8) | (data[x*3+0] << 16);
+                       }
+                       data += W * 3;
+                       dest += Window->W;
+               }
+               break;
+       default:
+               _SysDebug("ERROR: Unknown image format %i\n", Image->Format);
+               break;
+       }
+}
+

UCC git Repository :: git.ucc.asn.au