ciSideBorderWidth*2+Window->W, ciBottomBorderWidth-1,
cColour_BottomBorder
);
+
+ // Buttons
+ // TODO: Conditional for each
}
int Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data)
// === FUNCTIONS ===
// --- Management
extern tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int Flags, const char *Renderer);
+extern void WM_DestroyWindow(tWindow *Window);
extern tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID);
extern void WM_Invalidate(tWindow *Window);
extern void WM_SetWindowTitle(tWindow *Window, const char *Title);
* set the copy in the window structure.
*/
tWindow *(*CreateWindow)(int Arg);
+
+ /**
+ * \brief Clean up any stored info
+ * \param Window Window being destroyed
+ */
+ void (*DestroyWindow)(tWindow *Window);
/**
* \brief Redraw a window on the screen
return 0;
}
+int IPC_Msg_DestroyWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
+{
+ tWindow *win;
+
+ ASSERT(Msg->ID == IPCMSG_DESTROYWIN);
+
+ win = IPC_int_GetWindow(Client, Msg->Window);
+ if( !win )
+ return 0;
+
+ WM_DestroyWindow(win);
+ return 0;
+}
+
int IPC_Msg_SetWindowTitle(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
{
tWindow *win;
IPC_Msg_GetDisplayDims,
IPC_Msg_SendMsg,
IPC_Msg_CreateWin,
- NULL, // Destroy window
+ IPC_Msg_DestroyWin, // Destroy window
IPC_Msg_SetWindowTitle,
IPC_Msg_ShowWindow,
IPC_Msg_DecorateWindow,
WM_Hotkey_Register(2, keys, "Interface>Run");
keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_t;
WM_Hotkey_Register(2, keys, "Interface>Terminal");
+ keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_e;
+ WM_Hotkey_Register(2, keys, "Interface>TextEdit");
// Spawn interface root
{
if( child->Flags & ELEFLAG_ABSOLUTEPOS ) continue ;
// --- Width ---
- if( child->Flags & ELEFLAG_NOEXPAND )
+ if( child->Flags & (bVertical ? ELEFLAG_NOEXPAND : ELEFLAG_NOSTRETCH) )
w = child->MinW;
else if( bVertical )
w = child->FixedCross ? child->FixedCross : fullCross;
w = child->FixedWith ? child->FixedWith : dynWith;
// --- Height ---
- if( child->Flags & ELEFLAG_NOSTRETCH )
+ if( child->Flags & (bVertical ? ELEFLAG_NOSTRETCH : ELEFLAG_NOEXPAND) )
h = child->MinH;
else if( bVertical )
h = child->FixedWith ? child->FixedWith : dynWith;
return ret;
}
+void WM_DestroyWindow(tWindow *Window)
+{
+ // TODO: Lock window and flag as invalid
+
+ // - Remove from render tree
+ {
+ // TODO: Lock render tree?
+ tWindow *prev = Window->PrevSibling;
+ tWindow *next = Window->NextSibling;
+ if(prev)
+ prev->NextSibling = next;
+ else
+ Window->Parent->FirstChild = next;
+ if(next)
+ next->PrevSibling = prev;
+ else
+ Window->Parent->LastChild = prev;
+ }
+ WM_Invalidate(Window->Parent);
+
+ // - 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);
+ }
+
+ // - Clean up inheriting children?
+
+ // - Tell renderer to clean up
+ if( Window->Renderer->DestroyWindow )
+ Window->Renderer->DestroyWindow(Window);
+ else
+ _SysDebug("WARN: Renderer %s does not have a destroy function", Window->Renderer->Name);
+
+ // - Clean up render cache and window structure
+ free(Window->Title);
+ free(Window->RenderBuffer);
+ free(Window);
+}
+
tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID)
{
return IPC_int_GetWindow(Requester->Client, ID);
#include "include/ipc.h"
#include <stdlib.h>
+// === GLOBALS ===
+int giAxWin3_MainLoopExit;
+
// === CODE ===
int SoMain(void *Base, int argc, const char *argv[], const char **envp)
{
return 0;
}
-void AxWin3_MainLoop(void)
+int AxWin3_MainLoop(void)
{
tAxWin_IPCMessage *msg;
- int bExit = 0;
- while(!bExit)
+ giAxWin3_MainLoopExit = 0;
+
+ while(!giAxWin3_MainLoopExit)
{
msg = AxWin3_int_GetIPCMessage(0, NULL);
if(!msg) continue;
AxWin3_int_HandleMessage( msg );
}
+ return giAxWin3_MainLoopExit;
+}
+
+void AxWin3_StopMainLoop(int Reason)
+{
+ giAxWin3_MainLoopExit = Reason;
}
void AxWin3_MessageSelect(int nFD, fd_set *FDs)
msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DESTROYWIN, 0, 0);
AxWin3_int_SendIPCMessage(msg);
free(msg);
+
+ free(ret);
}
void *AxWin3_int_GetDataPtr(tHWND Window)
}
}
break; }
+ case IPCMSG_DESTROYWIN:
+ // Clean up resources associated with this window
+ break;
default:
_SysDebug("Unknow message ID %i", Msg->ID);
break;
LDFLAGS += -laxwin3
-OBJ = main.o
+OBJ = main.o strings.o
BIN = ate
DIR := Apps/AxWin/3.0
int Toolbar_New(tAxWin3_Widget *Widget);
int Toolbar_Open(tAxWin3_Widget *Widget);
int Toolbar_Save(tAxWin3_Widget *Widget);
+ int Toolbar_Close(tAxWin3_Widget *Widget);
// === GLOBALS ===
tHWND gMainWindow;
// TODO: Populate menu
// Create toolbar
- gMainWindow_Toolbar = AxWin3_Widget_AddWidget(gMainWindow_Root, ELETYPE_TOOLBAR, ELEFLAG_NOSTRETCH, "Toolbar");
+ gMainWindow_Toolbar = AxWin3_Widget_AddWidget(gMainWindow_Root,
+ ELETYPE_TOOLBAR, ELEFLAG_NOSTRETCH, "Toolbar");
add_toolbar_button(gMainWindow_Toolbar, "BtnNew", Toolbar_New);
add_toolbar_button(gMainWindow_Toolbar, "BtnOpen", Toolbar_Open);
add_toolbar_button(gMainWindow_Toolbar, "BtnSave", Toolbar_Save);
- AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+ add_toolbar_button(gMainWindow_Toolbar, "BtnClose", Toolbar_Close);
+ AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "");
add_toolbar_button(gMainWindow_Toolbar, "BtnUndo", NULL);
add_toolbar_button(gMainWindow_Toolbar, "BtnRedo", NULL);
- AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+ AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "");
add_toolbar_button(gMainWindow_Toolbar, "BtnCut", NULL);
add_toolbar_button(gMainWindow_Toolbar, "BtnCopy", NULL);
add_toolbar_button(gMainWindow_Toolbar, "BtnPaste", NULL);
- AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+ AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "");
add_toolbar_button(gMainWindow_Toolbar, "BtnSearch", NULL);
add_toolbar_button(gMainWindow_Toolbar, "BtnReplace", NULL);
// Main loop
AxWin3_MainLoop();
+ AxWin3_DestroyWindow(gMainWindow);
+
return 0;
}
tAxWin3_Widget *btn = AxWin3_Widget_AddWidget(Toolbar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, Ident);
tAxWin3_Widget *txt = AxWin3_Widget_AddWidget(btn, ELETYPE_TEXT, 0, Ident);
// TODO: Get image / text using `Ident` as a lookup key
- AxWin3_Widget_SetText(txt, Ident);
+ AxWin3_Widget_SetText(txt, getstr(Ident));
AxWin3_Widget_SetFireHandler(btn, Callback);
}
{
return 0;
}
+int Toolbar_Close(tAxWin3_Widget *Widget)
+{
+ AxWin3_StopMainLoop(1);
+ return 0;
+}
* strings.c
* - String Localisation
*/
+#include "strings.h"
+#include <string.h>
struct keyval_str
{
{"BtnNew", "New"},
{"BtnOpen", "Open"},
{"BtnSave", "Save"},
- {"BtnUndo", "Undo"}
+ {"BtnClose", "Close"},
+ {"BtnUndo", "Undo"},
+ {"BtnRedo", "Redo"},
+ {"BtnCut", "Cut"},
+ {"BtnCopy", "Copy"},
+ {"BtnPaste", "Paste"},
+ {"BtnSearch", "Search"},
+ {"BtnReplace", "Replace"},
};
+const int ciNumDisplayStrings = sizeof(gaDisplayStrings)/sizeof(gaDisplayStrings[0]);
+const char *getstr(const char *key)
+{
+ int i;
+ for(i = 0; i < ciNumDisplayStrings; i ++)
+ {
+ if( strcmp(key, gaDisplayStrings[i].key) == 0 )
+ return gaDisplayStrings[i].val;
+ }
+ return "-nostr-";
+}
+
+const char *getimg(const char *key)
+{
+ return "";
+}
// --- Connection management
extern void AxWin3_Connect(const char *ServerDesc);
extern tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback);
-extern void AxWin3_MainLoop(void);
+extern int AxWin3_MainLoop(void);
+extern void AxWin3_StopMainLoop(int Reason);
extern void AxWin3_MessageSelect(int nFD, fd_set *FDs);
// --- Non-Window based functions