From: John Hodge Date: Mon, 18 Feb 2013 13:02:09 +0000 (+0800) Subject: Usermode/AxWin3 - Decorator resize and close, misc fixes X-Git-Tag: rel0.15~562 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=9f005838b3165a84f6ed2a6cb6336be8ec9920d4;p=tpg%2Facess2.git Usermode/AxWin3 - Decorator resize and close, misc fixes --- diff --git a/Usermode/Applications/axwin3_src/WM/decorator.c b/Usermode/Applications/axwin3_src/WM/decorator.c index d30eadcc..d0dd2640 100644 --- a/Usermode/Applications/axwin3_src/WM/decorator.c +++ b/Usermode/Applications/axwin3_src/WM/decorator.c @@ -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; } diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index 4bb753ee..51692a64 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -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; diff --git a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c index c62dd7f5..a72cac3f 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c @@ -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; diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index 1de599b3..cc9d81d0 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -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) {