Usermode/AxWin3 - Decorator resize and close, misc fixes
authorJohn Hodge <[email protected]>
Mon, 18 Feb 2013 13:02:09 +0000 (21:02 +0800)
committerJohn Hodge <[email protected]>
Mon, 18 Feb 2013 13:02:09 +0000 (21:02 +0800)
Usermode/Applications/axwin3_src/WM/decorator.c
Usermode/Applications/axwin3_src/WM/ipc.c
Usermode/Applications/axwin3_src/WM/renderers/richtext.c
Usermode/Applications/axwin3_src/WM/wm.c

index d30eadc..d0dd264 100644 (file)
@@ -19,6 +19,8 @@ void  Decorator_Redraw(tWindow *Window);
  int   Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data);
 
 // === CONSTANTS ===
+#define BTN_CLOSE(win) win->W-16, -16, 14, 14
+#define BTN_MIN(win)   win->W-32, -16, 14, 14
 tColour        cColourActive_Titlebar   = 0x00CC44;
 tColour        cColourActive_TitleText  = 0x000000;
 tColour        cColourInactive_Titlebar = 0xD0D0D0;
@@ -26,6 +28,7 @@ tColour       cColourInactive_TitleText= 0x000000;
 tColour        cColour_TitleTopBorder   = 0xFFFFFF;
 tColour        cColour_SideBorder       = 0x008000;
 tColour        cColour_BottomBorder     = 0x008000;
+tColour        cColour_CloseBtn         = 0xFF1100;
  int   ciTitlebarHeight        = 18;
  int   ciSideBorderWidth       = 2;
  int   ciBottomBorderWidth     = 4;
@@ -131,38 +134,124 @@ void Decorator_Redraw(tWindow *Window)
                );
        
        // Buttons
+       WM_Render_FillRect(Window, BTN_CLOSE(Window), cColour_CloseBtn);
        // TODO: Conditional for each
 }
 
+static inline int Decorator_INT_CoordInRange(int X, int Y, int SX, int SY, int EX, int EY)
+{
+       _SysDebug("(%i<=%i<%i, %i<=%i<%i", SX, X, EX, SY, Y, EY);
+       return (X >= SX && X < EX && Y >= SY && Y < EY);
+}
+static inline int Decorator_INT_CoordInRangeR(int X, int Y, int SX, int SY, int W, int H)
+{
+       return Decorator_INT_CoordInRange(X, Y, SX, SY, SX+W, SY+H);
+}
+
 int Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data)
 {
        static tWindow  *btn1_down;
+       static enum {
+               BTN1_MOVE,
+               BTN1_RLEFT,
+               BTN1_RRIGHT,
+               BTN1_RBOTTOM,
+       } btn1_mode;
        switch(Message)
        {
        case WNDMSG_MOUSEMOVE: {
                const struct sWndMsg_MouseMove  *msg = Data;
 
-               if( btn1_down == Window ) {
-                       WM_MoveWindow(Window, Window->X + msg->dX, Window->Y + msg->dY);
+               if( btn1_down == Window )
+               {
+                       switch(btn1_mode)
+                       {
+                       case BTN1_MOVE: // Move
+                               WM_MoveWindow(Window, Window->X + msg->dX, Window->Y + msg->dY);
+                               break;
+                       case BTN1_RLEFT:        // Resize left
+                               if( Window->W + msg->dX > 50 )
+                               {
+                                       WM_MoveWindow(Window, Window->X + msg->dX, Window->Y);
+                                       WM_ResizeWindow(Window, Window->W - msg->dX, Window->H);
+                               }
+                               break;
+                       case BTN1_RRIGHT:       // Resize right
+                               if( Window->W + msg->dX > 50 )
+                               {
+                                       WM_ResizeWindow(Window, Window->W + msg->dX, Window->H);
+                               }
+                               break;
+                       case BTN1_RBOTTOM:      // Resize bottom
+                               if( Window->H + msg->dY > 50 )
+                               {
+                                       WM_ResizeWindow(Window, Window->W, Window->H + msg->dY);
+                               }
+                               break;
+                       }
                        return 0;
                }
 
+               // TODO: Change cursor when hovering over edges
+
                if(msg->Y >= 0) return 1;       // Pass
 
                // TODO: Handle
                return 0; }
        case WNDMSG_MOUSEBTN: {
                const struct sWndMsg_MouseButton        *msg = Data;
-               if( msg->Button == 0 && !msg->bPressed )
+               
+               // TODO: Do something with other buttons
+               // - Window menu for example
+               if( msg->Button != 0 )
+                       return 1;       // pass on
+
+               if( !msg->bPressed )
                        btn1_down = 0;          
 
-               if(msg->Y >= 0) return 1;       // Pass
-       
-               if( msg->Button == 0 && msg->bPressed )
+               #define HOTSPOTR(x,y,w,h) Decorator_INT_CoordInRangeR(msg->X, msg->Y, x, y, w, h)
+               #define HOTSPOTA(sx,sy,ex,ey) Decorator_INT_CoordInRange(msg->X, msg->Y, sx, sy, ew, eh)
+               // Left resize border
+               if( msg->bPressed && HOTSPOTR(-ciSideBorderWidth, -ciTitlebarHeight,
+                               ciSideBorderWidth, ciTitlebarHeight+Window->H+ciBottomBorderWidth) )
+               {
                        btn1_down = Window;
+                       btn1_mode = BTN1_RLEFT;
+                       return 0;
+               }
+               // Right resize border
+               if( msg->bPressed && HOTSPOTR(Window->W, -ciTitlebarHeight,
+                       ciSideBorderWidth, ciTitlebarHeight+Window->H+ciBottomBorderWidth) )
+               {
+                       btn1_down = Window;
+                       btn1_mode = BTN1_RRIGHT;
+                       return 0;
+               }
+               // Bottom resize border
+               if( msg->bPressed && HOTSPOTR(0, Window->H,
+                       Window->W, ciTitlebarHeight) )
+               {
+                       btn1_down = Window;
+                       btn1_mode = BTN1_RBOTTOM;
+                       return 0;
+               }
+               // Titlebar buttons
+               if( msg->bPressed && Decorator_INT_CoordInRangeR(msg->X, msg->Y, BTN_CLOSE(Window)) )
+               {
+                       WM_SendMessage(NULL, Window, WNDMSG_CLOSE, 0, NULL);
+                       return 0;
+               }
+               // Titlebar - Move
+               if( msg->bPressed && msg->Y < 0 )
+               {
+                       btn1_down = Window;
+                       btn1_mode = BTN1_MOVE;
+                       return 0;
+               }
+               #undef HOTSPOTR
+               #undef HOTSPOTA
 
-               // TODO: Handle
-               return 0; }
+               return 1; }
        default:        // Anything unhandled is passed on
                return 1;
        }
index 4bb753e..51692a6 100644 (file)
@@ -168,7 +168,10 @@ int _CompareClientPtrs(const void *_a, const void *_b)
 {
        tIPC_Client     *a = *(tIPC_Client**)_a;
        tIPC_Client     *b = *(tIPC_Client**)_b;
-       
+
+       ASSERT(a);
+       ASSERT(b);
+
        if(a->IPCType < b->IPCType)     return -1;
        if(a->IPCType > b->IPCType)     return 1;
        
index c62dd7f..a72cac3 100644 (file)
@@ -43,6 +43,7 @@ typedef struct sRichText_Window
 // === PROTOTYPES ===
  int   Renderer_RichText_Init(void);
 tWindow        *Renderer_RichText_Create(int Flags);
+void   Renderer_RichText_Destroy(tWindow *Window);
 void   Renderer_RichText_Redraw(tWindow *Window);
  int   Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data);
  int   Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const void *Data);
