AxWin3_Widget_SetSize(ele, 4);
// > Version/Time
- ele = AxWin3_Widget_AddWidget(gSidebarRoot, ELETYPE_BOX, ELEFLAG_VERTICAL|ELEFLAG_NOSTRETCH, "Version/Time");
+ ele = AxWin3_Widget_AddWidget(gSidebarRoot, ELETYPE_BOX, ELEFLAG_VERTICAL|ELEFLAG_ALIGN_CENTER|ELEFLAG_NOSTRETCH, "Version/Time");
txt = AxWin3_Widget_AddWidget(ele, ELETYPE_TEXT, ELEFLAG_NOSTRETCH, "Version String");
AxWin3_Widget_SetSize(txt, 20);
AxWin3_Widget_SetText(txt, "3.0");
_SysDebug("TODO: Launch text editor");
}
+void mainmenu_app_terminal(void *unused)
+{
+ _SysDebug("TODO: Launch terminal emulator");
+}
+
void mainmenu_run_dialog(void *unused)
{
AxWin3_ShowWindow(gRunDialog, 1);
gSystemMenu = AxWin3_Menu_Create(NULL);
AxWin3_Menu_AddItem(gSystemMenu, "Text &Editor\tWin+E", mainmenu_app_textedit, NULL, 0, NULL);
+ AxWin3_Menu_AddItem(gSystemMenu, "Terminal Emulator\tWin+T", mainmenu_app_terminal, NULL, 0, NULL);
AxWin3_Menu_AddItem(gSystemMenu, NULL, NULL, NULL, 0, NULL);
AxWin3_Menu_AddItem(gSystemMenu, "Run\tWin+R", mainmenu_run_dialog, NULL, 0, NULL);
}
OBJ += renderers/background.o
OBJ += renderers/menu.o
# TODO: Move to a lower makefile
-OBJ += renderers/widget.o renderers/widget/widget_decorator.o
+OBJ += renderers/widget.o
OBJ += renderers/widget/button.o
OBJ += renderers/widget/image.o
OBJ += renderers/widget/disptext.o
#include <decorator.h>
#include <wm_messages.h>
+// === IMPORTS ===
+extern tWindow *gpWM_FocusedWindow;
+
// === PROTOTYPES ===
void Decorator_UpdateBorderSize(tWindow *Window);
void Decorator_Redraw(tWindow *Window);
int Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data);
// === CONSTANTS ===
-tColour cColourActive_Titlebar = 0xFF8800;
+tColour cColourActive_Titlebar = 0x00CC44;
tColour cColourActive_TitleText = 0x000000;
tColour cColourInactive_Titlebar = 0xD0D0D0;
tColour cColourInactive_TitleText= 0x000000;
tColour cColour_TitleTopBorder = 0xFFFFFF;
-tColour cColour_SideBorder = 0xD0D0D0;
-tColour cColour_BottomBorder = 0xD0D0D0;
+tColour cColour_SideBorder = 0x008000;
+tColour cColour_BottomBorder = 0x008000;
int ciTitlebarHeight = 18;
int ciSideBorderWidth = 2;
int ciBottomBorderWidth = 4;
// === CODE ===
void Decorator_UpdateBorderSize(tWindow *Window)
{
- Window->BorderT = 0;
+ Window->BorderT = ciTitlebarHeight;
Window->BorderB = 0;
Window->BorderL = 0;
Window->BorderR = 0;
- Window->BorderT = ciTitlebarHeight;
if( Window->Flags & WINFLAG_MAXIMIZED )
return ;
+
+ _SysDebug("BorderL = %i", ciSideBorderWidth);
Window->BorderB = ciBottomBorderWidth;
Window->BorderR = ciSideBorderWidth;
void Decorator_Redraw(tWindow *Window)
{
- int bActive = 1;
+ int bActive;
int text_width, text_height;
- // TODO: Detect if window has focus
-
+ // TODO: This could possibly be expensive, but is there a better way?
+ {
+ tWindow *win;
+ for(win = gpWM_FocusedWindow; win; win = win->Owner)
+ {
+ if(win == Window) {
+ bActive = 1;
+ break;
+ }
+ }
+ }
+
// Draw title bar
WM_Render_FillRect(Window,
0, -ciTitlebarHeight, Window->W, ciTitlebarHeight,
// Bottom
WM_Render_FillRect(Window,
-ciSideBorderWidth, Window->H,
- ciSideBorderWidth*2+Window->W, ciBottomBorderWidth,
+ ciSideBorderWidth*2+Window->W, 1,
+ 0x000000
+ );
+ WM_Render_FillRect(Window,
+ -ciSideBorderWidth, Window->H+1,
+ ciSideBorderWidth*2+Window->W, ciBottomBorderWidth-1,
cColour_BottomBorder
);
}
struct sWidgetWin
{
tElement RootElement;
+
+ tElement *FocusedElement;
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
extern void Video_Update(void);
extern void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H);
+extern void Video_FillRect(int X, int Y, int W, int H, uint32_t Colour);
#endif
//! Don't decoratate even if root
#define WINFLAG_NODECORATE 0x00000002
//! Window takes up all of screen
-#define WINFLAG_MAXIMIZED 0x00000005
+#define WINFLAG_MAXIMIZED 0x00000004
//! Window contents are valid
#define WINFLAG_CLEAN 0x00000040
//! All child windows are un-changed
extern int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font, tColour Colour, const char *Text);
extern void WM_Render_GetTextDims(tFont *Font, const char *Text, int *W, int *H);
extern void WM_Render_DrawImage(tWindow *Window, int X, int Y, int W, int H, tImage *Image);
+extern void WM_Render_SetTextCursor(tWindow *Window, int X, int Y, int W, int H, tColour Colour);
// NOTE: Should really be elsewhere
extern tColour Video_AlphaBlend(tColour _orig, tColour _new, uint8_t _alpha);
#endif
struct sWindow
{
- tWindow *NextSibling;
- tWindow *PrevSibling;
+ tWindow *Owner;
// Render tree
tWindow *Parent;
tWindow *FirstChild;
tWindow *LastChild;
+ tWindow *NextSibling;
+ tWindow *PrevSibling;
tIPC_Client *Client;
uint32_t ID; //!< Client assigned ID
+
tWMRenderer *Renderer;
+ void *RendererInfo;
char *Title;
int Flags;
+ // Text Cursor
+ int CursorX, CursorY;
+ int CursorW, CursorH;
+
+ // Gutter sizes (cached from decorator)
int BorderL, BorderR;
int BorderT, BorderB;
- int RealW, RealH;
-
+ // Position and dimensions
int X, Y;
+ int RealW, RealH;
int W, H;
- void *RendererInfo;
-
void *RenderBuffer; //!< Cached copy of the rendered window
};
// Text
WM_Render_DrawText(Window,
- ciMenu_LeftPadding, y,
+ ciMenu_LeftPadding, y+1,
w, ciMenu_ItemHeight,
gMenu_Font,
cMenu_LabelColour,
if(item->UnderlineW)
{
WM_Render_FillRect(Window,
- ciMenu_LeftPadding + item->UnderlineX, y + ciMenu_FontHeight,
+ ciMenu_LeftPadding + item->UnderlineX, y + 1 + ciMenu_FontHeight,
item->UnderlineW, 1,
cMenu_LabelColour
);
void Renderer_Widget_Redraw(tWindow *Window)
{
tWidgetWin *info = Window->RendererInfo;
- WM_Render_FillRect(Window, 0, 0, 0xFFF, 0xFFF, info->RootElement.BackgroundColour);
+ WM_Render_FillRect(Window, 0, 0, Window->W, Window->H, info->RootElement.BackgroundColour);
Widget_UpdateDimensions(&info->RootElement);
Widget_UpdatePosition(&info->RootElement);
{
gaWM_WidgetTypes[Element->Type]->Render(Window, Element);
}
- else
- {
- Widget_Decorator_RenderWidget(Window, Element);
- }
for(child = Element->FirstChild; child; child = child->NextSibling)
{
if(w < child->MinW) w = child->MinW;
if(h < child->MinH) h = child->MinH;
- _SysDebug("Child %ix%i (min %ix%i)", w, h, child->MinW, child->MinH);
+// _SysDebug("Child %ix%i (min %ix%i)", w, h, child->MinW, child->MinH);
// Update the dimensions if they have changed
if( child->CachedW == w && child->CachedH == h )
#define TEXTINPUT_BACKGROUND 0xFFFFFF
#define TEXTINPUT_BORDER_OUT 0x404040
#define TEXTINPUT_BORDER_IN 0x808080
+#define TEXTINPUT_TEXT 0x000000
#endif
*
* renderer/widget/textinput.c
* - Single line text box
+ *
+ * TODO: Support Right-to-Left text
*/
#include <common.h>
#include "./common.h"
#include "./colours.h"
+struct sTextInputInfo
+{
+ int DrawOfs; // Byte offset for the leftmost character
+ int CursorXOfs; // Pixel offset of the cursor
+};
+
void Widget_TextInput_Render(tWindow *Window, tElement *Element)
{
- WM_Render_FillRect(
- Window,
+ struct sTextInputInfo *info = (void*)Element->Data;
+ struct sWidgetWin *wininfo = Window->RendererInfo;
+
+ WM_Render_FillRect(Window,
Element->CachedX, Element->CachedY,
Element->CachedW, Element->CachedH,
TEXTINPUT_BACKGROUND
);
- WM_Render_DrawRect(
- Window,
+ WM_Render_DrawRect(Window,
Element->CachedX, Element->CachedY,
Element->CachedW, Element->CachedH,
TEXTINPUT_BORDER_OUT
);
- WM_Render_DrawRect(
- Window,
+ WM_Render_DrawRect(Window,
Element->CachedX+1, Element->CachedY+1,
Element->CachedW-2, Element->CachedH-2,
TEXTINPUT_BORDER_IN
);
- // TODO: Cursor?
+
+ // Text
+ WM_Render_DrawText(Window,
+ Element->CachedX+2, Element->CachedY+2,
+ Element->CachedW-4, Element->CachedW-4,
+ NULL, TEXTINPUT_TEXT,
+ &Element->Text[info->DrawOfs]
+ );
+
+ // TODO: Determine if this element has focus
+ if( wininfo->FocusedElement == Element )
+ {
+ // TODO: Multiple Cursors
+ WM_Render_SetTextCursor(Window,
+ Element->CachedX+2+info->CursorXOfs,
+ Element->CachedY+2,
+ Element->CachedW-4, 1,
+ TEXTINPUT_TEXT
+ );
+ }
}
void Widget_TextInput_Init(tElement *Element)
{
+ struct sTextInputInfo *info;
int h;
// TODO: Select font correctly
Element->MinH = h;
Element->MinW = 4;
- _SysDebug("h = %i", h);
+ info = Element->Data = malloc(sizeof(*info));
+ info->DrawOfs = 0;
+ info->CursorXOfs = 0;
// No need to explicitly update parent min dims, as the AddElement routine does that
}
.Init = Widget_TextInput_Init
);
-
+++ /dev/null
-/*
- * Acess2 Window Manager v3
- * - By John Hodge (thePowersGang)
- *
- * renderer_widget_decorator.c
- * - Widget Decorator
- */
-#include <common.h>
-#include <wm.h>
-#include <renderer_widget.h>
-
-#include "./colours.h"
-
-// === 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
-// );
-
- 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)
- break;
-
- case ELETYPE_BUTTON: // Button
- break;
-
- // Text input field / Text Box
- case ELETYPE_TEXTINPUT:
- case ELETYPE_TEXTBOX:
- break;
-
- case ELETYPE_TEXT:
- break;
-
- case ELETYPE_IMAGE:
- break;
-
- default:
- _SysDebug(" ERROR: Unknown type %i", Element->Type);
- break;
- }
-}
void Video_Setup(void);
void Video_SetCursorPos(short X, short Y);
void Video_Update(void);
-void Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
-void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color);
+void Video_FillRect(int X, int Y, int W, int H, uint32_t Color);
// === GLOBALS ===
int giVideo_CursorX;
ioctl(giTerminalFD, TERM_IOCTL_GETSETCURSOR, &pos);
}
+void Video_FillRect(int X, int Y, int W, int H, uint32_t Colour)
+{
+ uint32_t *dest;
+ int i;
+
+ if(X < 0 || Y < 0) return;
+ if(W >= giScreenWidth) return;
+ if(H >= giScreenHeight) return;
+ if(X + W >= giScreenWidth) W = giScreenWidth - W;
+ if(Y + H >= giScreenHeight) W = giScreenHeight - H;
+
+ dest = gpScreenBuffer + Y * giScreenWidth + X;
+ while(H --)
+ {
+ for( i = W; W --; dest ++) *dest = Colour;
+ dest += giScreenWidth - W;
+ }
+}
+
/**
* \brief Blit an entire buffer to the screen
* \note Assumes Pitch = 4*W
tWindow *gpWM_RootWindow;
//! Window which will recieve the next keyboard event
tWindow *gpWM_FocusedWindow;
+//! Hilighted window (owner of the currently focused window)
+tWindow *gpWM_HilightedWindow;
// === CODE ===
void WM_Initialise(void)
if(renderer == NULL)
return NULL;
- if(!Parent)
- Parent = gpWM_RootWindow;
-
// - Call create window function
ret = renderer->CreateWindow(RendererArg);
ret->Client = Client;
ret->ID = ID;
ret->Parent = Parent;
+ if(!ret->Parent)
+ ret->Parent = gpWM_RootWindow;
+ ret->Owner = Parent;
ret->Renderer = renderer;
ret->Flags |= WINFLAG_CLEAN; // Needed to stop invaildate early exiting
// Append to parent
- if(Parent)
+ if(ret->Parent)
{
- if(Parent->LastChild)
- Parent->LastChild->NextSibling = ret;
+ if(ret->Parent->LastChild)
+ ret->Parent->LastChild->NextSibling = ret;
else
- Parent->FirstChild = ret;
- ret->PrevSibling = Parent->LastChild;
- Parent->LastChild = ret;
+ ret->Parent->FirstChild = ret;
+ ret->PrevSibling = ret->Parent->LastChild;
+ ret->Parent->LastChild = ret;
ret->NextSibling = NULL;
}
else
}
// Don't decorate child windows by default
- if(Parent != gpWM_RootWindow)
+ if(Parent)
{
ret->Flags |= WINFLAG_NODECORATE;
}
_msg.Val = 1;
WM_SendMessage(NULL, Destination, WNDMSG_FOCUS, sizeof(_msg), &_msg);
+ WM_Invalidate(gpWM_FocusedWindow);
+ WM_Invalidate(Destination);
gpWM_FocusedWindow = Destination;
+
+
+ // Get the owner of the focused window
+// while(Destination && Destination->Owner) Destination = Destination->Owner;
+// gpWM_HilightedWindow = Destination;
}
void WM_ShowWindow(tWindow *Window, int bShow)
{
- // Message window
struct sWndMsg_Bool _msg;
if( !!(Window->Flags & WINFLAG_SHOW) == bShow )
return ;
+ // Message window
_msg.Val = !!bShow;
WM_SendMessage(NULL, Window, WNDMSG_SHOW, sizeof(_msg), &_msg);
-
+
+ // Update the flag
if(bShow)
Window->Flags |= WINFLAG_SHOW;
- else {
+ else
+ {
Window->Flags &= ~WINFLAG_SHOW;
+
if( Window == gpWM_FocusedWindow )
WM_FocusWindow(Window->Parent);
- }
- // Just a little memory saving for large hidden windows
- if(Window->RenderBuffer) {
- free(Window->RenderBuffer);
- Window->RenderBuffer = NULL;
+
+ // Just a little memory saving for large hidden windows
+ if(Window->RenderBuffer) {
+ free(Window->RenderBuffer);
+ Window->RenderBuffer = NULL;
+ }
}
WM_Invalidate(Window);
void WM_Invalidate(tWindow *Window)
{
+ if(!Window) return ;
_SysDebug("Invalidating %p", Window);
// Don't invalidate twice (speedup)
// if( !(Window->Flags & WINFLAG_CLEAN) ) return;
// --- Rendering / Update
void WM_int_UpdateWindow(tWindow *Window)
{
- tWindow *child;
+ int bDecoratorRedraw = 0;
// Ignore hidden windows
if( !(Window->Flags & WINFLAG_SHOW) )
Decorator_UpdateBorderSize(Window);
Window->RealW = Window->BorderL + Window->W + Window->BorderR;
Window->RealH = Window->BorderT + Window->H + Window->BorderB;
- Decorator_Redraw(Window);
+ bDecoratorRedraw = 1;
}
else
{
// Process children
if( !(Window->Flags & WINFLAG_CHILDCLEAN) )
{
+ tWindow *child;
for( child = Window->FirstChild; child; child = child->NextSibling )
{
WM_int_UpdateWindow(child);
Window->Flags |= WINFLAG_CHILDCLEAN;
}
+ if( bDecoratorRedraw )
+ Decorator_Redraw(Window);
}
void WM_int_BlitWindow(tWindow *Window)
if( !(Window->Flags & WINFLAG_SHOW) )
return ;
- _SysDebug("Blit %p to (%i,%i) %ix%i", Window, Window->X, Window->Y, Window->RealW, Window->RealH);
+// _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);
+ if( Window == gpWM_FocusedWindow && Window->CursorW )
+ {
+ Video_FillRect(
+ Window->X + Window->BorderL + Window->CursorX,
+ Window->Y + Window->BorderT + Window->CursorY,
+ Window->CursorW, Window->CursorH,
+ 0x000000
+ );
+
+ }
+
for( child = Window->FirstChild; child; child = child->NextSibling )
{
WM_int_BlitWindow(child);
{
for( i = W; i --; )
*dest++ = Colour;
- dest += Window->W - W;
+ dest += Window->RealW - W;
}
}
}
}
+void WM_Render_SetTextCursor(tWindow *Window, int X, int Y, int W, int H, tColour Colour)
+{
+ if( X < 0 || Y < 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;
+
+ Window->CursorX = X;
+ Window->CursorY = Y;
+ Window->CursorW = W;
+ Window->CursorH = H;
+}
+