implement ui groups/states (WINUI) newapi tip

Thu, 14 Nov 2024 17:26:16 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 14 Nov 2024 17:26:16 +0100
branch
newapi
changeset 382
de653b07050b
parent 381
b47bda6666ce

implement ui groups/states (WINUI)

ui/winui/button.cpp file | annotate | diff | comparison | revisions
ui/winui/commandbar.cpp file | annotate | diff | comparison | revisions
ui/winui/list.cpp file | annotate | diff | comparison | revisions
ui/winui/text.cpp file | annotate | diff | comparison | revisions
ui/winui/toolkit.cpp file | annotate | diff | comparison | revisions
ui/winui/toolkit.h file | annotate | diff | comparison | revisions
ui/winui/winui.vcxproj file | annotate | diff | comparison | revisions
--- a/ui/winui/button.cpp	Wed Nov 13 22:02:50 2024 +0100
+++ b/ui/winui/button.cpp	Thu Nov 14 17:26:16 2024 +0100
@@ -98,6 +98,7 @@
 	UIElement elm = button;
 	UiWidget* widget = new UiWidget(elm);
 	ui_context_add_widget_destructor(current->ctx, widget);
+	ui_set_widget_groups(current->ctx, widget, args.groups);
 
 	// register callback
 	if (args.onclick) {
@@ -175,6 +176,24 @@
 	}
 }
 
+static void togglebutton_changed(UiObject *obj, bool checked, ui_callback onchange, void *onchangedata, int enable_state) {
+	if (onchange) {
+		UiEvent evt;
+		evt.obj = obj;
+		evt.window = obj->window;
+		evt.document = obj->ctx->document;
+		evt.eventdata = nullptr;
+		evt.intval = checked;
+		onchange(&evt, onchangedata);
+	}
+	if (enable_state > 0) {
+		if (checked) {
+			ui_set_group(obj->ctx, enable_state);
+		} else {
+			ui_unset_group(obj->ctx, enable_state);
+		}
+	}
+}
 
 static UIWIDGET create_togglebutton(UiObject *obj, ToggleButton button, UiToggleArgs args) {
 	UiObject* current = uic_current_obj(obj);
@@ -187,6 +206,7 @@
 	UIElement elm = button;
 	UiWidget* widget = new UiWidget(elm);
 	ui_context_add_widget_destructor(current->ctx, widget);
+	ui_set_widget_groups(current->ctx, widget, args.groups);
 
 	// bind variable
 	UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER);
@@ -201,6 +221,15 @@
 		togglebutton_register_unchecked_observers(button, obj, var);
 	}
 
+	if (args.enable_group > 0 || args.onchange) {
+		button.Checked([obj, args](IInspectable const& sender, RoutedEventArgs) {
+			togglebutton_changed(obj, true, args.onchange, args.onchangedata, args.enable_group);
+		});
+		button.Unchecked([obj, args](IInspectable const& sender, RoutedEventArgs) {
+			togglebutton_changed(obj, false, args.onchange, args.onchangedata, args.enable_group);
+			});
+	}
+
 	// add button to current container
 	UI_APPLY_LAYOUT1(current, args);
 
@@ -234,6 +263,7 @@
 	UIElement elm = button;
 	UiWidget* widget = new UiWidget(elm);
 	ui_context_add_widget_destructor(current->ctx, widget);
+	ui_set_widget_groups(current->ctx, widget, args.groups);
 
 	// bind variable
 	UiVar* var = nullptr;
@@ -274,6 +304,7 @@
 	UIElement elm = button;
 	UiWidget* widget = new UiWidget(elm);
 	ui_context_add_widget_destructor(current->ctx, widget);
+	ui_set_widget_groups(current->ctx, widget, args.groups);
 
 	UiVar* var = nullptr;
 	if (args.value) {
--- a/ui/winui/commandbar.cpp	Wed Nov 13 22:02:50 2024 +0100
+++ b/ui/winui/commandbar.cpp	Thu Nov 14 17:26:16 2024 +0100
@@ -136,6 +136,11 @@
 		button.Icon(ui_get_icon(item->args.icon));
 	}
 
+	UIElement elm = button;
+	UiWidget* widget = new UiWidget(elm);
+	ui_context_add_widget_destructor(obj->ctx, widget);
+	ui_set_widget_groups(obj->ctx, widget, item->args.groups);
+
 	// register callback
 	if (item->args.onclick) {
 		ui_callback cbfunc = item->args.onclick;
@@ -170,6 +175,7 @@
 		UIElement elm = button;
 		UiWidget* widget = new UiWidget(elm);
 		ui_context_add_widget_destructor(obj->ctx, widget);
+		ui_set_widget_groups(obj->ctx, widget, item->args.groups);
 
 		UiInteger* value = (UiInteger*)var->value;
 		int64_t i = value->value;
--- a/ui/winui/list.cpp	Wed Nov 13 22:02:50 2024 +0100
+++ b/ui/winui/list.cpp	Thu Nov 14 17:26:16 2024 +0100
@@ -64,6 +64,7 @@
     widget->data1 = args.model;
     widget->data2 = args.getvalue;
     ui_context_add_widget_destructor(current->ctx, widget);
+    ui_set_widget_groups(current->ctx, widget, args.groups);
 
     // bind var
     UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
@@ -135,6 +136,7 @@
     widget->data1 = args.model;
     widget->data2 = args.getvalue;
     ui_context_add_widget_destructor(current->ctx, widget);
+    ui_set_widget_groups(current->ctx, widget, args.groups);
 
     // bind var
     UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
@@ -230,6 +232,7 @@
     widget->data1 = args.model;
     widget->data2 = args.getvalue;
     ui_context_add_widget_destructor(current->ctx, widget);
+    ui_set_widget_groups(current->ctx, widget, args.groups);
 
     // bind var
     UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
--- a/ui/winui/text.cpp	Wed Nov 13 22:02:50 2024 +0100
+++ b/ui/winui/text.cpp	Thu Nov 14 17:26:16 2024 +0100
@@ -62,6 +62,7 @@
     UIElement elm = textarea;
     UiWidget* widget = new UiWidget(elm);
     ui_context_add_widget_destructor(current->ctx, widget);
+    ui_set_widget_groups(current->ctx, widget, args.groups);
 
     UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_TEXT);
     if (var) {
@@ -180,6 +181,7 @@
     UIElement elm = textfield;
     UiWidget* widget = new UiWidget(elm);
     ui_context_add_widget_destructor(current->ctx, widget);
+    ui_set_widget_groups(current->ctx, widget, args.groups);
 
     UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_STRING);
     if (var) {
@@ -212,6 +214,7 @@
     UIElement elm = textfield;
     UiWidget* widget = new UiWidget(elm);
     ui_context_add_widget_destructor(current->ctx, widget);
+    ui_set_widget_groups(current->ctx, widget, args.groups);
 
     UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_STRING);
     if (var) {
--- a/ui/winui/toolkit.cpp	Wed Nov 13 22:02:50 2024 +0100
+++ b/ui/winui/toolkit.cpp	Thu Nov 14 17:26:16 2024 +0100
@@ -355,3 +355,27 @@
 	pool->EnqueueJob(job);
 }
 
+
+
+void ui_set_widget_groups(UiContext *ctx, UIWIDGET widget, const int *groups) {
+	if(!groups) {
+		return;
+	}
+	size_t ngroups = uic_group_array_size(groups);
+	ui_set_widget_ngroups(ctx, widget, groups, ngroups);
+}
+
+void ui_set_widget_ngroups(UiContext *ctx, UIWIDGET widget, const int *groups, size_t ngroups) {
+	if(ngroups > 0) {
+		uic_add_group_widget_i(ctx, widget, (ui_enablefunc)ui_set_enabled, groups, ngroups);
+		ui_set_enabled(widget, FALSE);
+	}
+}
+
+
+UIEXPORT void ui_set_enabled(UIWIDGET widget, int enabled) {
+	Control ctrl = widget->uielement.as<Control>();
+	if (ctrl) {
+		ctrl.IsEnabled(enabled);
+	}
+}
--- a/ui/winui/toolkit.h	Wed Nov 13 22:02:50 2024 +0100
+++ b/ui/winui/toolkit.h	Thu Nov 14 17:26:16 2024 +0100
@@ -66,4 +66,7 @@
 void ui_context_add_widget_destructor(UiContext* ctx, UiWidget* widget);
 void ui_context_add_container_destructor(UiContext* ctx, UiContainer *container);
 
-UiEvent ui_create_int_event(UiObject* obj, int64_t i);
\ No newline at end of file
+UiEvent ui_create_int_event(UiObject* obj, int64_t i);
+
+void ui_set_widget_groups(UiContext *ctx, UIWIDGET widget, const int *groups);
+void ui_set_widget_ngroups(UiContext *ctx, UIWIDGET widget, const int *groups, size_t ngroups);
--- a/ui/winui/winui.vcxproj	Wed Nov 13 22:02:50 2024 +0100
+++ b/ui/winui/winui.vcxproj	Thu Nov 14 17:26:16 2024 +0100
@@ -68,7 +68,7 @@
   <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
     <UseDebugLibraries>false</UseDebugLibraries>
     <WholeProgramOptimization>true</WholeProgramOptimization>
-    <LinkIncremental>false</LinkIncremental>
+    <LinkIncremental>true</LinkIncremental>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
@@ -91,6 +91,7 @@
       <PreprocessorDefinitions>_DEBUG;DISABLE_XAML_GENERATED_MAIN__;UI_WINUI;UI_WINUI_PCH;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\ucx;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <LanguageStandard_C Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">stdc17</LanguageStandard_C>
+      <RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MultiThreadedDebugDLL</RuntimeLibrary>
     </ClCompile>
     <Link>
       <AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">shell32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -98,11 +99,15 @@
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
     <ClCompile>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>DISABLE_XAML_GENERATED_MAIN__;UI_WINUI;UI_WINUI_PCH;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\..\ucx;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <SDLCheck Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</SDLCheck>
+      <LanguageStandard_C Condition="'$(Configuration)|$(Platform)'=='Release|x64'">stdc17</LanguageStandard_C>
     </ClCompile>
     <Link>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">shell32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup Condition="'$(WindowsPackageType)'!='None' and Exists('Package.appxmanifest')">
@@ -171,27 +176,35 @@
   <ItemGroup>
     <ClCompile Include="..\common\context.c">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="..\common\document.c">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="..\common\menu.c">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="..\common\object.c">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="..\common\properties.c">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="..\common\toolbar.c">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="..\common\types.c">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="..\common\ucx_properties.c">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="appmenu.cpp" />
     <ClCompile Include="button.cpp" />
@@ -272,6 +285,10 @@
     <OutDir>$(SolutionDir)..\..\build\vs\$(Platform)\$(Configuration)\</OutDir>
     <IntDir>..\..\build\vs\winui\$(Platform)\$(Configuration)\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(SolutionDir)..\..\build\vs\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>..\..\build\vs\winui\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
     <Import Project="..\..\make\vs\packages\Microsoft.WindowsAppSDK.1.5.241001000\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\make\vs\packages\Microsoft.WindowsAppSDK.1.5.241001000\build\native\Microsoft.WindowsAppSDK.targets')" />

mercurial