// sixten: Rows and columns. inline void UI_RowBegin(void) { UI_SetNextLayoutAxis(Axis2_X); ui_box *Box = UI_MakeBox(0, StrLit("")); UI_PushParent(Box); } inline void UI_RowEnd(void) { UI_PopParent(); } inline void UI_ColumnBegin(void) { UI_SetNextLayoutAxis(Axis2_Y); ui_box *Box = UI_MakeBox(0, StrLit("")); UI_PushParent(Box); } inline void UI_ColumnEnd(void) { UI_PopParent(); } #define UI_Row DeferLoop(UI_RowBegin(), UI_RowEnd()) #define UI_Column DeferLoop(UI_ColumnBegin(), UI_ColumnEnd()) // sixten: Compositions inline void UI_PushAxisSize(axis2 Axis, ui_size Size) { if(Axis == Axis2_X) { UI_PushWidth(Size); } else { UI_PushHeight(Size); } } inline void UI_PopAxisSize(axis2 Axis) { if(Axis == Axis2_X) { UI_PopWidth(); } else { UI_PopHeight(); } } inline void UI_SetNextAxisSize(axis2 Axis, ui_size Size) { if(Axis == Axis2_X) { UI_SetNextWidth(Size); } else { UI_SetNextHeight(Size); } } #define UI_AxisSize(Axis, Size) DeferLoop(UI_PushAxisSize(Axis, Size), UI_PopAxisSize(Axis)) #define UI_Size(Width, Height) UI_Width(Width) UI_Height(Height) #define UI_PushSize(Width, Height) UI_PushWidth(Width); UI_PushHeight(Height) #define UI_PopSize() UI_PopWidth(); UI_PopHeight() #define UI_SetNextSize(Width, Height) UI_SetNextWidth(Width); UI_SetNextHeight(Height) #define UI_FixedP(Value) UI_FixedX(Value.x) UI_FixedY(Value.y) #define UI_SetNextFixedP(Value) UI_SetNextFixedX(Value.x); UI_SetNextFixedY(Value.y) // sixten: Spacing static ui_box *UI_NamedSpacer(ui_size Size, string String) { ui_box *Parent = UI_TopParent(); UI_SetNextAxisSize(Parent->LayoutAxis, Size); ui_box *Box = UI_MakeBox(0, String); return(Box); } static ui_box *UI_NamedSpacerF(ui_size Size, char *Format, ...) { temporary_memory Scratch = GetScratch(0, 0); va_list Arguments; va_start(Arguments, Format); string String = PushFormatVariadic(Scratch.Arena, Format, Arguments); va_end(Arguments); ui_box *Box = UI_NamedSpacer(Size, String); ReleaseScratch(Scratch); return(Box); } static void UI_Spacer(ui_size Size) { UI_NamedSpacer(Size, StrLit("")); } #define UI_Padding(Size) DeferLoop(UI_Spacer(Size), UI_Spacer(Size)) // sixten: Common widgets static ui_box *UI_Label(string String) { ui_box *Box = UI_MakeBox(UI_BoxFlag_DrawText, String); return(Box); } static ui_box *UI_LabelF(char *Format, ...) { temporary_memory Scratch = GetScratch(0, 0); va_list Arguments; va_start(Arguments, Format); string String = PushFormatVariadic(Scratch.Arena, Format, Arguments); va_end(Arguments); ui_box *Box = UI_MakeBox(UI_BoxFlag_DrawText, String); ReleaseScratch(Scratch); return(Box); } static ui_signal UI_Button(string String) { ui_box *Box = UI_MakeBox(UI_BoxFlag_DrawText| UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| UI_BoxFlag_HotAnimation| UI_BoxFlag_ActiveAnimation| UI_BoxFlag_Clickable, String); ui_signal Signal = UI_SignalFromBox(Box); return(Signal); } static ui_signal UI_ButtonF(char *Format, ...) { temporary_memory Scratch = GetScratch(0, 0); va_list Arguments; va_start(Arguments, Format); string String = PushFormatVariadic(Scratch.Arena, Format, Arguments); va_end(Arguments); ui_box *Box = UI_MakeBox(UI_BoxFlag_DrawText| UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| UI_BoxFlag_HotAnimation| UI_BoxFlag_ActiveAnimation| UI_BoxFlag_Clickable, String); ui_signal Signal = UI_SignalFromBox(Box); ReleaseScratch(Scratch); return(Signal); } static ui_signal UI_Checkbox(string String, b32 *Checked) { UI_SetNextSize(UI_ChildrenSum(1, 1), UI_ChildrenSum(1, 1)); UI_SetNextLayoutAxis(Axis2_X); ui_box *ContainerBox = UI_MakeBox(UI_BoxFlag_Clickable, String); UI_Parent(ContainerBox) { r32 OpacityTransition = AnimationCurve_AnimateValueF(*Checked, *Checked, 0.15, "UI Checkbox Transition %p", Checked); v4 TextColor = UI_TopTextColor(); TextColor.a = OpacityTransition; UI_CornerRadius(2) UI_Size(UI_Em(1, 1), UI_Em(1, 1)) UI_Font(Font_Icons) UI_TextColor(TextColor) UI_MakeBoxF(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawText, "%U", FontIcon_Cancel); UI_Size(UI_TextContent(15, 1), UI_Em(1, 1)) UI_Label(String); } ui_signal Signal = UI_SignalFromBox(ContainerBox); if(Signal.Hovering) { Platform.SetCursor(PlatformCursor_Hand); } if(Signal.Pressed) { *Checked = !*Checked; } return(Signal); }