From: John Hodge Date: Sat, 29 Oct 2011 15:03:42 +0000 (+0800) Subject: Usermode/AxWin3 - Porting over the AxWin2 widget code X-Git-Tag: rel0.14~169 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=1b3ef37ec6016643ee96ebab4c9966d9bb846b21;p=tpg%2Facess2.git Usermode/AxWin3 - Porting over the AxWin2 widget code --- diff --git a/Usermode/Applications/axwin3_src/WM/Makefile b/Usermode/Applications/axwin3_src/WM/Makefile index 69c99b22..1e7b9bd7 100644 --- a/Usermode/Applications/axwin3_src/WM/Makefile +++ b/Usermode/Applications/axwin3_src/WM/Makefile @@ -4,9 +4,9 @@ CPPFLAGS += -I include/ -DIR := Apps/AxWin/2.0 +DIR := Apps/AxWin/3.0 BIN := AxWinWM -OBJ := main.o +OBJ := main.o wm.o input.o OBJ += messageio.o OBJ += renderer_classes.o renderer_passthru.o renderer_widget.o diff --git a/Usermode/Applications/axwin3_src/WM/include/common.h b/Usermode/Applications/axwin3_src/WM/include/common.h index 7da032d0..5aae9273 100644 --- a/Usermode/Applications/axwin3_src/WM/include/common.h +++ b/Usermode/Applications/axwin3_src/WM/include/common.h @@ -10,6 +10,8 @@ #include +#define TODO(str) + // === FUNCTIONS === // --- Input --- int Input_Init(void); diff --git a/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h b/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h index fbb3e02a..7187c87f 100644 --- a/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h +++ b/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h @@ -17,5 +17,32 @@ enum MSG_WIDGET_SETTEXT }; +enum eElementTypes +{ + ELETYPE_NONE, + + ELETYPE_WINDOW, //!< Window root element + + ELETYPE_BOX, //!< Content box (invisible in itself) + ELETYPE_TABBAR, //!< Tab Bar + ELETYPE_TOOLBAR, //!< Tool Bar + + ELETYPE_BUTTON, //!< Push Button + + ELETYPE_TEXT, //!< Text + ELETYPE_IMAGE, //!< Image + + ELETYPE_SPACER, //!< Visual Spacer (horizontal / vertical rule) + + MAX_ELETYPES = 0x100 +}; + +typedef struct +{ + uint32_t Parent; + uint32_t NewID; + char DebugName[]; +} tWidgetMsg_Create; + #endif diff --git a/Usermode/Applications/axwin3_src/WM/input.c b/Usermode/Applications/axwin3_src/WM/input.c index ebbad924..9de0d42e 100644 --- a/Usermode/Applications/axwin3_src/WM/input.c +++ b/Usermode/Applications/axwin3_src/WM/input.c @@ -8,15 +8,25 @@ #include #include +// TODO: Move out to a common header typedef struct { int Num; int Value; } tNumValue; - #define JOY_IOCTL_GETSETAXISLIMIT 6 #define JOY_IOCTL_GETSETAXISPOSITION 7 +// === IMPORTS === +// TODO: Move out +const char *gsMouseDevice; + int giTerminalFD; + int giScreenWidth; + int giScreenHeight; + +// === GLOBALS === + int giMouseFD; + // === CODE === int Input_Init(void) { @@ -26,14 +36,13 @@ int Input_Init(void) giMouseFD = open(gsMouseDevice, 3); // Set mouse limits - num_value.Num = 0; - num_value.Value = giScreenWidth; + // TODO: Update these if the screen resolution changes + num_value.Num = 0; num_value.Value = giScreenWidth; ioctl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value); num_value.Value = giScreenWidth/2; ioctl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value); - num_value.Num = 1; - num_value.Value = giScreenHeight; + num_value.Num = 1; num_value.Value = giScreenHeight; ioctl(giMouseFD, JOY_IOCTL_GETSETAXISLIMIT, &num_value); num_value.Value = giScreenHeight/2; ioctl(giMouseFD, JOY_IOCTL_GETSETAXISPOSITION, &num_value); @@ -85,6 +94,8 @@ void Input_HandleSelect(fd_set *set) // Handle movement Video_SetCursorPos( mouseinfo.Axies[0].CursorPos, mouseinfo.Axies[1].CursorPos ); -// _SysDebug("Cursor to %i,%i", mouseinfo.Axies[0].CursorPos, mouseinfo.Axies[1].CursorPos); + + + // TODO: Handle button presses } } diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget.c b/Usermode/Applications/axwin3_src/WM/renderer_widget.c index ddcb2437..fa284e83 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderer_widget.c @@ -8,6 +8,7 @@ #include #include #include +#include // === TYPES === typedef struct sWidgetWin tWidgetWin; @@ -17,6 +18,9 @@ typedef struct sAxWin_Element tElement; struct sAxWin_Element { enum eElementTypes Type; + + uint32_t ID; //!< Application provided ID number + tElement *ListNext; //!< Next element in bucket // Element Tree tElement *Parent; @@ -24,10 +28,6 @@ struct sAxWin_Element tElement *LastChild; tElement *NextSibling; - // Application - tApplication *Owner; //!< Owning application - uint16_t ApplicationID; //!< Index into sApplication::EleIndex - // User modifiable attributes short PaddingL, PaddingR; short PaddingT, PaddingB; @@ -55,6 +55,9 @@ struct sAxWin_Element struct sWidgetWin { tElement RootElement; + + int TableSize; //!< Number of entries, anything over will wrap + tElement *ElementTable[]; //!< Hash table essentially }; // === PROTOTYPES === @@ -88,13 +91,213 @@ void Renderer_Widget_Redraw(tWindow *Window) { } +// --- Render / Resize --- +void _UpdateDimensions(tElement *Ele) +{ + tElement *child; + int nChildren = 0; + int nFixed = 0; + int maxCross = 0; + int fixedSize = 0; + int fullCross, dynWith; + + // Pass 1 + // - Get the fixed and minimum sizes of the element + for( child = Element->FirstChild; child; child = child->NextSibling ) + { + // Ignore elements that will not be rendered + if( child->Flags & ELEFLAG_NORENDER ) continue ; + + // Absolutely positioned elements don't affect dimensions + if( child->Flags & ELEFLAG_ABSOLUTEPOS ) continue ; + + // Fixed width elements + if( child->FixedWith ) + { + nFixed ++; + fixedSize += child->FixedWith; + } + + if( child->FixedCross && maxCross < child->FixedCross ) + maxCross = child->FixedCross; + if( child->MinCross && maxCross < child->MinCross ) + maxCross = child->MinCross; + nChildren ++; + } + + // Get the dynamic with size from the unused space in the element + if( nChildren > nFixed ) { + if( Element->Flags & ELEFLAG_VERTICAL ) + dynWith = Element->CachedH - Element->PaddingT - Element->PaddingB; + else + dynWith = Element->CachedW - Element->PaddingL - Element->PaddingR; + dynWith -= fixedSize; + if( dynWith < 0 ) return ; + dynWith /= nChildren - nFixed; + } + + // Get the cross size + if( Element->Flags & ELEFLAG_VERTICAL ) + fullCross = Element->CachedW - Element->PaddingL - Element->PaddingR; + else + fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB; + + // Pass 2 - Set sizes and recurse + for( child = Element->FirstChild; child; child = child->NextSibling ) + { + int cross, with; + + // Ignore elements that will not be rendered + if( child->Flags & ELEFLAG_NORENDER ) continue ; + + // --- Cross Size --- + // TODO: Expand to fill? + // TODO: Extra flag so options are (Expand, Equal, Wrap) + if( child->FixedCross ) + cross = child->FixedCross; + else if( child->Flags & ELEFLAG_NOEXPAND ) + cross = child->MinCross; + else + cross = fullCross; + + // --- With Size --- + if( child->FixedWith) + with = child->FixedWith; + else if( child->Flags & ELEFLAG_NOSTRETCH ) + with = child->MinWith; + else + with = dynWith; + + + // Update the dimensions if they have changed + if( Element->Flags & ELEFLAG_VERTICAL ) { + // If no change, don't recurse + if( child->CachedW == cross && child->CachedH == with ) + continue ; + child->CachedW = cross; + child->CachedH = with; + } + else { + // If no change, don't recurse + if( child->CachedW == with && child->CachedH == cross ) + continue ; + child->CachedW = with; + child->CachedH = cross; + } + + // Force the positions of child elements to be recalculated + child->CachedX = -1; + + // Recurse down so the child elements can be updated + _UpdateDimensions(child); + } + +} + +void _UpdatePosition(tElement *Element) +{ + tElement *child; + int x, y; + + if( Element->Flags & ELEFLAG_NORENDER ) return ; + + // Initialise + x = Element->CachedX + Element->PaddingL; + y = Element->CachedY + Element->PaddingT; + + // Update each child + for(child = Element->FirstChild; child; child = child->NextSibling) + { + int newX, newY; + // Ignore elements that will not be rendered + if( child->Flags & ELEFLAG_NORENDER ) continue ; + + newX = x; newY = y; + + // Handle alignment + if( Element->Flags & ELEFLAG_ALIGN_CENTER ) { + if(Element->Flags & ELEFLAG_VERTICAL) + newX += Element->CachedW/2 - child->CachedW/2; + else + newY += Element->CachedH/2 - child->CachedH/2; + } + else if( Element->Flags & ELEFLAG_ALIGN_END ) { + if(Element->Flags & ELEFLAG_VERTICAL ) + newX += Element->CachedW - child->CachedW + - Element->PaddingL - Element->PaddingR; + else + newY += Element->CachedH - child->CachedH + - Element->PaddingT - Element->PaddingB; + } + + // Check for changes, and don't update if there was no change + if( newX != child->CachedX || newY != child->CachedY ) + { + child->CachedX = newX; + child->CachedY = newY; + // Update child's children positions + WM_UpdatePosition(child); + } + + // Increment + if(Element->Flags & ELEFLAG_VERTICAL ) { + y += child->CachedH + Element->GapSize; + } + else { + x += child->CachedW + Element->GapSize; + } + } +} + + +// --- Helpers --- +tElement *_GetElementById(tWidgetWin *Info, uint32_t ID) +{ + tElement *ele; + int num; + + if( ID < Info->TableSize ) return Info->ElementTable[ID]; + + while( ID >= Info->TableSize ) { + num ++; + ID -= Info->TableSize; + } + + ele = Info->ElementTable[num]; + while(num-- && ele) ele = ele->ListNext; + return ele; +} + +// --- Message Handlers --- +void _NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg) +{ + const int max_debugname_len = Len - sizeof(tWidgetMsg_Create); + tElement *parent; + + // Sanity check + if( Len < sizeof(tWidgetMsg_Create) ) + return ; + if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len ) + return ; + + // Create + parent = _GetElementById(Info, Msg->Parent); + +} + int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) { tWidgetWin *info = Target->RendererInfo; switch(Msg) { + case MSG_WIDGET_CREATE: + _NewWidget(info, Len, Data); + return 0; default: return 1; // Unhandled } } + + + diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c new file mode 100644 index 00000000..0c0756ec --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -0,0 +1,21 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * wm.c + * - Window manager core + */ +#include +#include + +// === CODE === +void WM_RegisterRenderer(tWMRenderer *Renderer) +{ + TODO("Implement WM_RegisterRenderer"); +} + +tWindow *WM_CreateWindowStruct(size_t ExtraSize) +{ + return NULL; +} +