mirror of
				https://github.com/PancakeTAS/lsfg-vk.git
				synced 2025-10-30 07:01:10 +00:00 
			
		
		
		
	ui: configuration system and basic switching
This commit is contained in:
		
							parent
							
								
									3dba2a7a3d
								
							
						
					
					
						commit
						cbc536c23e
					
				
					 22 changed files with 709 additions and 272 deletions
				
			
		
							
								
								
									
										67
									
								
								ui/Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										67
									
								
								ui/Cargo.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -2,6 +2,12 @@
 | 
				
			||||||
# It is not intended for manual editing.
 | 
					# It is not intended for manual editing.
 | 
				
			||||||
version = 4
 | 
					version = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "anyhow"
 | 
				
			||||||
 | 
					version = "1.0.98"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "autocfg"
 | 
					name = "autocfg"
 | 
				
			||||||
version = "1.5.0"
 | 
					version = "1.5.0"
 | 
				
			||||||
| 
						 | 
					@ -570,6 +576,15 @@ dependencies = [
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "serde_spanned"
 | 
				
			||||||
 | 
					version = "1.0.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "slab"
 | 
					name = "slab"
 | 
				
			||||||
version = "0.4.10"
 | 
					version = "0.4.10"
 | 
				
			||||||
| 
						 | 
					@ -602,7 +617,7 @@ dependencies = [
 | 
				
			||||||
 "cfg-expr",
 | 
					 "cfg-expr",
 | 
				
			||||||
 "heck",
 | 
					 "heck",
 | 
				
			||||||
 "pkg-config",
 | 
					 "pkg-config",
 | 
				
			||||||
 "toml",
 | 
					 "toml 0.8.23",
 | 
				
			||||||
 "version-compare",
 | 
					 "version-compare",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -619,11 +634,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
 | 
					checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_spanned",
 | 
					 "serde_spanned 0.6.9",
 | 
				
			||||||
 "toml_datetime",
 | 
					 "toml_datetime 0.6.11",
 | 
				
			||||||
 "toml_edit",
 | 
					 "toml_edit",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "toml"
 | 
				
			||||||
 | 
					version = "0.9.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "indexmap",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					 "serde_spanned 1.0.0",
 | 
				
			||||||
 | 
					 "toml_datetime 0.7.0",
 | 
				
			||||||
 | 
					 "toml_parser",
 | 
				
			||||||
 | 
					 "toml_writer",
 | 
				
			||||||
 | 
					 "winnow",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "toml_datetime"
 | 
					name = "toml_datetime"
 | 
				
			||||||
version = "0.6.11"
 | 
					version = "0.6.11"
 | 
				
			||||||
| 
						 | 
					@ -633,6 +663,15 @@ dependencies = [
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "toml_datetime"
 | 
				
			||||||
 | 
					version = "0.7.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "toml_edit"
 | 
					name = "toml_edit"
 | 
				
			||||||
version = "0.22.27"
 | 
					version = "0.22.27"
 | 
				
			||||||
| 
						 | 
					@ -641,18 +680,36 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "indexmap",
 | 
					 "indexmap",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_spanned",
 | 
					 "serde_spanned 0.6.9",
 | 
				
			||||||
 "toml_datetime",
 | 
					 "toml_datetime 0.6.11",
 | 
				
			||||||
 "winnow",
 | 
					 "winnow",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "toml_parser"
 | 
				
			||||||
 | 
					version = "1.0.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "winnow",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "toml_writer"
 | 
				
			||||||
 | 
					version = "1.0.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ui"
 | 
					name = "ui"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "anyhow",
 | 
				
			||||||
 "glib-build-tools",
 | 
					 "glib-build-tools",
 | 
				
			||||||
 "gtk4",
 | 
					 "gtk4",
 | 
				
			||||||
 "libadwaita",
 | 
					 "libadwaita",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					 "toml 0.9.2",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,10 @@ edition = "2024"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
gtk = { version = "0.10.0", package = "gtk4" }
 | 
					gtk = { version = "0.10.0", package = "gtk4" }
 | 
				
			||||||
adw = { version = "0.8.0", package = "libadwaita" }
 | 
					adw = { version = "0.8.0", package = "libadwaita", features = ["v1_4"] }
 | 
				
			||||||
 | 
					serde = { version = "1.0", features = ["derive"] }
 | 
				
			||||||
 | 
					toml = "0.9.2"
 | 
				
			||||||
 | 
					anyhow = "1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[build-dependencies]
 | 
					[build-dependencies]
 | 
				
			||||||
glib-build-tools = "0.21.0"
 | 
					glib-build-tools = "0.21.0"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										89
									
								
								ui/rsc/pane/main.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								ui/rsc/pane/main.ui
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,89 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<interface>
 | 
				
			||||||
 | 
					<template class="LSPaneMain" parent="AdwNavigationPage">
 | 
				
			||||||
 | 
					<child>
 | 
				
			||||||
 | 
					<object class="AdwToolbarView">
 | 
				
			||||||
 | 
					    <!-- Header -->
 | 
				
			||||||
 | 
					    <child type="top">
 | 
				
			||||||
 | 
					    <object class="AdwHeaderBar">
 | 
				
			||||||
 | 
					    <property name="title-widget">
 | 
				
			||||||
 | 
					    <object class="AdwWindowTitle">
 | 
				
			||||||
 | 
					        <property name="title">lsfg-vk Configuration Menu</property>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </property>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </child>
 | 
				
			||||||
 | 
					    <!-- Content -->
 | 
				
			||||||
 | 
					    <property name="content">
 | 
				
			||||||
 | 
					    <object class="GtkScrolledWindow">
 | 
				
			||||||
 | 
					    <property name="hscrollbar-policy">never</property>
 | 
				
			||||||
 | 
					    <child>
 | 
				
			||||||
 | 
					    <object class="GtkBox" id="main_box">
 | 
				
			||||||
 | 
					    <property name="orientation">vertical</property>
 | 
				
			||||||
 | 
					    <property name="margin-start">48</property>
 | 
				
			||||||
 | 
					    <property name="margin-end">48</property>
 | 
				
			||||||
 | 
					    <property name="margin-top">32</property>
 | 
				
			||||||
 | 
					    <property name="margin-bottom">32</property>
 | 
				
			||||||
 | 
					    <property name="spacing">32</property>
 | 
				
			||||||
 | 
					    <child>
 | 
				
			||||||
 | 
					    <!-- Frame Generation -->
 | 
				
			||||||
 | 
					    <object class="AdwPreferencesGroup">
 | 
				
			||||||
 | 
					        <property name="title">Frame Generation</property>
 | 
				
			||||||
 | 
					        <!-- Frame Generation: Multiplier -->
 | 
				
			||||||
 | 
					        <child>
 | 
				
			||||||
 | 
					        <object class="LSPrefNumber" id="pref_multiplier">
 | 
				
			||||||
 | 
					            <property name="opt-name">Multiplier</property>
 | 
				
			||||||
 | 
					        </object>
 | 
				
			||||||
 | 
					        </child>
 | 
				
			||||||
 | 
					        <!-- Frame Generation: Flow Scale -->
 | 
				
			||||||
 | 
					        <child>
 | 
				
			||||||
 | 
					        <object class="LSPrefSlider" id="pref_flow_scale">
 | 
				
			||||||
 | 
					            <property name="opt-name">Flow Scale</property>
 | 
				
			||||||
 | 
					        </object>
 | 
				
			||||||
 | 
					        </child>
 | 
				
			||||||
 | 
					        <!-- Frame Generation: Performance Mode -->
 | 
				
			||||||
 | 
					        <child>
 | 
				
			||||||
 | 
					        <object class="LSPrefSwitch" id="pref_performance_mode">
 | 
				
			||||||
 | 
					            <property name="opt-name">Performance Mode</property>
 | 
				
			||||||
 | 
					            <property name="default-state">false</property>
 | 
				
			||||||
 | 
					        </object>
 | 
				
			||||||
 | 
					        </child>
 | 
				
			||||||
 | 
					        </object>
 | 
				
			||||||
 | 
					    </child>
 | 
				
			||||||
 | 
					    <child>
 | 
				
			||||||
 | 
					    <!-- Misc -->
 | 
				
			||||||
 | 
					    <object class="AdwPreferencesGroup">
 | 
				
			||||||
 | 
					        <property name="title">Misc</property>
 | 
				
			||||||
 | 
					        <!-- Misc: HDR Mode -->
 | 
				
			||||||
 | 
					        <child>
 | 
				
			||||||
 | 
					        <object class="LSPrefSwitch" id="pref_hdr_mode">
 | 
				
			||||||
 | 
					            <property name="opt-name">HDR Mode</property>
 | 
				
			||||||
 | 
					            <property name="default-state">false</property>
 | 
				
			||||||
 | 
					        </object>
 | 
				
			||||||
 | 
					        </child>
 | 
				
			||||||
 | 
					        <!-- Misc: Experimental Present Mode -->
 | 
				
			||||||
 | 
					        <child>
 | 
				
			||||||
 | 
					        <object class="LSPrefDropdown" id="pref_experimental_present_mode">
 | 
				
			||||||
 | 
					            <property name="opt-name">Experimental Present Mode</property>
 | 
				
			||||||
 | 
					            <property name="default-selection">0</property>
 | 
				
			||||||
 | 
					            <property name="options">
 | 
				
			||||||
 | 
					            <object class="GtkStringList">
 | 
				
			||||||
 | 
					            <items>
 | 
				
			||||||
 | 
					                <item>VSync/FIFO</item>
 | 
				
			||||||
 | 
					                <item>Mailbox</item>
 | 
				
			||||||
 | 
					                <item>Immediate</item>
 | 
				
			||||||
 | 
					            </items>
 | 
				
			||||||
 | 
					            </object>
 | 
				
			||||||
 | 
					            </property>
 | 
				
			||||||
 | 
					        </object>
 | 
				
			||||||
 | 
					        </child>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </child>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </child>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </property>
 | 
				
			||||||
 | 
					</object>
 | 
				
			||||||
 | 
					</child>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					</interface>
 | 
				
			||||||
							
								
								
									
										39
									
								
								ui/rsc/pane/sidebar.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								ui/rsc/pane/sidebar.ui
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<interface>
 | 
				
			||||||
 | 
					<template class="LSPaneSidebar" parent="AdwNavigationPage">
 | 
				
			||||||
 | 
					<child>
 | 
				
			||||||
 | 
					<object class="AdwToolbarView">
 | 
				
			||||||
 | 
					    <!-- Header -->
 | 
				
			||||||
 | 
					    <child type="top">
 | 
				
			||||||
 | 
					    <object class="AdwHeaderBar">
 | 
				
			||||||
 | 
					    <property name="title-widget">
 | 
				
			||||||
 | 
					    <object class="AdwWindowTitle">
 | 
				
			||||||
 | 
					        <property name="title">Profiles</property>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </property>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </child>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- Content -->
 | 
				
			||||||
 | 
					    <!-- TODO: content -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- Footer -->
 | 
				
			||||||
 | 
					    <child type="bottom">
 | 
				
			||||||
 | 
					    <object class="GtkBox">
 | 
				
			||||||
 | 
					    <property name="orientation">vertical</property>
 | 
				
			||||||
 | 
					    <property name="margin-start">12</property>
 | 
				
			||||||
 | 
					    <property name="margin-end">12</property>
 | 
				
			||||||
 | 
					    <property name="margin-top">12</property>
 | 
				
			||||||
 | 
					    <property name="margin-bottom">12</property>
 | 
				
			||||||
 | 
					    <child>
 | 
				
			||||||
 | 
					    <object class="GtkButton">
 | 
				
			||||||
 | 
					        <property name="label">Create New Profile</property>
 | 
				
			||||||
 | 
					        <property name="css-classes">suggested-action</property>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </child>
 | 
				
			||||||
 | 
					    </object>
 | 
				
			||||||
 | 
					    </child>
 | 
				
			||||||
 | 
					</object>
 | 
				
			||||||
 | 
					</child>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					</interface>
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,8 @@
 | 
				
			||||||
<gresources>
 | 
					<gresources>
 | 
				
			||||||
  <gresource prefix="/gay/pancake/lsfg-vk/">
 | 
					  <gresource prefix="/gay/pancake/lsfg-vk/">
 | 
				
			||||||
    <file compressed="true" preprocess="xml-stripblanks">window.ui</file>
 | 
					    <file compressed="true" preprocess="xml-stripblanks">window.ui</file>
 | 
				
			||||||
 | 
					    <file compressed="true" preprocess="xml-stripblanks">pane/main.ui</file>
 | 
				
			||||||
 | 
					    <file compressed="true" preprocess="xml-stripblanks">pane/sidebar.ui</file>
 | 
				
			||||||
    <file compressed="true" preprocess="xml-stripblanks">pref/dropdown.ui</file>
 | 
					    <file compressed="true" preprocess="xml-stripblanks">pref/dropdown.ui</file>
 | 
				
			||||||
    <file compressed="true" preprocess="xml-stripblanks">pref/number.ui</file>
 | 
					    <file compressed="true" preprocess="xml-stripblanks">pref/number.ui</file>
 | 
				
			||||||
    <file compressed="true" preprocess="xml-stripblanks">pref/entry.ui</file>
 | 
					    <file compressed="true" preprocess="xml-stripblanks">pref/entry.ui</file>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										125
									
								
								ui/rsc/window.ui
									
										
									
									
									
								
							
							
						
						
									
										125
									
								
								ui/rsc/window.ui
									
										
									
									
									
								
							| 
						 | 
					@ -11,132 +11,11 @@
 | 
				
			||||||
        <property name="max-sidebar-width">300</property>
 | 
					        <property name="max-sidebar-width">300</property>
 | 
				
			||||||
        <!-- Split View: Left Sidebar -->
 | 
					        <!-- Split View: Left Sidebar -->
 | 
				
			||||||
        <property name="sidebar">
 | 
					        <property name="sidebar">
 | 
				
			||||||
        <object class="AdwNavigationPage">
 | 
					            <object class="LSPaneSidebar" id="sidebar"/>
 | 
				
			||||||
        <child>
 | 
					 | 
				
			||||||
        <object class="AdwToolbarView">
 | 
					 | 
				
			||||||
            <!-- Left Sidebar: Header -->
 | 
					 | 
				
			||||||
            <child type="top">
 | 
					 | 
				
			||||||
            <object class="AdwHeaderBar">
 | 
					 | 
				
			||||||
            <property name="title-widget">
 | 
					 | 
				
			||||||
            <object class="AdwWindowTitle">
 | 
					 | 
				
			||||||
                <property name="title">Profiles</property>
 | 
					 | 
				
			||||||
            </object>
 | 
					 | 
				
			||||||
            </property>
 | 
					 | 
				
			||||||
            </object>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            <!-- Left Sidebar: Content -->
 | 
					 | 
				
			||||||
            <!-- TODO: content -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            <!-- Left Sidebar: Footer -->
 | 
					 | 
				
			||||||
            <child type="bottom">
 | 
					 | 
				
			||||||
            <object class="GtkBox">
 | 
					 | 
				
			||||||
            <property name="orientation">vertical</property>
 | 
					 | 
				
			||||||
            <property name="margin-start">12</property>
 | 
					 | 
				
			||||||
            <property name="margin-end">12</property>
 | 
					 | 
				
			||||||
            <property name="margin-top">12</property>
 | 
					 | 
				
			||||||
            <property name="margin-bottom">12</property>
 | 
					 | 
				
			||||||
            <child>
 | 
					 | 
				
			||||||
            <object class="GtkButton">
 | 
					 | 
				
			||||||
                <property name="label">Create New Profile</property>
 | 
					 | 
				
			||||||
                <property name="css-classes">suggested-action</property>
 | 
					 | 
				
			||||||
            </object>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
            </object>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
        </object>
 | 
					 | 
				
			||||||
        </child>
 | 
					 | 
				
			||||||
        </object>
 | 
					 | 
				
			||||||
        </property>
 | 
					        </property>
 | 
				
			||||||
        <!-- Split View: Main Content -->
 | 
					        <!-- Split View: Main Content -->
 | 
				
			||||||
        <property name="content">
 | 
					        <property name="content">
 | 
				
			||||||
        <object class="AdwNavigationPage">
 | 
					            <object class="LSPaneMain" id="main"/>
 | 
				
			||||||
        <child>
 | 
					 | 
				
			||||||
        <object class="AdwToolbarView">
 | 
					 | 
				
			||||||
            <!-- Main Content: Header -->
 | 
					 | 
				
			||||||
            <child type="top">
 | 
					 | 
				
			||||||
            <object class="AdwHeaderBar">
 | 
					 | 
				
			||||||
            <property name="title-widget">
 | 
					 | 
				
			||||||
            <object class="AdwWindowTitle">
 | 
					 | 
				
			||||||
                <property name="title">lsfg-vk Configuration Menu</property>
 | 
					 | 
				
			||||||
            </object>
 | 
					 | 
				
			||||||
            </property>
 | 
					 | 
				
			||||||
            </object>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            <!-- Main Content: Content -->
 | 
					 | 
				
			||||||
            <property name="content">
 | 
					 | 
				
			||||||
            <object class="GtkScrolledWindow">
 | 
					 | 
				
			||||||
            <property name="hscrollbar-policy">never</property>
 | 
					 | 
				
			||||||
            <child>
 | 
					 | 
				
			||||||
            <object class="GtkBox" id="main_box">
 | 
					 | 
				
			||||||
            <property name="orientation">vertical</property>
 | 
					 | 
				
			||||||
            <property name="margin-start">48</property>
 | 
					 | 
				
			||||||
            <property name="margin-end">48</property>
 | 
					 | 
				
			||||||
            <property name="margin-top">32</property>
 | 
					 | 
				
			||||||
            <property name="margin-bottom">32</property>
 | 
					 | 
				
			||||||
            <property name="spacing">32</property>
 | 
					 | 
				
			||||||
            <child>
 | 
					 | 
				
			||||||
            <!-- Content: Frame Generation -->
 | 
					 | 
				
			||||||
            <object class="AdwPreferencesGroup">
 | 
					 | 
				
			||||||
                <property name="title">Frame Generation</property>
 | 
					 | 
				
			||||||
                <!-- Frame Generation: Multiplier -->
 | 
					 | 
				
			||||||
                <child>
 | 
					 | 
				
			||||||
                <object class="LSPrefNumber" id="pref_multiplier">
 | 
					 | 
				
			||||||
                    <property name="opt-name">Multiplier</property>
 | 
					 | 
				
			||||||
                </object>
 | 
					 | 
				
			||||||
                </child>
 | 
					 | 
				
			||||||
                <!-- Frame Generation: Flow Scale -->
 | 
					 | 
				
			||||||
                <child>
 | 
					 | 
				
			||||||
                <object class="LSPrefSlider" id="pref_flow_scale">
 | 
					 | 
				
			||||||
                    <property name="opt-name">Flow Scale</property>
 | 
					 | 
				
			||||||
                </object>
 | 
					 | 
				
			||||||
                </child>
 | 
					 | 
				
			||||||
                <!-- Frame Generation: Performance Mode -->
 | 
					 | 
				
			||||||
                <child>
 | 
					 | 
				
			||||||
                <object class="LSPrefSwitch" id="pref_performance_mode">
 | 
					 | 
				
			||||||
                    <property name="opt-name">Performance Mode</property>
 | 
					 | 
				
			||||||
                    <property name="default-state">false</property>
 | 
					 | 
				
			||||||
                </object>
 | 
					 | 
				
			||||||
                </child>
 | 
					 | 
				
			||||||
                </object>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
            <child>
 | 
					 | 
				
			||||||
                <!-- Content: Misc -->
 | 
					 | 
				
			||||||
                <object class="AdwPreferencesGroup">
 | 
					 | 
				
			||||||
                    <property name="title">Frame Generation</property>
 | 
					 | 
				
			||||||
                    <!-- Misc: HDR Mode -->
 | 
					 | 
				
			||||||
                    <child>
 | 
					 | 
				
			||||||
                    <object class="LSPrefSwitch" id="pref_hdr_mode">
 | 
					 | 
				
			||||||
                        <property name="opt-name">HDR Mode</property>
 | 
					 | 
				
			||||||
                        <property name="default-state">false</property>
 | 
					 | 
				
			||||||
                    </object>
 | 
					 | 
				
			||||||
                    </child>
 | 
					 | 
				
			||||||
                    <!-- Misc: Experimental Present Mode -->
 | 
					 | 
				
			||||||
                    <child>
 | 
					 | 
				
			||||||
                    <object class="LSPrefDropdown" id="pref_experimental_present_mode">
 | 
					 | 
				
			||||||
                        <property name="opt-name">Experimental Present Mode</property>
 | 
					 | 
				
			||||||
                        <property name="default-selection">0</property>
 | 
					 | 
				
			||||||
                        <property name="options">
 | 
					 | 
				
			||||||
                        <object class="GtkStringList">
 | 
					 | 
				
			||||||
                        <items>
 | 
					 | 
				
			||||||
                            <item>vsync/fifo</item>
 | 
					 | 
				
			||||||
                            <item>mailbox</item>
 | 
					 | 
				
			||||||
                            <item>immediate</item>
 | 
					 | 
				
			||||||
                        </items>
 | 
					 | 
				
			||||||
                        </object>
 | 
					 | 
				
			||||||
                        </property>
 | 
					 | 
				
			||||||
                    </object>
 | 
					 | 
				
			||||||
                    </child>
 | 
					 | 
				
			||||||
                </object>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
            </object>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
            </object>
 | 
					 | 
				
			||||||
            </property>
 | 
					 | 
				
			||||||
        </object>
 | 
					 | 
				
			||||||
        </child>
 | 
					 | 
				
			||||||
        </object>
 | 
					 | 
				
			||||||
        </property>
 | 
					        </property>
 | 
				
			||||||
        </object>
 | 
					        </object>
 | 
				
			||||||
    </property>
 | 
					    </property>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										129
									
								
								ui/src/config.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								ui/src/config.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,129 @@
 | 
				
			||||||
 | 
					use std::sync::{Arc, OnceLock, RwLock};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use anyhow::Context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod structs;
 | 
				
			||||||
 | 
					pub use structs::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Find the configuration file path based on environment variables
 | 
				
			||||||
 | 
					fn find_config_file() -> String {
 | 
				
			||||||
 | 
					    if let Some(path) = std::env::var("LSFG_CONFIG").ok() {
 | 
				
			||||||
 | 
					        return path;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Some(xdg) = std::env::var("XDG_CONFIG_HOME").ok() {
 | 
				
			||||||
 | 
					        return format!("{}/lsfg-vk/conf.toml", xdg);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Some(home) = std::env::var("HOME").ok() {
 | 
				
			||||||
 | 
					        return format!("{}/.config/lsfg-vk/conf.toml", home);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "conf.toml".to_string()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static CONFIG: OnceLock<Arc<RwLock<TomlConfig>>> = OnceLock::new();
 | 
				
			||||||
 | 
					static CONFIG_WRITER: OnceLock<std::sync::mpsc::Sender<()>> = OnceLock::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// Load the configuration from the file and create a writer.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					pub fn load_config() -> Result<(), anyhow::Error> {
 | 
				
			||||||
 | 
					    // load the configuration file
 | 
				
			||||||
 | 
					    let path = find_config_file();
 | 
				
			||||||
 | 
					    let data = std::fs::read(path)
 | 
				
			||||||
 | 
					        .context("Failed to read conf.toml")?;
 | 
				
			||||||
 | 
					    let config: TomlConfig = toml::from_slice(&data)
 | 
				
			||||||
 | 
					        .context("Failed to parse conf.toml")?;
 | 
				
			||||||
 | 
					    CONFIG.set(Arc::new(RwLock::new(config)))
 | 
				
			||||||
 | 
					        .ok().context("Failed to set configuration state")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // create the configuration writer thread
 | 
				
			||||||
 | 
					    let (tx, rx) = std::sync::mpsc::channel::<()>();
 | 
				
			||||||
 | 
					    CONFIG_WRITER.set(tx)
 | 
				
			||||||
 | 
					        .ok().context("Failed to set configuration writer")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::thread::spawn(move || {
 | 
				
			||||||
 | 
					        let config = CONFIG.get().unwrap();
 | 
				
			||||||
 | 
					        loop {
 | 
				
			||||||
 | 
					            // wait for a signal to write the configuration
 | 
				
			||||||
 | 
					            if let Err(_) = rx.recv() {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // wait a bit to avoid excessive writes
 | 
				
			||||||
 | 
					            std::thread::sleep(std::time::Duration::from_millis(200));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // empty the channel
 | 
				
			||||||
 | 
					            while rx.try_recv().is_ok() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // write the configuration
 | 
				
			||||||
 | 
					            eprintln!("Saving configuration...");
 | 
				
			||||||
 | 
					            if let Ok(config) = config.try_read() {
 | 
				
			||||||
 | 
					                if let Err(e) = save_config(&config) {
 | 
				
			||||||
 | 
					                    eprintln!("Failed to save configuration: {}", e);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    eprintln!("Configuration saved successfully");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                eprintln!("Failed to read configuration state");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// Get a snapshot of the current configuration
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					pub fn get_config() -> Result<TomlConfig, anyhow::Error> {
 | 
				
			||||||
 | 
					    let conf = CONFIG.get()
 | 
				
			||||||
 | 
					        .expect("Configuration not loaded")
 | 
				
			||||||
 | 
					        .try_read()
 | 
				
			||||||
 | 
					        .map(|config| config.clone());
 | 
				
			||||||
 | 
					    if let Ok(config) = conf {
 | 
				
			||||||
 | 
					        return Ok(config)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    anyhow::bail!("Failed to read configuration state")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// Safely edit the configuration.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					pub fn edit_config<F>(f: F) -> Result<(), anyhow::Error>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    F: FnOnce(&mut TomlConfig)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    let mut config = CONFIG.get()
 | 
				
			||||||
 | 
					        .expect("Configuration not loaded")
 | 
				
			||||||
 | 
					        .write()
 | 
				
			||||||
 | 
					        .map_err(|_| anyhow::anyhow!("Failed to acquire write lock on configuration"))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    f(&mut config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CONFIG_WRITER.get().unwrap().send(())
 | 
				
			||||||
 | 
					        .context("Failed to send configuration update signal")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// Save the configuration to the file
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// # Arguments
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// `config` - The configuration to save
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					pub fn save_config(config: &TomlConfig) -> Result<(), anyhow::Error> {
 | 
				
			||||||
 | 
					    let path = find_config_file();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let parent = std::path::Path::new(&path).parent()
 | 
				
			||||||
 | 
					        .context("Failed to get parent directory of config path")?;
 | 
				
			||||||
 | 
					    std::fs::create_dir_all(parent)
 | 
				
			||||||
 | 
					        .context("Failed to create config directory")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let data = toml::to_string(config)
 | 
				
			||||||
 | 
					        .context("Failed to serialize conf.toml")?;
 | 
				
			||||||
 | 
					    std::fs::write(path, data)
 | 
				
			||||||
 | 
					        .context("Failed to write conf.toml")?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										68
									
								
								ui/src/config/structs.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								ui/src/config/structs.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// multiplier
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Deserialize, Serialize)]
 | 
				
			||||||
 | 
					pub struct Multiplier(i64);
 | 
				
			||||||
 | 
					impl Default for Multiplier {
 | 
				
			||||||
 | 
					    fn default() -> Self { Multiplier(2) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl From<i64> for Multiplier {
 | 
				
			||||||
 | 
					    fn from(value: i64) -> Self { Multiplier(value) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// flow scale
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Deserialize, Serialize)]
 | 
				
			||||||
 | 
					pub struct FlowScale(f64);
 | 
				
			||||||
 | 
					impl Default for FlowScale {
 | 
				
			||||||
 | 
					    fn default() -> Self { FlowScale(1.0) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl From<f64> for FlowScale {
 | 
				
			||||||
 | 
					    fn from(value: f64) -> Self { FlowScale(value) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// present mode
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Deserialize, Serialize)]
 | 
				
			||||||
 | 
					pub enum PresentMode {
 | 
				
			||||||
 | 
					    #[serde(rename = "fifo", alias = "vsync")]
 | 
				
			||||||
 | 
					    Vsync,
 | 
				
			||||||
 | 
					    #[serde(rename = "immediate")]
 | 
				
			||||||
 | 
					    Immediate,
 | 
				
			||||||
 | 
					    #[serde(rename = "mailbox")]
 | 
				
			||||||
 | 
					    Mailbox,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl Default for PresentMode {
 | 
				
			||||||
 | 
					    fn default() -> Self { PresentMode::Vsync }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Global configuration for the application
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Default, Deserialize, Serialize)]
 | 
				
			||||||
 | 
					pub struct TomlGlobal {
 | 
				
			||||||
 | 
					    pub dll: Option<String>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Game-specific configuration
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Deserialize, Serialize)]
 | 
				
			||||||
 | 
					pub struct TomlGame {
 | 
				
			||||||
 | 
					    pub exe: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[serde(default)]
 | 
				
			||||||
 | 
					    pub multiplier: Multiplier,
 | 
				
			||||||
 | 
					    #[serde(default)]
 | 
				
			||||||
 | 
					    pub flow_scale: FlowScale,
 | 
				
			||||||
 | 
					    #[serde(default)]
 | 
				
			||||||
 | 
					    pub performance_mode: bool,
 | 
				
			||||||
 | 
					    #[serde(default)]
 | 
				
			||||||
 | 
					    pub hdr_mode: bool,
 | 
				
			||||||
 | 
					    #[serde(default)]
 | 
				
			||||||
 | 
					    pub experimental_present_mode: PresentMode
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Main configuration structure
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Deserialize, Serialize)]
 | 
				
			||||||
 | 
					pub struct TomlConfig {
 | 
				
			||||||
 | 
					    pub version: i64,
 | 
				
			||||||
 | 
					    #[serde(default)]
 | 
				
			||||||
 | 
					    pub global: TomlGlobal,
 | 
				
			||||||
 | 
					    #[serde(default)]
 | 
				
			||||||
 | 
					    pub game: Vec<TomlGame>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										131
									
								
								ui/src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										131
									
								
								ui/src/main.rs
									
										
									
									
									
								
							| 
						 | 
					@ -1,9 +1,130 @@
 | 
				
			||||||
mod ui;
 | 
					use std::sync::{Arc, OnceLock, RwLock};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use adw::{self, subclass::prelude::ObjectSubclassIsExt};
 | 
				
			||||||
 | 
					use gtk::{gio, prelude::*};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::config::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod wrapper;
 | 
				
			||||||
 | 
					mod config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const APP_ID: &str = "gay.pancake.lsfg-vk.ConfigurationUi";
 | 
					const APP_ID: &str = "gay.pancake.lsfg-vk.ConfigurationUi";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					#[derive(Debug)]
 | 
				
			||||||
    let app = ui::App::new(APP_ID)
 | 
					struct State {
 | 
				
			||||||
        .expect("Failed to create application");
 | 
					    // ui state
 | 
				
			||||||
    app.run()
 | 
					    selected_game: Option<usize>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static STATE: OnceLock<Arc<RwLock<State>>> = OnceLock::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    gio::resources_register_include!("ui.gresource")
 | 
				
			||||||
 | 
					        .expect("Failed to register resources");
 | 
				
			||||||
 | 
					    config::load_config()
 | 
				
			||||||
 | 
					        .expect("Failed to load configuration");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // prepare the application state
 | 
				
			||||||
 | 
					    STATE.set(Arc::new(RwLock::new(State {
 | 
				
			||||||
 | 
					        selected_game: Some(0)
 | 
				
			||||||
 | 
					    }))).expect("Failed to set application state");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // start the application
 | 
				
			||||||
 | 
					    let app = adw::Application::builder()
 | 
				
			||||||
 | 
					        .application_id(APP_ID)
 | 
				
			||||||
 | 
					        .build();
 | 
				
			||||||
 | 
					    app.connect_activate(build_ui);
 | 
				
			||||||
 | 
					    app.run();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn build_ui(app: &adw::Application) {
 | 
				
			||||||
 | 
					    // create the main window
 | 
				
			||||||
 | 
					    let window = wrapper::Window::new(app);
 | 
				
			||||||
 | 
					    window.set_application(Some(app));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // register main pane signals
 | 
				
			||||||
 | 
					    let main = window.imp().main.imp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let pref_multiplier = main.pref_multiplier.imp();
 | 
				
			||||||
 | 
					    pref_multiplier.number.connect_value_changed(|dropdown| {
 | 
				
			||||||
 | 
					        if let Ok(state) = STATE.get().unwrap().try_read() {
 | 
				
			||||||
 | 
					            if state.selected_game.is_none() {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let multiplier = (dropdown.value() as i64).into();
 | 
				
			||||||
 | 
					            let _ = config::edit_config(|config| {
 | 
				
			||||||
 | 
					                config.game[state.selected_game.unwrap()]
 | 
				
			||||||
 | 
					                    .multiplier = multiplier;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let pref_flow_scale = main.pref_flow_scale.imp();
 | 
				
			||||||
 | 
					    pref_flow_scale.slider.connect_value_changed(|slider| {
 | 
				
			||||||
 | 
					        if let Ok(state) = STATE.get().unwrap().try_read() {
 | 
				
			||||||
 | 
					            if state.selected_game.is_none() {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let flow_scale = (slider.value() / 100.0).into();
 | 
				
			||||||
 | 
					            let _ = config::edit_config(|config| {
 | 
				
			||||||
 | 
					                config.game[state.selected_game.unwrap()]
 | 
				
			||||||
 | 
					                    .flow_scale = flow_scale;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let pref_performance_mode = main.pref_performance_mode.imp();
 | 
				
			||||||
 | 
					    pref_performance_mode.switch.connect_state_notify(|switch| {
 | 
				
			||||||
 | 
					        if let Ok(state) = STATE.get().unwrap().try_read() {
 | 
				
			||||||
 | 
					            if state.selected_game.is_none() {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let performance_mode = switch.state();
 | 
				
			||||||
 | 
					            let _ = config::edit_config(|config| {
 | 
				
			||||||
 | 
					                config.game[state.selected_game.unwrap()]
 | 
				
			||||||
 | 
					                    .performance_mode = performance_mode;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let pref_hdr_mode = main.pref_hdr_mode.imp();
 | 
				
			||||||
 | 
					    pref_hdr_mode.switch.connect_state_notify(|switch| {
 | 
				
			||||||
 | 
					        if let Ok(state) = STATE.get().unwrap().try_read() {
 | 
				
			||||||
 | 
					            if state.selected_game.is_none() {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let hdr_mode = switch.state();
 | 
				
			||||||
 | 
					            let _ = config::edit_config(|config| {
 | 
				
			||||||
 | 
					                config.game[state.selected_game.unwrap()]
 | 
				
			||||||
 | 
					                    .hdr_mode = hdr_mode;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let pref_experimental_present_mode = main.pref_experimental_present_mode.imp();
 | 
				
			||||||
 | 
					    pref_experimental_present_mode.dropdown.connect_selected_notify(|dropdown| {
 | 
				
			||||||
 | 
					        if let Ok(state) = STATE.get().unwrap().try_read() {
 | 
				
			||||||
 | 
					            if state.selected_game.is_none() {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let selected = match dropdown.selected() {
 | 
				
			||||||
 | 
					                0 => PresentMode::Vsync,
 | 
				
			||||||
 | 
					                1 => PresentMode::Mailbox,
 | 
				
			||||||
 | 
					                2 => PresentMode::Immediate,
 | 
				
			||||||
 | 
					                _ => PresentMode::Vsync,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            config::edit_config(|config| {
 | 
				
			||||||
 | 
					                config.game[state.selected_game.unwrap()]
 | 
				
			||||||
 | 
					                    .experimental_present_mode = selected;
 | 
				
			||||||
 | 
					            }).unwrap();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // present the window
 | 
				
			||||||
 | 
					    window.present();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										36
									
								
								ui/src/ui.rs
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								ui/src/ui.rs
									
										
									
									
									
								
							| 
						 | 
					@ -1,36 +0,0 @@
 | 
				
			||||||
use std::sync::Arc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use adw;
 | 
					 | 
				
			||||||
use gtk::{gio, glib, prelude::*};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod ui;
 | 
					 | 
				
			||||||
pub mod pref;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct App {
 | 
					 | 
				
			||||||
    app: Arc<adw::Application>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl App {
 | 
					 | 
				
			||||||
    pub fn new(appid: &str) -> Result<Self, glib::Error> {
 | 
					 | 
				
			||||||
        gio::resources_register_include!("ui.gresource")?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let app = adw::Application::builder()
 | 
					 | 
				
			||||||
            .application_id(appid)
 | 
					 | 
				
			||||||
            .build();
 | 
					 | 
				
			||||||
        app.connect_activate(Self::build_ui);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(App {
 | 
					 | 
				
			||||||
            app: Arc::new(app)
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn build_ui(app: &adw::Application) {
 | 
					 | 
				
			||||||
        let window = ui::Window::new(app);
 | 
					 | 
				
			||||||
        window.set_application(Some(app));
 | 
					 | 
				
			||||||
        window.present();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn run(self){
 | 
					 | 
				
			||||||
        self.app.run();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,29 +0,0 @@
 | 
				
			||||||
use gtk::glib;
 | 
					 | 
				
			||||||
use gtk;
 | 
					 | 
				
			||||||
use adw;
 | 
					 | 
				
			||||||
use gtk::glib::types::StaticTypeExt;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod window;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
glib::wrapper! {
 | 
					 | 
				
			||||||
    pub struct Window(ObjectSubclass<window::Window>)
 | 
					 | 
				
			||||||
        @extends
 | 
					 | 
				
			||||||
            adw::ApplicationWindow, adw::Window,
 | 
					 | 
				
			||||||
            gtk::ApplicationWindow, gtk::Window, gtk::Widget,
 | 
					 | 
				
			||||||
        @implements
 | 
					 | 
				
			||||||
            gtk::gio::ActionGroup, gtk::gio::ActionMap,
 | 
					 | 
				
			||||||
            gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget,
 | 
					 | 
				
			||||||
            gtk::Native, gtk::Root, gtk::ShortcutManager;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Window {
 | 
					 | 
				
			||||||
    pub fn new(app: &adw::Application) -> Self {
 | 
					 | 
				
			||||||
        super::pref::PrefDropdown::ensure_type();
 | 
					 | 
				
			||||||
        super::pref::PrefSwitch::ensure_type();
 | 
					 | 
				
			||||||
        super::pref::PrefEntry::ensure_type();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        glib::Object::builder()
 | 
					 | 
				
			||||||
            .property("application", app)
 | 
					 | 
				
			||||||
            .build()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,73 +0,0 @@
 | 
				
			||||||
use gtk::{prelude::RangeExt, subclass::prelude::*};
 | 
					 | 
				
			||||||
use adw::subclass::prelude::*;
 | 
					 | 
				
			||||||
use crate::ui::pref::*;
 | 
					 | 
				
			||||||
use gtk::{glib, CompositeTemplate};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(CompositeTemplate, Default)]
 | 
					 | 
				
			||||||
#[template(resource = "/gay/pancake/lsfg-vk/window.ui")]
 | 
					 | 
				
			||||||
pub struct Window {
 | 
					 | 
				
			||||||
    // main config elements
 | 
					 | 
				
			||||||
    #[template_child]
 | 
					 | 
				
			||||||
    pref_multiplier: TemplateChild<PrefNumber>,
 | 
					 | 
				
			||||||
    #[template_child]
 | 
					 | 
				
			||||||
    pref_flow_scale: TemplateChild<PrefSlider>,
 | 
					 | 
				
			||||||
    #[template_child]
 | 
					 | 
				
			||||||
    pref_performance_mode: TemplateChild<PrefSwitch>,
 | 
					 | 
				
			||||||
    #[template_child]
 | 
					 | 
				
			||||||
    pref_hdr_mode: TemplateChild<PrefSwitch>,
 | 
					 | 
				
			||||||
    #[template_child]
 | 
					 | 
				
			||||||
    pref_experimental_present_mode: TemplateChild<PrefDropdown>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[glib::object_subclass]
 | 
					 | 
				
			||||||
impl ObjectSubclass for Window {
 | 
					 | 
				
			||||||
    const NAME: &'static str = "LSApplicationWindow";
 | 
					 | 
				
			||||||
    type Type = super::Window;
 | 
					 | 
				
			||||||
    type ParentType = adw::ApplicationWindow;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn class_init(klass: &mut Self::Class) {
 | 
					 | 
				
			||||||
        klass.bind_template();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
 | 
					 | 
				
			||||||
        obj.init_template();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl ObjectImpl for Window {
 | 
					 | 
				
			||||||
    fn constructed(&self) {
 | 
					 | 
				
			||||||
        self.parent_constructed();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.pref_multiplier.get()
 | 
					 | 
				
			||||||
            .imp().number.get().connect_value_changed(|dropdown| {
 | 
					 | 
				
			||||||
                let selected = dropdown.value();
 | 
					 | 
				
			||||||
                println!("Multiplier changed: {}", selected);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        self.pref_flow_scale.get()
 | 
					 | 
				
			||||||
            .imp().slider.get().connect_value_changed(|slider| {
 | 
					 | 
				
			||||||
                let value = slider.value();
 | 
					 | 
				
			||||||
                println!("Flow scale changed: {}", value);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        self.pref_performance_mode.get()
 | 
					 | 
				
			||||||
            .imp().switch.get().connect_state_notify(|switch| {
 | 
					 | 
				
			||||||
                let state = switch.state();
 | 
					 | 
				
			||||||
                println!("Performance mode changed: {}", state);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        self.pref_hdr_mode.get()
 | 
					 | 
				
			||||||
            .imp().switch.get().connect_state_notify(|switch| {
 | 
					 | 
				
			||||||
                let state = switch.state();
 | 
					 | 
				
			||||||
                println!("HDR mode changed: {}", state);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        self.pref_experimental_present_mode.get()
 | 
					 | 
				
			||||||
            .imp().dropdown.get().connect_selected_notify(|dropdown| {
 | 
					 | 
				
			||||||
                let selected = dropdown.selected();
 | 
					 | 
				
			||||||
                println!("Experimental present mode changed: {}", selected);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl WidgetImpl for Window {}
 | 
					 | 
				
			||||||
impl WindowImpl for Window {}
 | 
					 | 
				
			||||||
impl ApplicationWindowImpl for Window {}
 | 
					 | 
				
			||||||
impl AdwWindowImpl for Window {}
 | 
					 | 
				
			||||||
impl AdwApplicationWindowImpl for Window {}
 | 
					 | 
				
			||||||
							
								
								
									
										77
									
								
								ui/src/wrapper.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								ui/src/wrapper.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,77 @@
 | 
				
			||||||
 | 
					use gtk::glib;
 | 
				
			||||||
 | 
					use gtk;
 | 
				
			||||||
 | 
					use adw;
 | 
				
			||||||
 | 
					use gtk::glib::types::StaticTypeExt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod pane;
 | 
				
			||||||
 | 
					pub mod pref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod imp {
 | 
				
			||||||
 | 
					    use gtk::subclass::prelude::*;
 | 
				
			||||||
 | 
					    use adw::subclass::prelude::*;
 | 
				
			||||||
 | 
					    use crate::wrapper::pane::*;
 | 
				
			||||||
 | 
					    use gtk::{glib, CompositeTemplate};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[derive(CompositeTemplate, Default)]
 | 
				
			||||||
 | 
					    #[template(resource = "/gay/pancake/lsfg-vk/window.ui")]
 | 
				
			||||||
 | 
					    pub struct Window {
 | 
				
			||||||
 | 
					        #[template_child]
 | 
				
			||||||
 | 
					        pub main: TemplateChild<PaneMain>,
 | 
				
			||||||
 | 
					        #[template_child]
 | 
				
			||||||
 | 
					        pub sidebar: TemplateChild<PaneSidebar>,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[glib::object_subclass]
 | 
				
			||||||
 | 
					    impl ObjectSubclass for Window {
 | 
				
			||||||
 | 
					        const NAME: &'static str = "LSApplicationWindow";
 | 
				
			||||||
 | 
					        type Type = super::Window;
 | 
				
			||||||
 | 
					        type ParentType = adw::ApplicationWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fn class_init(klass: &mut Self::Class) {
 | 
				
			||||||
 | 
					            klass.bind_template();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
 | 
				
			||||||
 | 
					            obj.init_template();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl ObjectImpl for Window {
 | 
				
			||||||
 | 
					        fn constructed(&self) {
 | 
				
			||||||
 | 
					            self.parent_constructed();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl WidgetImpl for Window {}
 | 
				
			||||||
 | 
					    impl WindowImpl for Window {}
 | 
				
			||||||
 | 
					    impl ApplicationWindowImpl for Window {}
 | 
				
			||||||
 | 
					    impl AdwWindowImpl for Window {}
 | 
				
			||||||
 | 
					    impl AdwApplicationWindowImpl for Window {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					glib::wrapper! {
 | 
				
			||||||
 | 
					    pub struct Window(ObjectSubclass<imp::Window>)
 | 
				
			||||||
 | 
					        @extends
 | 
				
			||||||
 | 
					            adw::ApplicationWindow, adw::Window,
 | 
				
			||||||
 | 
					            gtk::ApplicationWindow, gtk::Window, gtk::Widget,
 | 
				
			||||||
 | 
					        @implements
 | 
				
			||||||
 | 
					            gtk::gio::ActionGroup, gtk::gio::ActionMap,
 | 
				
			||||||
 | 
					            gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget,
 | 
				
			||||||
 | 
					            gtk::Native, gtk::Root, gtk::ShortcutManager;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Window {
 | 
				
			||||||
 | 
					    pub fn new(app: &adw::Application) -> Self {
 | 
				
			||||||
 | 
					        pref::PrefDropdown::ensure_type();
 | 
				
			||||||
 | 
					        pref::PrefEntry::ensure_type();
 | 
				
			||||||
 | 
					        pref::PrefNumber::ensure_type();
 | 
				
			||||||
 | 
					        pref::PrefSlider::ensure_type();
 | 
				
			||||||
 | 
					        pref::PrefSwitch::ensure_type();
 | 
				
			||||||
 | 
					        pane::PaneMain::ensure_type();
 | 
				
			||||||
 | 
					        pane::PaneSidebar::ensure_type();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        glib::Object::builder()
 | 
				
			||||||
 | 
					            .property("application", app)
 | 
				
			||||||
 | 
					            .build()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								ui/src/wrapper/pane.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ui/src/wrapper/pane.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					use gtk::glib;
 | 
				
			||||||
 | 
					use gtk;
 | 
				
			||||||
 | 
					use adw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod main;
 | 
				
			||||||
 | 
					pub mod sidebar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					glib::wrapper! {
 | 
				
			||||||
 | 
					    pub struct PaneMain(ObjectSubclass<main::PaneMain>)
 | 
				
			||||||
 | 
					        @extends
 | 
				
			||||||
 | 
					            adw::NavigationPage, gtk::Widget,
 | 
				
			||||||
 | 
					        @implements
 | 
				
			||||||
 | 
					            gtk::Accessible, gtk::Actionable, gtk::Buildable, gtk::ConstraintTarget;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					glib::wrapper! {
 | 
				
			||||||
 | 
					    pub struct PaneSidebar(ObjectSubclass<sidebar::PaneSidebar>)
 | 
				
			||||||
 | 
					        @extends
 | 
				
			||||||
 | 
					            adw::NavigationPage, gtk::Widget,
 | 
				
			||||||
 | 
					        @implements
 | 
				
			||||||
 | 
					            gtk::Accessible, gtk::Actionable, gtk::Buildable, gtk::ConstraintTarget;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PaneMain {
 | 
				
			||||||
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
 | 
					        glib::Object::new()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PaneSidebar {
 | 
				
			||||||
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
 | 
					        glib::Object::new()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										43
									
								
								ui/src/wrapper/pane/main.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								ui/src/wrapper/pane/main.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					use gtk::glib;
 | 
				
			||||||
 | 
					use gtk::subclass::prelude::*;
 | 
				
			||||||
 | 
					use adw::subclass::prelude::*;
 | 
				
			||||||
 | 
					use crate::wrapper::pref::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(gtk::CompositeTemplate, Default)]
 | 
				
			||||||
 | 
					#[template(resource = "/gay/pancake/lsfg-vk/pane/main.ui")]
 | 
				
			||||||
 | 
					pub struct PaneMain {
 | 
				
			||||||
 | 
					    #[template_child]
 | 
				
			||||||
 | 
					    pub pref_multiplier: TemplateChild<PrefNumber>,
 | 
				
			||||||
 | 
					    #[template_child]
 | 
				
			||||||
 | 
					    pub pref_flow_scale: TemplateChild<PrefSlider>,
 | 
				
			||||||
 | 
					    #[template_child]
 | 
				
			||||||
 | 
					    pub pref_performance_mode: TemplateChild<PrefSwitch>,
 | 
				
			||||||
 | 
					    #[template_child]
 | 
				
			||||||
 | 
					    pub pref_hdr_mode: TemplateChild<PrefSwitch>,
 | 
				
			||||||
 | 
					    #[template_child]
 | 
				
			||||||
 | 
					    pub pref_experimental_present_mode: TemplateChild<PrefDropdown>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[glib::object_subclass]
 | 
				
			||||||
 | 
					impl ObjectSubclass for PaneMain {
 | 
				
			||||||
 | 
					    const NAME: &'static str = "LSPaneMain";
 | 
				
			||||||
 | 
					    type Type = super::PaneMain;
 | 
				
			||||||
 | 
					    type ParentType = adw::NavigationPage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn class_init(klass: &mut Self::Class) {
 | 
				
			||||||
 | 
					        klass.bind_template();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
 | 
				
			||||||
 | 
					        obj.init_template();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ObjectImpl for PaneMain {
 | 
				
			||||||
 | 
					    fn constructed(&self) {
 | 
				
			||||||
 | 
					        self.parent_constructed();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl WidgetImpl for PaneMain {}
 | 
				
			||||||
 | 
					impl NavigationPageImpl for PaneMain {}
 | 
				
			||||||
							
								
								
									
										33
									
								
								ui/src/wrapper/pane/sidebar.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ui/src/wrapper/pane/sidebar.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					use gtk::glib;
 | 
				
			||||||
 | 
					use gtk::subclass::prelude::*;
 | 
				
			||||||
 | 
					use adw::subclass::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(gtk::CompositeTemplate, Default)]
 | 
				
			||||||
 | 
					#[template(resource = "/gay/pancake/lsfg-vk/pane/sidebar.ui")]
 | 
				
			||||||
 | 
					pub struct PaneSidebar {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[glib::object_subclass]
 | 
				
			||||||
 | 
					impl ObjectSubclass for PaneSidebar {
 | 
				
			||||||
 | 
					    const NAME: &'static str = "LSPaneSidebar";
 | 
				
			||||||
 | 
					    type Type = super::PaneSidebar;
 | 
				
			||||||
 | 
					    type ParentType = adw::NavigationPage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn class_init(klass: &mut Self::Class) {
 | 
				
			||||||
 | 
					        klass.bind_template();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
 | 
				
			||||||
 | 
					        obj.init_template();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ObjectImpl for PaneSidebar {
 | 
				
			||||||
 | 
					    fn constructed(&self) {
 | 
				
			||||||
 | 
					        self.parent_constructed();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl WidgetImpl for PaneSidebar {}
 | 
				
			||||||
 | 
					impl NavigationPageImpl for PaneSidebar {}
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue