diff -r 73c8a3780c72 -r 641dcc79e0ef ui/winui/container.cpp --- a/ui/winui/container.cpp Sun Nov 10 09:12:30 2024 +0100 +++ b/ui/winui/container.cpp Sun Nov 10 15:30:46 2024 +0100 @@ -1,30 +1,30 @@ /* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2023 Olaf Wintermann. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +* +* Copyright 2023 Olaf Wintermann. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ #include "pch.h" @@ -122,7 +122,7 @@ gl.Value = 0; gl.GridUnitType = GridUnitType::Auto; } - + control.HorizontalAlignment(HorizontalAlignment::Stretch); control.VerticalAlignment(VerticalAlignment::Stretch); @@ -179,13 +179,24 @@ void UiGridContainer::Add(FrameworkElement control, UiBool fill) { GridLength gl; - int hexpand = FALSE; - int vexpand = FALSE; + bool hexpand = false; + bool vexpand = false; + bool hfill = false; + bool vfill = false; + if(layout.fill != UI_LAYOUT_UNDEFINED) { + fill = ui_lb2bool(layout.fill); + } if (layout.hexpand != UI_LAYOUT_UNDEFINED) { hexpand = layout.hexpand; + hfill = true; } if (layout.vexpand != UI_LAYOUT_UNDEFINED) { vexpand = layout.vexpand; + vfill = true; + } + if (fill) { + hfill = true; + vfill = true; } // create new RowDefinition for the new line @@ -203,6 +214,11 @@ } rowdef.Height(gl); grid.RowDefinitions().Append(rowdef); + } else if (vexpand) { + // adjust row + gl.GridUnitType = GridUnitType::Star; + gl.Value = 1; + grid.RowDefinitions().GetAt(y).Height(gl); } // create new columndefinition, if a new column is added @@ -219,11 +235,42 @@ coldef.Width(gl); grid.ColumnDefinitions().Append(coldef); cols++; + } else if(hexpand) { + // adjust column + if (layout.colspan == 0) { + gl.GridUnitType = GridUnitType::Star; + gl.Value = 1; + grid.ColumnDefinitions().GetAt(x).Width(gl); + } else { + int adjust_col = x; + bool adjust = true; + for (int i = 0; i < layout.colspan; i++) { + if (grid.ColumnDefinitions().Size() == x + i) { + break; + } + adjust_col = x + i; + GridLength w = grid.ColumnDefinitions().GetAt(adjust_col).Width(); + if (w.GridUnitType == GridUnitType::Star) { + adjust = false; + break; + } + } + + if (adjust) { + gl.GridUnitType = GridUnitType::Star; + gl.Value = 1; + grid.ColumnDefinitions().GetAt(adjust_col).Width(gl); + } + } } // add control - control.HorizontalAlignment(HorizontalAlignment::Stretch); - control.VerticalAlignment(VerticalAlignment::Stretch); + if (hfill) { + control.HorizontalAlignment(HorizontalAlignment::Stretch); + } + if (vfill) { + control.VerticalAlignment(VerticalAlignment::Stretch); + } if (layout.colspan > 0) { grid.SetColumnSpan(control, layout.colspan); @@ -277,7 +324,7 @@ frame.SetColumn(label, 0); frame.Children().Append(label); } - + // workarea frame frame.RowDefinitions().Append(rowdefFrame); @@ -460,16 +507,24 @@ return newobj; } +static UiTabView* tabview_pivot_create(UiObject* obj, UiTabViewArgs args) { + Pivot pivot = Pivot(); + UiPivotTabView* tabview = new UiPivotTabView(obj, pivot, args); + + return tabview; +} + UiPivotTabView::UiPivotTabView(UiObject* obj, Pivot pivot, UiTabViewArgs args) { this->current = obj; this->pivot = pivot; + this->subcontainer = args.subcontainer; this->margin = args.margin; this->spacing = args.spacing; this->columnspacing = args.columnspacing; this->rowspacing = args.rowspacing; } -UiObject* UiPivotTabView::AddTab(const char* label) { +UiObject* UiPivotTabView::AddTab(const char* label, int index) { TextBlock text = TextBlock(); wchar_t* wlabel = str2wstr(label, nullptr); winrt::hstring hstr(wlabel); @@ -487,27 +542,110 @@ return create_subcontainer_obj(current, subcontainer, this->subcontainer, margin, spacing, columnspacing, rowspacing); } +void UiPivotTabView::Remove(int index) { + pivot.Items().RemoveAt(index); +} + +void UiPivotTabView::Select(int index) { + +} + FrameworkElement UiPivotTabView::GetFrameworkElement() { return pivot; } -static UiTabView* tabview_pivot_create(UiObject* obj, UiTabViewArgs args) { - Pivot pivot = Pivot(); - UiPivotTabView* tabview = new UiPivotTabView(obj, pivot, args); + +static UiTabView* tabview_invisible_create(UiObject *obj, UiTabViewArgs args) { + Grid container = Grid(); + container.HorizontalAlignment(HorizontalAlignment::Stretch); + container.VerticalAlignment(VerticalAlignment::Stretch); + UiInvisibleTabView *tabview = new UiInvisibleTabView(obj, container, args); + return tabview; +} + +UiInvisibleTabView::UiInvisibleTabView(UiObject* obj, Grid container, UiTabViewArgs args) { + this->current = obj; + this->container = container; + this->subcontainer = args.subcontainer; + this->margin = args.margin; + this->spacing = args.spacing; + this->columnspacing = args.columnspacing; + this->rowspacing = args.rowspacing; + this->currentIndex = -1; + + GridLength gl; + gl.GridUnitType = GridUnitType::Star; + gl.Value = 1; + + ColumnDefinition coldef = ColumnDefinition(); + coldef.Width(gl); + container.ColumnDefinitions().Append(coldef); + + RowDefinition rowdef = RowDefinition(); + rowdef.Height(gl); + container.RowDefinitions().Append(rowdef); +} - return tabview; +UiObject* UiInvisibleTabView::AddTab(const char* label, int index) { + Grid subcontainer = Grid(); + subcontainer.HorizontalAlignment(HorizontalAlignment::Stretch); + subcontainer.VerticalAlignment(VerticalAlignment::Stretch); + + if (pages.size() == 0) { + container.Children().Append(subcontainer); + currentIndex = 0; + } + + if (index < 0) { + pages.push_back(subcontainer); + } else { + pages.insert(pages.begin() + index, subcontainer); + } + + // sub container + return create_subcontainer_obj(current, subcontainer, this->subcontainer, margin, spacing, columnspacing, rowspacing); +} + +void UiInvisibleTabView::Remove(int index) { + +} + +void UiInvisibleTabView::Select(int index) { + if (index >= 0 && index < pages.size()) { + if (currentIndex != -1) { + container.Children().RemoveAt(0); + } + + container.Children().Append(pages.at(index)); + } +} + +FrameworkElement UiInvisibleTabView::GetFrameworkElement() { + return container; +} + + +static UiTabView* tabview_main_create(UiObject* obj, UiTabViewArgs args) { + TabView tabview = TabView(); + tabview.IsAddTabButtonVisible(false); + //tabview.CanDragTabs(false); + //tabview.CanReorderTabs(false); + UiMainTabView* uitabview = new UiMainTabView(obj, tabview, args); + + return uitabview; } UiMainTabView::UiMainTabView(UiObject* obj, TabView tabview, UiTabViewArgs args) { this->current = obj; this->tabview = tabview; + this->subcontainer = args.subcontainer; this->margin = args.margin; this->spacing = args.spacing; this->columnspacing = args.columnspacing; this->rowspacing = args.rowspacing; } -UiObject* UiMainTabView::AddTab(const char* label) { +UiObject* UiMainTabView::AddTab(const char* label, int index) { TextBlock text = TextBlock(); wchar_t* wlabel = str2wstr(label, nullptr); winrt::hstring hstr(wlabel); @@ -527,18 +665,26 @@ return create_subcontainer_obj(current, subcontainer, this->subcontainer, margin, spacing, columnspacing, rowspacing); } +void UiMainTabView::Remove(int index) { + this->tabview.TabItems().RemoveAt(index); +} + +void UiMainTabView::Select(int index) { + +} + FrameworkElement UiMainTabView::GetFrameworkElement() { return tabview; } -static UiTabView* tabview_main_create(UiObject* obj, UiTabViewArgs args) { - TabView tabview = TabView(); - tabview.IsAddTabButtonVisible(false); - //tabview.CanDragTabs(false); - //tabview.CanReorderTabs(false); - UiMainTabView* uitabview = new UiMainTabView(obj, tabview, args); - return uitabview; +static UiTabView* tabview_navigationview_create(UiObject* obj, UiTabViewArgs args, UiTabViewType type) { + NavigationView navigationview = NavigationView(); + UiNavigationTabView* tabview = new UiNavigationTabView(obj, navigationview, args, type); + navigationview.IsBackButtonVisible(NavigationViewBackButtonVisible::Collapsed); + navigationview.IsSettingsVisible(false); + + return tabview; } UiNavigationTabView::UiNavigationTabView(UiObject* obj, NavigationView navigationview, UiTabViewArgs args, UiTabViewType type) { @@ -557,7 +703,7 @@ navigationview.SelectionChanged({ this, &UiNavigationTabView::SelectionChanged }); } -UiObject* UiNavigationTabView::AddTab(const char* label) { +UiObject* UiNavigationTabView::AddTab(const char* label, int index1) { TextBlock text = TextBlock(); wchar_t* wlabel = str2wstr(label, nullptr); winrt::hstring hstr(wlabel); @@ -581,6 +727,15 @@ return create_subcontainer_obj(current, subcontainer, this->subcontainer, margin, spacing, columnspacing, rowspacing); } +void UiNavigationTabView::Remove(int index) { + navigationview.MenuItems().RemoveAt(index); + pages.erase(pages.begin() + index); +} + +void UiNavigationTabView::Select(int index) { + +} + FrameworkElement UiNavigationTabView::GetFrameworkElement() { return navigationview; } @@ -596,13 +751,13 @@ } } -static UiTabView* tabview_navigationview_create(UiObject* obj, UiTabViewArgs args, UiTabViewType type) { - NavigationView navigationview = NavigationView(); - UiNavigationTabView* tabview = new UiNavigationTabView(obj, navigationview, args, type); - navigationview.IsBackButtonVisible(NavigationViewBackButtonVisible::Collapsed); - navigationview.IsSettingsVisible(false); +static int64_t ui_tabview_get(UiInteger *i) { + return 0; +} - return tabview; +static void ui_tabview_set(UiInteger *i, int64_t value) { + UiTabView *tabview = (UiTabView*)i->obj; + tabview->Select(value); } UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs args) { @@ -629,6 +784,10 @@ tabview = tabview_pivot_create(obj, args); break; } + case UI_TABVIEW_INVISIBLE: { + tabview = tabview_invisible_create(obj, args); + break; + } } UiTabViewContainer* ctn = new UiTabViewContainer(tabview); @@ -642,6 +801,17 @@ ui_context_add_widget_destructor(current->ctx, widget); widget->data1 = tabview; + // TODO: add tabview destructor + + // bind variable + UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER); + if (var) { + UiInteger *i = (UiInteger*)var->value; + i->obj = tabview; + i->get = ui_tabview_get; + i->set = ui_tabview_set; + } + UiObject* newobj = uic_object_new(obj, widget); newobj->container = ctn; uic_obj_add(obj, newobj); @@ -656,12 +826,59 @@ uic_obj_add(current, newobj); } +UIEXPORT void ui_tabview_select(UIWIDGET tabview, int tab) { + UiTabView* t = (UiTabView*)tabview->data1; + t->Select(tab); +} + +UIEXPORT void ui_tabview_remove(UIWIDGET tabview, int tab) { + UiTabView* t = (UiTabView*)tabview->data1; + t->Remove(tab); +} + +UIEXPORT UiObject* ui_tabview_add(UIWIDGET tabview, const char *name, int tab_index) { + UiTabView* t = (UiTabView*)tabview->data1; + UiObject* newobj = t->AddTab(name, tab_index); + return newobj; +} + + + +// --------------------- UI Headerbar --------------------- + +// TODO: replace placeholder implementation + +UIEXPORT UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs args) { + UiContainerArgs boxargs = { }; + boxargs.fill = UI_OFF; + return ui_hbox_create(obj, boxargs); +} + +UIEXPORT void ui_headerbar_start_create(UiObject *obj) { + UiContainerArgs boxargs = { }; + boxargs.fill = UI_OFF; + ui_hbox_create(obj, boxargs); +} + +UIEXPORT void ui_headerbar_center_create(UiObject *obj) { + UiContainerArgs boxargs = { }; + boxargs.fill = UI_OFF; + ui_hbox_create(obj, boxargs); +} + +UIEXPORT void ui_headerbar_end_create(UiObject *obj) { + UiContainerArgs boxargs = { }; + boxargs.fill = UI_OFF; + ui_hbox_create(obj, boxargs); +} + + /* - * -------------------- Layout Functions -------------------- - * - * functions for setting layout attributes for the current container - * - */ +* -------------------- Layout Functions -------------------- +* +* functions for setting layout attributes for the current container +* +*/ void ui_layout_fill(UiObject* obj, UiBool fill) { UiContainer* ct = uic_get_current_container(obj); @@ -678,14 +895,14 @@ ct->layout.vexpand = expand; } -void ui_layout_hfill(UiObject *obj, UiBool fill) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.hfill = fill; +void ui_layout_hfill(UiObject* obj, UiBool fill) { + UiContainer* ct = uic_get_current_container(obj); + ct->layout.hfill = fill; } -void ui_layout_vfill(UiObject *obj, UiBool fill) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.vfill = fill; +void ui_layout_vfill(UiObject* obj, UiBool fill) { + UiContainer* ct = uic_get_current_container(obj); + ct->layout.vfill = fill; } void ui_layout_width(UiObject* obj, int width) {