#include <axwin3/menu.h>
#define SIDEBAR_WIDTH 36
+#define RUN_WIDTH 200
+#define RUN_HEIGHT 70
// === PROTOTYPES ===
void create_sidebar(void);
void create_mainmenu(void);
+void create_run_dialog(void);
// === GLOBALS ===
tHWND gSidebar;
-tHWND gSystemMenu;
tAxWin3_Widget *gSidebarRoot;
+tHWND gSystemMenu;
+tHWND gRunDialog;
+tAxWin3_Widget *gRunInput;
int giScreenWidth;
int giScreenHeight;
{
// Connect to AxWin3 Server
AxWin3_Connect(NULL);
+
+ // TODO: Register to be told when the display layout changes
+ AxWin3_GetDisplayDims(0, NULL, NULL, &giScreenWidth, &giScreenHeight);
create_sidebar();
create_mainmenu();
+ create_run_dialog();
// Idle loop
AxWin3_MainLoop();
{
tAxWin3_Widget *btn, *txt, *ele;
- // TODO: Register to be told when the display layout changes
- AxWin3_GetDisplayDims(0, NULL, NULL, &giScreenWidth, &giScreenHeight);
-
// Create sidebar
gSidebar = AxWin3_Widget_CreateWindow(NULL, SIDEBAR_WIDTH, giScreenHeight, ELEFLAG_VERTICAL);
AxWin3_MoveWindow(gSidebar, 0, 0);
AxWin3_Widget_SetSize(txt, 20);
AxWin3_Widget_SetText(txt, "3.0");
+ // Turn off decorations
+ AxWin3_DecorateWindow(gSidebar, 0);
+
// Show!
AxWin3_ShowWindow(gSidebar, 1);
void mainmenu_run_dialog(void *unused)
{
_SysDebug("TODO: Show run dialog");
+ AxWin3_ShowWindow(gRunDialog, 1);
}
void create_mainmenu(void)
AxWin3_Menu_AddItem(gSystemMenu, "Run\tWin+R", mainmenu_run_dialog, NULL, 0, NULL);
}
+int run_dorun(tAxWin3_Widget *unused)
+{
+// char *cmd = AxWin3_Widget_GetText(gRunInput);
+ AxWin3_ShowWindow(gRunDialog, 0);
+ return 0;
+}
+
+int run_close(tAxWin3_Widget *unused)
+{
+ AxWin3_ShowWindow(gRunDialog, 0);
+ return 0;
+}
+
+tAxWin3_Widget *make_textbutton(tAxWin3_Widget *Parent, const char *Label, tAxWin3_Widget_FireCb handler)
+{
+ tAxWin3_Widget *ret, *txt;
+ ret = AxWin3_Widget_AddWidget(Parent, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, "_btn");
+ AxWin3_Widget_SetFireHandler(ret, handler);
+ txt = AxWin3_Widget_AddWidget(ret, ELETYPE_TEXT, 0, "_txt");
+ AxWin3_Widget_SetText(ret, Label);
+ return ret;
+}
+
+void create_run_dialog(void)
+{
+ tAxWin3_Widget *root, *box, *ele;
+
+ gRunDialog = AxWin3_Widget_CreateWindow(NULL, RUN_WIDTH, RUN_HEIGHT, ELEFLAG_VERTICAL);
+ AxWin3_SetWindowTitle(gRunDialog, "Run Program...");
+
+ AxWin3_MoveWindow(gRunDialog, giScreenWidth/2-RUN_WIDTH/2, giScreenHeight/2-RUN_HEIGHT/2);
+ root = AxWin3_Widget_GetRoot(gRunDialog);
+
+ gRunInput = AxWin3_Widget_AddWidget(root, ELETYPE_TEXTINPUT, 0, "Input");
+ AxWin3_Widget_SetFireHandler(gRunInput, run_dorun);
+
+ box = AxWin3_Widget_AddWidget(root, ELETYPE_BOX, ELEFLAG_ALIGN_CENTER|ELEFLAG_NOSTRETCH, "Button Area");
+ ele = make_textbutton(box, "Ok", run_dorun);
+ ele = make_textbutton(box, "Cancel", run_close);
+}
+
BIN := AxWinWM
OBJ := main.o input.o video.o ipc.o image.o
OBJ += wm.o wm_input.o wm_render.o wm_render_text.o
-OBJ += renderer_classes.o renderer_passthru.o renderer_background.o
+OBJ += decorator.o
+OBJ += renderer_passthru.o
+OBJ += renderer_background.o
OBJ += renderer_widget.o renderer_widget_decorator.o
OBJ += renderer_menu.o
--- /dev/null
+/*
+ * Acess2 Window Manager v3 (axwin3)
+ * - By John Hodge (thePowersGang)
+ *
+ * decorator.c
+ * - Window Decorator
+ */
+#include <common.h>
+#include <wm.h>
+#include <decorator.h>
+
+// === PROTOTYPES ===
+void Decorator_UpdateBorderSize(tWindow *Window);
+void Decorator_Redraw(tWindow *Window);
+ int Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data);
+
+// === CONSTANTS ===
+tColour cColourActive_Titlebar = 0xFF8800;
+tColour cColourActive_TitleText = 0x000000;
+tColour cColourInactive_Titlebar = 0xD0D0D0;
+tColour cColourInactive_TitleText= 0x000000;
+tColour cColour_SideBorder = 0xD0D0D0;
+tColour cColour_BottomBorder = 0xD0D0D0;
+ int ciTitlebarHeight = 18;
+ int ciSideBorderWidth = 2;
+ int ciBottomBorderWidth = 4;
+
+// === CODE ===
+void Decorator_UpdateBorderSize(tWindow *Window)
+{
+ Window->BorderT = 0;
+ Window->BorderB = 0;
+ Window->BorderL = 0;
+ Window->BorderR = 0;
+
+ Window->BorderT = ciTitlebarHeight;
+ if( Window->Flags & WINFLAG_MAXIMIZED )
+ return ;
+
+ Window->BorderB = ciBottomBorderWidth;
+ Window->BorderR = ciSideBorderWidth;
+ Window->BorderL = ciSideBorderWidth;
+}
+
+void Decorator_Redraw(tWindow *Window)
+{
+ int bActive = 1;
+ int text_width, text_height;
+
+ // TODO: Detect if window has focus
+
+ // Draw title bar
+ WM_Render_FillRect(Window,
+ 0, -ciTitlebarHeight, Window->W, ciTitlebarHeight,
+ (bActive ? cColourActive_Titlebar : cColourInactive_Titlebar)
+ );
+
+ WM_Render_GetTextDims(
+ NULL, // TODO: Select font
+ Window->Title ? Window->Title : "jI",
+ &text_width, &text_height
+ );
+ WM_Render_DrawText(Window,
+ ciTitlebarHeight + 4, -(ciTitlebarHeight - (ciTitlebarHeight/2 - text_height/2)),
+ Window->W - ciTitlebarHeight - 4, text_height,
+ NULL, // TODO: Select font
+ (bActive ? cColourActive_TitleText : cColourInactive_TitleText),
+ Window->Title ? Window->Title : "--"
+ );
+
+ // Maximized windows don't have any other borders
+ if( Window->Flags & WINFLAG_MAXIMIZED )
+ return ;
+
+ // Left
+ WM_Render_FillRect(Window,
+ -ciSideBorderWidth, -ciTitlebarHeight,
+ ciSideBorderWidth, Window->H + ciTitlebarHeight + ciBottomBorderWidth,
+ cColour_SideBorder
+ );
+ // Right
+ WM_Render_FillRect(Window,
+ Window->W, -ciTitlebarHeight,
+ ciSideBorderWidth, Window->H + ciTitlebarHeight + ciBottomBorderWidth,
+ cColour_SideBorder
+ );
+ // Bottom
+ WM_Render_FillRect(Window,
+ -ciSideBorderWidth, Window->H,
+ ciSideBorderWidth*2+Window->W, ciBottomBorderWidth,
+ cColour_BottomBorder
+ );
+}
+
+int Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data)
+{
+ switch(Message)
+ {
+ default: // Anything unhandled is passed on
+ return 1;
+ }
+}
+
--- /dev/null
+/*
+ * Acess2 Window Manager v3 (axwin3)
+ * - By John Hodge (thePowersGang)
+ *
+ * include/decorator.h
+ * - Decorator definitions
+ */
+#ifndef _DECORATOR_H_
+#define _DECORATOR_H_
+
+#include <wm_internals.h>
+
+extern void Decorator_UpdateBorderSize(tWindow *Window);
+extern void Decorator_Redraw(tWindow *Window);
+extern int Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data);
+
+#endif
+
#ifndef _WM_H_
#define _WM_H_
+#include <stdint.h>
+#include <stdlib.h>
+
#include "image.h"
// === CONSTANTS ===
*/
//! Render the window
#define WINFLAG_SHOW 0x00000001
-//! Window isn't contained within the parent/owner
-#define WINFLAG_NONNESTED 0x00000002
+//! Don't decoratate even if root
+#define WINFLAG_NODECORATE 0x00000002
+//! Window takes up all of screen
+#define WINFLAG_MAXIMIZED 0x00000005
//! Window contents are valid
#define WINFLAG_CLEAN 0x00000040
//! All child windows are un-changed
// --- Management
extern tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int Flags, const char *Renderer);
extern void WM_Invalidate(tWindow *Window);
+extern void WM_SetWindowTitle(tWindow *Window, const char *Title);
extern void WM_FocusWindow(tWindow *Destination);
extern void WM_RaiseWindow(tWindow *Window);
extern void WM_ShowWindow(tWindow *Window, int bShow);
+extern void WM_DecorateWindow(tWindow *Window, int bDecorate);
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 *Source, tWindow *Dest, int MessageID, int Length, void *Data);
uint32_t ID; //!< Client assigned ID
tWMRenderer *Renderer;
+ char *Title;
+
int Flags;
-
- int X;
- int Y;
- int W;
- int H;
+
+ int BorderL, BorderR;
+ int BorderT, BorderB;
+
+ int RealW, RealH;
+
+ int X, Y;
+ int W, H;
void *RendererInfo;
return 0;
}
+int IPC_Msg_SetWindowTitle(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
+{
+ tWindow *win;
+
+ if( Msg->Size < 1 ) return -1;
+ if( Msg->Data[ Msg->Size-1 ] != '\0' ) return -1;
+
+ win = IPC_int_GetWindow(Client, Msg->Window);
+ if(!win) return 1;
+
+ WM_SetWindowTitle(win, Msg->Data);
+
+ return 0;
+}
+
int IPC_Msg_ShowWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
{
- tIPCMsg_ShowWindow *info = (void*)Msg->Data;
+ tIPCMsg_Boolean *info = (void*)Msg->Data;
tWindow *win;
if( Msg->Size < sizeof(*info) ) return -1;
win = IPC_int_GetWindow(Client, Msg->Window);
if(!win) return 1;
- WM_ShowWindow(win, !!info->bShow);
+ WM_ShowWindow(win, !!info->Value);
+
+ return 0;
+}
+
+int IPC_Msg_DecorateWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
+{
+ tIPCMsg_Boolean *info = (void*)Msg->Data;
+ tWindow *win;
+ if( Msg->Size < sizeof(*info) ) return -1;
+
+ win = IPC_int_GetWindow(Client, Msg->Window);
+ if(!win) return 1;
+
+ WM_DecorateWindow(win, !!info->Value);
return 0;
}
_SysDebug(" IPC_Handle: IPCMSG_CREATEWIN");
rv = IPC_Msg_CreateWin(client, Msg);
break;
+ // TODO: Destroy window
+
+ // --- Set window title
+ case IPCMSG_SETWINTITLE:
+ _SysDebug(" IPC_Handle: IPCMSG_SETWINTITLE");
+ rv = IPC_Msg_SetWindowTitle(client, Msg);
+ break;
+
// --- Give a window focus
case IPCMSG_FOCUSWINDOW:
_SysDebug(" IPC_Handle: IPCMSG_FOCUSWINDOW");
_SysDebug(" IPC_Handle: IPCMSG_SHOWWINDOW");
rv = IPC_Msg_ShowWindow(client, Msg);
break;
+ case IPCMSG_DECORATEWINDOW:
+ _SysDebug(" IPC_Handle: IPCMSG_DECORATEWINDOW");
+ rv = IPC_Msg_DecorateWindow(client, Msg);
+ break;
// --- Move/Resize a window
case IPCMSG_SETWINPOS:
_SysDebug(" IPC_Handle: IPCMSG_SETWINPOS");
info->MaxItems = Argument;
info->HilightedItem = -1;
- _SysDebug("Renderer_Menu_Create: ->MaxItems = %i", info->MaxItems);
+ ret->Flags |= WINFLAG_NODECORATE;
+ ret->H = ciMenu_TopPadding + ciMenu_BottomPadding;
+
+// _SysDebug("Renderer_Menu_Create: ->MaxItems = %i", info->MaxItems);
return ret;
}
int w, h, y, i;
w = info->CachedW;
+ #if 0
h = ciMenu_TopPadding + ciMenu_BottomPadding;
for( i = 0; i < info->nItems; i ++ )
{
else
h += ciMenu_SpacerHeight;
}
+ #else
+ h = Window->H;
+ #endif
// _SysDebug("w = %i, h = %i", w, h);
- // - Resize window to contain all items
- WM_ResizeWindow(Window, w, h);
-
// - Move the window such that it is on screen
// > Make sure to catch if the menu can't fit fully onscreen
}
// Don't overwrite
- if(info->Items[req->ID]) return 0;
+ if(info->Items[req->ID]) {
+ _SysDebug("- Caught overwrite of %i", req->ID);
+ return 0;
+ }
// Bookkeeping
if(req->ID >= info->nItems) info->nItems = req->ID + 1;
// Allocate
{
// Spacer
item->Label = NULL;
+ WM_ResizeWindow(Window, info->CachedW, Window->H+ciMenu_SpacerHeight);
return 0;
}
info->CachedW = ciMenu_LeftPadding + info->MaxLabelWidth
+ ciMenu_Gap + info->MaxShortcutWidth
+ ciMenu_RightPadding;
- // TODO: Smarter height?
- // Doesn't matter a lot here really
- WM_ResizeWindow(Window, info->CachedW, info->nItems*ciMenu_ItemHeight);
}
+ WM_ResizeWindow(Window, info->CachedW, Window->H+ciMenu_ItemHeight);
return 0;
}
// Manipulation messages
case MSG_MENU_ADDITEM:
- _SysDebug("MSG_MENU_ADDITEM");
+// _SysDebug("MSG_MENU_ADDITEM");
return Renderer_Menu_int_AddItem(Window, Length, Data);
// Only message to pass to client
void Widget_SetText(tWidgetWin *Info, int Len, tWidgetMsg_SetText *Msg);
int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data);
// --- Type helpers
-void Widget_TextBox_UpdateText(tElement *Element, const char *Text);
+void Widget_DispText_UpdateText(tElement *Element, const char *Text);
void Widget_Image_UpdateText(tElement *Element, const char *Text);
int Widget_Button_MouseButton(tElement *Element, int X, int Y, int Button, int bPress);
+void Widget_TextInput_Init(tElement *Element);
// === GLOBALS ===
tWMRenderer gRenderer_Widget = {
} gaWM_WidgetTypes[NUM_ELETYPES] = {
{0}, // NULL
{0}, // Box
- {.UpdateText = Widget_TextBox_UpdateText}, // Text
+ {.UpdateText = Widget_DispText_UpdateText}, // Text
{.UpdateText = Widget_Image_UpdateText}, // Image
- {.MouseButton = Widget_Button_MouseButton} // Button
+ {.MouseButton = Widget_Button_MouseButton}, // Button
+ {0}, // Spacer
+ {.Init = Widget_TextInput_Init}, // Text Box (Single Line)
};
const int ciWM_NumWidgetTypes = sizeof(gaWM_WidgetTypes)/sizeof(gaWM_WidgetTypes[0]);
}
// --- Type Helpers
-void Widget_TextBox_UpdateText(tElement *Element, const char *Text)
+void Widget_DispText_UpdateText(tElement *Element, const char *Text)
{
int w=0, h=0;
return 0; // Handled
}
+void Widget_TextInput_Init(tElement *Element)
+{
+ int h;
+
+ // TODO: Select font correctly
+ WM_Render_GetTextDims(NULL, "jJ", NULL, &h);
+
+ if( Element->Parent && (Element->Parent->Flags & ELEFLAG_VERTICAL) )
+ Element->MinWith = h;
+ else
+ Element->MinCross = h;
+
+ // No need to explicitly update parent min dims, as the AddElement routine does that
+}
+
#define BUTTON_BGCOLOUR 0xD0D0D0
#define BUTTON_BORDER 0xF0F0F0
#define TEXT_COLOUR 0x000000
+#define TEXTINPUT_BACKGROUND 0xFFFFFF
+#define TEXTINPUT_BORDER_OUT 0x404040
// === CODE ===
void Widget_Decorator_RenderWidget(tWindow *Window, tElement *Element)
BUTTON_BORDER
);
break;
+
+ // Text input field / Text Box
+ case ELETYPE_TEXTINPUT:
+ case ELETYPE_TEXTBOX:
+ WM_Render_FillRect(
+ Window,
+ Element->CachedX, Element->CachedY,
+ Element->CachedW, Element->CachedH,
+ TEXTINPUT_BACKGROUND
+ );
+ WM_Render_DrawRect(
+ Window,
+ Element->CachedX, Element->CachedY,
+ Element->CachedW, Element->CachedH,
+ TEXTINPUT_BORDER_OUT
+ );
+// WM_Render_DrawRect(
+// Window,
+// Element->CachedX+1, Element->CachedY+1,
+// Element->CachedW-2, Element->CachedH-2,
+// TEXTINPUT_BORDER_IN
+// );
+ break;
case ELETYPE_TEXT:
WM_Render_DrawText(
#include <string.h>
#include <video.h>
#include <wm_messages.h>
+#include <decorator.h>
// === IMPORTS ===
extern void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int Msg, int Len, void *Data);
WM_CreateWindow(NULL, NULL, 0, 0x0088FF, "Background");
gpWM_RootWindow->W = giScreenWidth;
gpWM_RootWindow->H = giScreenHeight;
- gpWM_RootWindow->Flags = WINFLAG_SHOW;
+ gpWM_RootWindow->Flags = WINFLAG_SHOW|WINFLAG_NODECORATE;
}
void WM_RegisterRenderer(tWMRenderer *Renderer)
ret->ID = ID;
ret->Parent = Parent;
ret->Renderer = renderer;
- ret->Flags = WINFLAG_CLEAN; // Needed to stop invaildate early exiting
+ ret->Flags |= WINFLAG_CLEAN; // Needed to stop invaildate early exiting
// Append to parent
if(Parent)
gpWM_RootWindow = ret;
}
+ // Don't decorate child windows by default
+ if(Parent != gpWM_RootWindow)
+ {
+ ret->Flags |= WINFLAG_NODECORATE;
+ }
+
// - Return!
return ret;
}
return ret;
}
+void WM_SetWindowTitle(tWindow *Window, const char *Title)
+{
+ if(Window->Title)
+ free(Window->Title);
+ Window->Title = strdup(Title);
+ _SysDebug("Window %p title set to '%s'", Window, Title);
+}
+
void WM_RaiseWindow(tWindow *Window)
{
tWindow *parent = Window->Parent;
if( Window == gpWM_FocusedWindow )
WM_FocusWindow(Window->Parent);
}
+ // Just a little memory saving for large hidden windows
+ if(Window->RenderBuffer)
+ free(Window->RenderBuffer);
+
+ WM_Invalidate(Window);
+}
+
+void WM_DecorateWindow(tWindow *Window, int bDecorate)
+{
+ if( !(Window->Flags & WINFLAG_NODECORATE) == !!bDecorate )
+ return ;
+
+ if(bDecorate)
+ Window->Flags &= ~WINFLAG_NODECORATE;
+ else
+ Window->Flags |= WINFLAG_NODECORATE;
+
+ // Needed because the window size changes
+ if(Window->RenderBuffer)
+ free(Window->RenderBuffer);
+
WM_Invalidate(Window);
}
if(W <= 0 || H <= 0 ) return 1;
if(Window->X + W < 0) Window->X = -W + 1;
if(Window->Y + H < 0) Window->Y = -H + 1;
-
+
Window->W = W; Window->H = H;
+ if(Window->RenderBuffer)
+ free(Window->RenderBuffer);
WM_Invalidate(Window);
{
// Render
if( !(Window->Flags & WINFLAG_CLEAN) )
{
+ // Calculate RealW/RealH
+ if( !(Window->Flags & WINFLAG_NODECORATE) )
+ {
+ _SysDebug("Applying decorations to %p", Window);
+ Decorator_UpdateBorderSize(Window);
+ Window->RealW = Window->BorderL + Window->W + Window->BorderR;
+ Window->RealH = Window->BorderT + Window->H + Window->BorderB;
+ Decorator_Redraw(Window);
+ }
+ else
+ {
+ Window->BorderL = 0;
+ Window->BorderR = 0;
+ Window->BorderT = 0;
+ Window->BorderB = 0;
+ Window->RealW = Window->W;
+ Window->RealH = Window->H;
+ }
+
Window->Renderer->Redraw(Window);
Window->Flags |= WINFLAG_CLEAN;
}
if( !(Window->Flags & WINFLAG_SHOW) )
return ;
- _SysDebug("Blit %p to (%i,%i) %ix%i", Window, Window->X, Window->Y, Window->W, Window->H);
- Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->W, Window->H);
+ _SysDebug("Blit %p to (%i,%i) %ix%i", Window, Window->X, Window->Y, Window->RealW, Window->RealH);
+ Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->RealW, Window->RealH);
for( child = Window->FirstChild; child; child = child->NextSibling )
{
{
uint32_t *dest;
int i;
-// _SysDebug("WM_Render_FilledRect(%p, 0x%x...", Window, Colour);
-// _SysDebug(" (%i,%i), %ix%i)", X, Y, W, H);
+
+ X += Window->BorderL;
+ Y += Window->BorderT;
+
// Clip to window dimensions
if(X < 0) { W += X; X = 0; }
if(Y < 0) { H += Y; Y = 0; }
if(W <= 0 || H <= 0) return;
- if(X >= Window->W) return;
- if(Y >= Window->H) return;
- if(X + W > Window->W) W = Window->W - X;
- if(Y + H > Window->H) H = Window->H - Y;
-// _SysDebug(" Clipped to (%i,%i), %ix%i", X, Y, W, H);
+ if(X >= Window->RealW) return;
+ if(Y >= Window->RealH) return;
+ if(X + W > Window->RealW) W = Window->RealW - X;
+ if(Y + H > Window->RealH) H = Window->RealH - Y;
+
+ // TODO: Catch overflow into decorator area
if(!Window->RenderBuffer) {
- Window->RenderBuffer = malloc(Window->W*Window->H*4);
+ Window->RenderBuffer = malloc(Window->RealW*Window->RealH*4);
}
- dest = (uint32_t*)Window->RenderBuffer + Y*Window->W + X;
+ dest = (uint32_t*)Window->RenderBuffer + Y*Window->RealW + X;
while( H -- )
{
for( i = W; i --; )
if(!Window->RenderBuffer) {
Window->RenderBuffer = malloc(Window->W*Window->H*4);
}
-
+
+ // Apply offset
+ X += Window->BorderL;
+ Y += Window->BorderT;
+
// Bounds Check
- if( X >= Window->W ) return ;
- if( Y >= Window->H ) return ;
+ if( X >= Window->RealW ) return ;
+ if( Y >= Window->RealH ) 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;
+ if( X + W > Window->RealW ) W = Window->RealW - X;
+ if( Y + H > Window->RealH ) H = Window->RealH - Y;
+
+ // TODO: Catch overflow into decorator area
+ #if 0
+ if( !Window->bDrawingDecorations )
+ {
+ if( X < Window->BorderL ) return ;
+ if( Y < Window->BorderT ) return ;
+ if( X + W > Window->BorderL + Window->W ) W = X - (Window->BorderL + Window->W);
+ if( Y + H > Window->BorderT + Window->H ) H = Y - (Window->BorderT + Window->H);
+ }
+ #endif
- dest = (uint32_t*)Window->RenderBuffer + Y * Window->W + X;
+ dest = (uint32_t*)Window->RenderBuffer + Y * Window->RealW + X;
data = Image->Data;
// Do the render
dest[x] = b | (g << 8) | (r << 16);
}
data += Image->Width * 4;
- dest += Window->W;
+ dest += Window->RealW;
}
break;
dest[x] = data[x*3+2] | (data[x*3+1] << 8) | (data[x*3+0] << 16);
}
data += W * 3;
- dest += Window->W;
+ dest += Window->RealW;
}
break;
default:
if(!Text) return 0;
+
+ X += Window->BorderL;
+ Y += Window->BorderT;
+
// Check the bounds
- if(W < 0 || X < 0 || X >= Window->W) return 0;
- if(X + W > Window->W) W = Window->W - X;
+ if(W < 0 || X < 0 || X >= Window->RealW) return 0;
+ if(X + W > Window->RealW) W = Window->RealW - X;
- if(H < 0 || Y < 0 || Y >= Window->H) return 0;
- if(Y + H > Window->H) H = Window->H - Y;
+ if(H < 0 || Y < 0 || Y >= Window->RealH) return 0;
+ if(Y + H > Window->RealH) H = Window->RealH - Y;
+ // TODO: Catch trampling of decorations
+
// Handle NULL font (system default monospace)
if( !Font ) Font = &gSystemFont;
}
// _SysDebug("X = %i, Y = %i", X, Y);
- outBuf = (uint32_t*)Window->RenderBuffer + Y*Window->W + X;
+ outBuf = (uint32_t*)Window->RenderBuffer + Y*Window->RealW + X;
inBuf = Glyph->Bitmap + yStart*Glyph->TrueWidth;
for( y = yStart; y < Glyph->TrueHeight; y ++ )
{
outBuf[dst_x] = Video_AlphaBlend( outBuf[dst_x], Color, inBuf[x] );
}
- outBuf += Window->W;
+ outBuf += Window->RealW;
inBuf += Glyph->TrueWidth;
}
}
typedef struct sAxWin_IPCMessage tAxWin_IPCMessage;
typedef struct sIPCMsg_ReturnInt tIPCMsg_ReturnInt;
typedef struct sIPCMsg_CreateWin tIPCMsg_CreateWin;
-typedef struct sIPCMsg_ShowWindow tIPCMsg_ShowWindow;
+typedef struct sIPCMsg_Boolean tIPCMsg_Boolean;
typedef struct sIPCMsg_SetWindowPos tIPCMsg_SetWindowPos;
typedef struct sIPCMsg_SendMsg tIPCMsg_SendMsg;
char Data[];
};
-struct sIPCMsg_ShowWindow
+struct sIPCMsg_Boolean
{
- uint32_t bShow;
+ uint32_t Value;
};
struct sIPCMsg_SetWindowPos
IPCMSG_SENDMSG, //!< Send a message to another window (or to self)
IPCMSG_CREATEWIN, //!< Create a window
IPCMSG_DESTROYWIN, //!< Destroy a window
+ IPCMSG_SETWINTITLE, //!< Set window title
IPCMSG_SHOWWINDOW, //!< Show/Hide a window
+ IPCMSG_DECORATEWINDOW, //!< Enable/Disable decorations
IPCMSG_FOCUSWINDOW, //!< Give a window focus (no data)
IPCMSG_SETWINPOS, //!< Set a window position
};
#include <stdint.h>
+extern void _SysDebug(const char *Fmt, ...);
+
struct sAxWin3_Window
{
uint32_t ServerID;
}
}
+void AxWin3_SetWindowTitle(tHWND Window, const char *Title)
+{
+ tAxWin_IPCMessage *msg;
+ int len = strlen(Title);
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINTITLE, 0, len+1);
+ strcpy(msg->Data, Title);
+
+ AxWin3_int_SendIPCMessage(msg);
+
+ free(msg);
+}
+
void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length, void *Data)
{
tAxWin_IPCMessage *msg;
void AxWin3_ShowWindow(tHWND Window, int bShow)
{
tAxWin_IPCMessage *msg;
- tIPCMsg_ShowWindow *info;
+ tIPCMsg_Boolean *info;
msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SHOWWINDOW, 0, sizeof(*info));
info = (void*)msg->Data;
- info->bShow = !!bShow;
+ info->Value = !!bShow;
+
+ AxWin3_int_SendIPCMessage(msg);
+
+ free(msg);
+}
+
+void AxWin3_DecorateWindow(tHWND Window, int bDecorate)
+{
+ tAxWin_IPCMessage *msg;
+ tIPCMsg_Boolean *info;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DECORATEWINDOW, 0, sizeof(*info));
+ info = (void*)msg->Data;
+ info->Value = !!bDecorate;
AxWin3_int_SendIPCMessage(msg);
#ifndef _AXWIN3_AXWIN_H_
#define _AXWIN3_AXWIN_H_
+// === CONSTANTS ===
+
+// === TYPES ===
typedef struct sAxWin3_Window *tHWND;
typedef unsigned int tAxWin3_Colour; // TODO: Actual 32-bit
// --- Core window management functions
extern void AxWin3_SendMessage(tHWND Window, tHWND Dest, int Message, int Length, void *Data);
+extern void AxWin3_SetWindowTitle(tHWND Window, const char *Title);
extern void AxWin3_FocusWindow(tHWND Window);
extern void AxWin3_ShowWindow(tHWND Window, int bShow);
+extern void AxWin3_DecorateWindow(tHWND Window, int bDecorate);
extern void AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H);
extern void AxWin3_MoveWindow(tHWND Window, short X, short Y);
extern void AxWin3_ResizeWindow(tHWND Window, short W, short H);
ELETYPE_IMAGE, //!< Image
ELETYPE_BUTTON, //!< Push Button
ELETYPE_SPACER, //!< Visual Spacer (horizontal / vertical rule)
+ ELETYPE_TEXTINPUT, //!< Text Input Field
+ ELETYPE_TEXTBOX, //!< Text Box Input
ELETYPE_TABBAR, //!< Tab Bar
ELETYPE_TOOLBAR, //!< Tool Bar