@@ -52,6 +53,7 @@ void  Renderer_RichText_Redraw(tWindow *Window);
 tWMRenderer    gRenderer_RichText = {
        .Name = "RichText",
        .CreateWindow   = Renderer_RichText_Create,
+       .DestroyWindow  = Renderer_RichText_Destroy,
        .Redraw         = Renderer_RichText_Redraw,
        .HandleMessage  = Renderer_RichText_HandleMessage,
        .nIPCHandlers = N_IPC_RICHTEXT,
@@ -83,6 +85,23 @@ tWindow *Renderer_RichText_Create(int Flags)
        return ret;
 }
 
+void Renderer_RichText_Destroy(tWindow *Window)
+{
+       tRichText_Window        *info = ret->RendererInfo;
+
+       // TODO: Is locking needed? WM_Destroy should have taken us off the render tree
+       while( info->FirstLine )
+       {
+               tRichText_Line *line = info->FirstLine;
+               info->FirstLine = line->Next;
+
+               free(line);
+       }
+
+       if( info->Font )
+               _SysDebug("RichText_Destroy - TODO: Free font");
+}
+
 static inline int Renderer_RichText_RenderText_Act(tWindow *Window, tRichText_Window *info, int X, int Row, const char *Text, int Bytes, tColour FG, tColour BG, int Flags)
 {
         int    rwidth;
index 1de599b..cc9d81d 100644 (file)
@@ -117,13 +117,15 @@ void WM_DestroyWindow(tWindow *Window)
        // - Remove from inheritance tree?
        
        // - Clean up render children
-       // Lock should not be needed
-       tWindow *win, *next;
-       for( win = Window->FirstChild; win; win = next )
        {
-               next = win->NextSibling;
-               ASSERT(Window->FirstChild->Parent == Window);
-               WM_DestroyWindow(win);
+               // Lock should not be needed
+               tWindow *win, *next;
+               for( win = Window->FirstChild; win; win = next )
+               {
+                       next = win->NextSibling;
+                       ASSERT(Window->FirstChild->Parent == Window);
+                       WM_DestroyWindow(win);
+               }
        }
        
        // - Clean up inheriting children?
@@ -133,7 +135,10 @@ void WM_DestroyWindow(tWindow *Window)
                Window->Renderer->DestroyWindow(Window);
        else
                _SysDebug("WARN: Renderer %s does not have a destroy function", Window->Renderer->Name);
-       
+
+       // - Tell client to clean up
+       WM_SendMessage(NULL, Window, WNDMSG_DESTROY, 0, NULL);
+
        // - Clean up render cache and window structure
        free(Window->Title);
        free(Window->RenderBuffer);
@@ -356,7 +361,7 @@ int WM_ResizeWindow(tWindow *Window, int W, int H)
        if( Window->W == W && Window->H == H )
                return 0;
 
-       _SysDebug("WM_Resizeindow: %ix%i", W, H);
+       _SysDebug("WM_ResizeWindow: %ix%i", W, H);
        Window->W = W;  Window->H = H;
 
        if(Window->RenderBuffer) {

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