Browse Source

Progress on controls

Benjamin Schaaf 3 years ago
parent
commit
f9e6576266
5 changed files with 302 additions and 204 deletions
  1. 97 134
      data/camera.ui
  2. 42 0
      data/controls-popover.ui
  3. 2 0
      data/org.postmarketos.Megapixels.gresource.xml
  4. 32 0
      data/shutter-symbolic.svg
  5. 129 70
      src/main.c

+ 97 - 134
data/camera.ui

@@ -1,11 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk" version="4.0"/>
-  <object class="GtkAdjustment" id="control_adj">
-    <property name="upper">100</property>
-    <property name="step-increment">1</property>
-    <property name="page-increment">10</property>
-  </object>
   <object class="GtkWindow" id="window">
     <property name="can-focus">0</property>
     <property name="default-width">360</property>
@@ -18,7 +13,7 @@
           <object class="GtkStackPage">
             <property name="name">main</property>
             <property name="child">
-              <object class="GtkOverlay" id="page_main">
+              <object class="GtkOverlay">
                 <property name="can-focus">0</property>
                 <child>
                   <object class="GtkGLArea" id="preview">
@@ -28,100 +23,65 @@
                   </object>
                 </child>
                 <child type="overlay">
-                  <object class="GtkBox" id="control_box">
-                    <property name="visible">0</property>
+                  <object class="GtkBox">
+                    <property name="orientation">vertical</property>
+                    <property name="vexpand">1</property>
+                    <property name="hexpand">1</property>
+                    <property name="spacing">5</property>
                     <property name="can-focus">0</property>
+                    <property name="margin-start">5</property>
+                    <property name="margin-end">5</property>
+                    <property name="margin-bottom">5</property>
+                    <property name="margin-top">5</property>
                     <child>
                       <object class="GtkBox">
+                        <property name="orientation">horizontal</property>
                         <property name="hexpand">1</property>
+                        <property name="valign">start</property>
                         <property name="can-focus">0</property>
-                        <property name="margin-start">10</property>
-                        <property name="margin-end">10</property>
-                        <property name="margin-top">10</property>
-                        <property name="margin-bottom">10</property>
-                        <child>
-                          <object class="GtkLabel" id="control_name">
-                            <property name="can-focus">0</property>
-                            <property name="margin-end">10</property>
-                            <property name="label" translatable="yes">ISO</property>
-                          </object>
-                        </child>
+                        <property name="spacing">5</property>
                         <child>
-                          <object class="GtkScale" id="control_slider">
-                            <property name="hexpand">1</property>
-                            <property name="adjustment">control_adj</property>
-                            <property name="round-digits">1</property>
+                          <object class="GtkButton" id="iso-controls-button">
+                            <property name="valign">start</property>
+                            <property name="label">ISO</property>
+                            <style>
+                              <class name="circular"/>
+                            </style>
                           </object>
                         </child>
                         <child>
-                          <object class="GtkToggleButton" id="control_auto">
-                            <property name="label" translatable="yes">Auto</property>
-                            <property name="receives-default">1</property>
-                            <property name="margin-start">10</property>
+                          <object class="GtkButton" id="shutter-controls-button">
+                            <property name="valign">start</property>
+                            <property name="icon-name">shutter-symbolic</property>
+                            <style>
+                              <class name="circular"/>
+                            </style>
                           </object>
                         </child>
                       </object>
                     </child>
-                    <style>
-                      <class name="controlbox"/>
-                    </style>
-                  </object>
-                </child>
-                <child type="overlay">
-                  <object class="GtkBox">
-                    <property name="orientation">horizontal</property>
-                    <property name="hexpand">1</property>
-                    <property name="valign">end</property>
-                    <property name="homogeneous">0</property>
-                    <property name="can-focus">0</property>
-                    <property name="margin-bottom">5</property>
                     <child>
-                      <object class="GtkBox">
-                        <property name="orientation">horizontal</property>
-                        <property name="hexpand">1</property>
-                        <property name="valign">end</property>
-                        <property name="can-focus">0</property>
-                        <property name="margin-start">5</property>
-                        <property name="spacing">5</property>
+                      <object class="GtkButton">
+                        <property name="visible">0</property>
+                        <property name="halign">start</property>
                         <child>
-                          <object class="GtkButton">
-                            <property name="action-name">app.open-settings</property>
-                            <property name="receives-default">1</property>
+                          <object class="GtkBox">
+                            <property name="orientation">horizontal</property>
+                            <property name="spacing">10</property>
                             <child>
-                              <object class="GtkImage">
-                                <property name="can-focus">0</property>
-                                <property name="icon-name">settings-symbolic</property>
+                              <object class="GtkLabel">
+                                <property name="label">Error</property>
                               </object>
                             </child>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkButton">
-                            <property name="action-name">app.switch-camera</property>
-                            <property name="receives-default">1</property>
                             <child>
                               <object class="GtkImage">
-                                <property name="can-focus">0</property>
-                                <property name="icon-name">switch-camera-symbolic</property>
+                                <property name="icon-name">dialog-warning-symbolic</property>
                               </object>
                             </child>
                           </object>
                         </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton">
-                        <property name="action-name">app.capture</property>
-                        <property name="receives-default">1</property>
-                        <child>
-                          <object class="GtkImage">
-                            <property name="pixel-size">60</property>
-                            <property name="can-focus">0</property>
-                            <property name="icon-name">shutter-button-symbolic</property>
-                          </object>
-                        </child>
                         <style>
-                          <class name="circular"/>
+                          <class name="destructive-action"/>
                         </style>
                       </object>
                     </child>
@@ -129,86 +89,89 @@
                       <object class="GtkBox">
                         <property name="orientation">horizontal</property>
                         <property name="hexpand">1</property>
-                        <property name="halign">end</property>
+                        <property name="vexpand">1</property>
                         <property name="valign">end</property>
                         <property name="can-focus">0</property>
-                        <property name="margin-end">5</property>
-                        <property name="spacing">5</property>
                         <child>
-                          <object class="GtkButton">
-                            <property name="action-name">app.open-last</property>
-                            <property name="receives-default">1</property>
+                          <object class="GtkBox">
+                            <property name="orientation">horizontal</property>
+                            <property name="hexpand">1</property>
+                            <property name="valign">end</property>
+                            <property name="can-focus">0</property>
+                            <property name="spacing">5</property>
                             <child>
-                              <object class="GtkStack" id="open_last_stack">
-                                <property name="can-focus">0</property>
-                                <child>
-                                  <object class="GtkImage" id="thumb_last">
-                                    <property name="width-request">24</property>
-                                    <property name="height-request">24</property>
-                                    <property name="can-focus">0</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkSpinner" id="process_spinner">
-                                    <property name="width-request">24</property>
-                                    <property name="height-request">24</property>
-                                    <property name="can-focus">0</property>
-                                  </object>
-                                </child>
+                              <object class="GtkButton">
+                                <property name="action-name">app.open-settings</property>
+                                <property name="icon-name">settings-symbolic</property>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkButton">
+                                <property name="action-name">app.switch-camera</property>
+                                <property name="icon-name">switch-camera-symbolic</property>
                               </object>
                             </child>
                           </object>
                         </child>
                         <child>
                           <object class="GtkButton">
-                            <property name="action-name">app.open-photos</property>
-                            <property name="receives-default">1</property>
+                            <property name="action-name">app.capture</property>
                             <child>
                               <object class="GtkImage">
+                                <property name="pixel-size">60</property>
                                 <property name="can-focus">0</property>
-                                <property name="icon-name">folder-symbolic</property>
+                                <property name="icon-name">shutter-button-symbolic</property>
                               </object>
                             </child>
+                            <style>
+                              <class name="circular"/>
+                            </style>
                           </object>
                         </child>
-                      </object>
-                    </child>
-                    <style>
-                      <class name="button-overlay"/>
-                    </style>
-                  </object>
-                </child>
-                <child type="overlay">
-                  <object class="GtkBox" id="error_box">
-                    <property name="visible">0</property>
-                    <property name="can-focus">0</property>
-                    <child>
-                      <object class="GtkBox">
-                        <property name="hexpand">1</property>
-                        <property name="can-focus">0</property>
-                        <property name="margin-start">10</property>
-                        <property name="margin-end">10</property>
-                        <property name="margin-top">10</property>
-                        <property name="margin-bottom">10</property>
-                        <property name="spacing">10</property>
                         <child>
-                          <object class="GtkLabel" id="error_message">
+                          <object class="GtkBox">
+                            <property name="orientation">horizontal</property>
                             <property name="hexpand">1</property>
+                            <property name="halign">end</property>
+                            <property name="valign">end</property>
                             <property name="can-focus">0</property>
-                            <property name="halign">start</property>
-                            <property name="label" translatable="yes">No error</property>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkButton" id="error_close">
-                            <property name="label">gtk-close</property>
-                            <property name="receives-default">1</property>
+                            <property name="spacing">5</property>
+                            <child>
+                              <object class="GtkButton">
+                                <property name="action-name">app.open-last</property>
+                                <child>
+                                  <object class="GtkStack" id="open_last_stack">
+                                    <property name="can-focus">0</property>
+                                    <child>
+                                      <object class="GtkImage" id="thumb_last">
+                                        <property name="width-request">24</property>
+                                        <property name="height-request">24</property>
+                                        <property name="can-focus">0</property>
+                                      </object>
+                                    </child>
+                                    <child>
+                                      <object class="GtkSpinner" id="process_spinner">
+                                        <property name="width-request">24</property>
+                                        <property name="height-request">24</property>
+                                        <property name="can-focus">0</property>
+                                      </object>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkButton">
+                                <property name="action-name">app.open-photos</property>
+                                <property name="icon-name">folder-symbolic</property>
+                              </object>
+                            </child>
                           </object>
                         </child>
                       </object>
                     </child>
                     <style>
-                      <class name="errorbox"/>
+                      <class name="button-overlay"/>
                     </style>
                   </object>
                 </child>
@@ -221,7 +184,7 @@
             <property name="name">settings</property>
             <property name="title" translatable="yes">page1</property>
             <property name="child">
-              <object class="GtkScrolledWindow" id="page_settings">
+              <object class="GtkScrolledWindow">
                 <property name="child">
                   <object class="GtkViewport">
                     <property name="can-focus">0</property>
@@ -238,11 +201,11 @@
                           <object class="GtkBox">
                             <property name="can-focus">0</property>
                             <child>
-                              <object class="GtkButton" id="settings_back">
+                              <object class="GtkButton">
                                 <property name="label" translatable="yes">Back</property>
-                                <property name="receives-default">1</property>
                                 <property name="margin-start">10</property>
                                 <property name="margin-end">10</property>
+                                <property name="action-name">app.close-settings</property>
                                 <style>
                                   <class name="suggested-action"/>
                                 </style>
@@ -251,7 +214,7 @@
                             <child>
                               <object class="GtkLabel">
                                 <property name="can-focus">0</property>
-                                <property name="label" translatable="yes">Settings aren&apos;t functional yet</property>
+                                <property name="label" translatable="yes">Settings aren't functional yet</property>
                               </object>
                             </child>
                           </object>

+ 42 - 0
data/controls-popover.ui

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk" version="4.0"/>
+  <object class="GtkPopover" id="controls">
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <property name="hexpand">1</property>
+        <property name="spacing">5</property>
+        <child>
+          <object class="GtkLabel" id="title">
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="orientation">horizontal</property>
+            <property name="hexpand">1</property>
+            <property name="spacing">5</property>
+            <child>
+              <object class="GtkScale" id="scale">
+                <property name="orientation">horizontal</property>
+                <property name="draw-value">0</property>
+                <property name="width-request">150</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="value-label">
+              </object>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="auto-button">
+                <property name="valign">center</property>
+                <property name="label">auto</property>
+                <property name="margin-start">5</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>

+ 2 - 0
data/org.postmarketos.Megapixels.gresource.xml

@@ -2,11 +2,13 @@
 <gresources>
   <gresource prefix="/org/postmarketos/Megapixels">
     <file preprocess="xml-stripblanks">camera.ui</file>
+    <file preprocess="xml-stripblanks">controls-popover.ui</file>
     <file>camera.css</file>
     <file preprocess="xml-stripblanks">switch-camera-symbolic.svg</file>
     <file preprocess="xml-stripblanks">shutter-button-symbolic.svg</file>
     <file preprocess="xml-stripblanks">folder-symbolic.svg</file>
     <file preprocess="xml-stripblanks">settings-symbolic.svg</file>
+    <file preprocess="xml-stripblanks">shutter-symbolic.svg</file>
     <file>blit.vert</file>
     <file>blit.frag</file>
     <file>debayer.vert</file>

+ 32 - 0
data/shutter-symbolic.svg

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   width="32"
+   height="32"
+   viewBox="0 0 8.4666665 8.466667"
+   version="1.1"
+   id="svg8">
+  <defs
+     id="defs2" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <path
+     style="fill:#bebebe;fill-opacity:1;stroke-width:1"
+     d="M 16 0 A 16.000001 16.000001 0 0 0 8.5097656 1.8730469 L 11.611328 13.443359 L 19.189453 0.3203125 A 16.000001 16.000001 0 0 0 16 0 z M 20.699219 0.70703125 L 14.705078 11.087891 L 29.330078 7.1679688 A 16.000001 16.000001 0 0 0 20.699219 0.70703125 z M 7.1679688 2.6699219 A 16.000001 16.000001 0 0 0 0.70703125 11.300781 L 11.087891 17.294922 L 7.1679688 2.6699219 z M 30.126953 8.5117188 L 18.558594 11.611328 L 31.679688 19.189453 A 16.000001 16.000001 0 0 0 32 16 A 16.000001 16.000001 0 0 0 30.126953 8.5117188 z M 0.3203125 12.810547 A 16.000001 16.000001 0 0 0 0 16 A 16.000001 16.000001 0 0 0 1.8730469 23.490234 L 13.443359 20.388672 L 0.3203125 12.810547 z M 20.912109 14.705078 L 24.832031 29.330078 A 16.000001 16.000001 0 0 0 31.292969 20.699219 L 20.912109 14.705078 z M 20.388672 18.558594 L 12.8125 31.679688 A 16.000001 16.000001 0 0 0 16 32 A 16.000001 16.000001 0 0 0 23.490234 30.126953 L 20.388672 18.558594 z M 17.294922 20.912109 L 2.6699219 24.832031 A 16.000001 16.000001 0 0 0 11.300781 31.292969 L 17.294922 20.912109 z "
+     transform="scale(0.26458334)"
+     id="path4537" />
+</svg>

+ 129 - 70
src/main.c

@@ -61,12 +61,8 @@ static MPZBarScanResult *zbar_result = NULL;
 
 static int burst_length = 3;
 
-static enum user_control current_control;
-
 // Widgets
 GtkWidget *preview;
-GtkWidget *error_box;
-GtkWidget *error_message;
 GtkWidget *main_stack;
 GtkWidget *open_last_stack;
 GtkWidget *thumb_last;
@@ -598,39 +594,6 @@ run_quit_action(GSimpleAction *action, GVariant *param, GApplication *app)
 void
 preview_pressed(GtkGestureClick *gesture, int n_press, double x, double y)
 {
-	// Handle taps on the controls
-	// if (event->y < 32) {
-	// 	if (gtk_widget_is_visible(control_box)) {
-	// 		gtk_widget_hide(control_box);
-	// 		return;
-	// 	} else {
-	// 		gtk_widget_show(control_box);
-	// 	}
-
-	// 	if (event->x < 60) {
-	// 		// ISO
-	// 		current_control = USER_CONTROL_ISO;
-	// 		gtk_label_set_text(GTK_LABEL(control_name), "ISO");
-	// 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(control_auto),
-	// 					     !gain_is_manual);
-	// 		gtk_adjustment_set_lower(control_slider, 0.0);
-	// 		gtk_adjustment_set_upper(control_slider, (float)gain_max);
-	// 		gtk_adjustment_set_value(control_slider, (double)gain);
-
-	// 	} else if (event->x > 60 && event->x < 120) {
-	// 		// Shutter angle
-	// 		current_control = USER_CONTROL_SHUTTER;
-	// 		gtk_label_set_text(GTK_LABEL(control_name), "Shutter");
-	// 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(control_auto),
-	// 					     !exposure_is_manual);
-	// 		gtk_adjustment_set_lower(control_slider, 1.0);
-	// 		gtk_adjustment_set_upper(control_slider, 360.0);
-	// 		gtk_adjustment_set_value(control_slider, (double)exposure);
-	// 	}
-
-	// 	return;
-	// }
-
 	// Tapped zbar result
 	// if (zbar_result) {
 	// 	// Transform the event coordinates to the image
@@ -656,13 +619,7 @@ preview_pressed(GtkGestureClick *gesture, int n_press, double x, double y)
 	}
 }
 
-void
-on_error_close_clicked(GtkWidget *widget, gpointer user_data)
-{
-	gtk_widget_hide(error_box);
-}
-
-void
+static void
 run_camera_switch_action(GSimpleAction *action, GVariant *param, gpointer user_data)
 {
 	size_t next_index = camera->index + 1;
@@ -678,19 +635,132 @@ run_camera_switch_action(GSimpleAction *action, GVariant *param, gpointer user_d
 	update_io_pipeline();
 }
 
-void
+static void
 run_open_settings_action(GSimpleAction *action, GVariant *param, gpointer user_data)
 {
 	gtk_stack_set_visible_child_name(GTK_STACK(main_stack), "settings");
 }
 
-void
-on_back_clicked(GtkWidget *widget, gpointer user_data)
+static void
+run_close_settings_action(GSimpleAction *action, GVariant *param, gpointer user_data)
 {
 	gtk_stack_set_visible_child_name(GTK_STACK(main_stack), "main");
 }
 
-void
+static void
+on_controls_scale_changed(GtkAdjustment *adjustment, void (*set_fn)(double))
+{
+	set_fn(gtk_adjustment_get_value(adjustment));
+}
+
+static void
+update_value(GtkAdjustment *adjustment, GtkLabel *label)
+{
+	char buf[12];
+	snprintf(buf, 12, "%.0f", gtk_adjustment_get_value(adjustment));
+	gtk_label_set_label(label, buf);
+}
+
+static void
+on_auto_controls_toggled(GtkToggleButton *button, void (*set_auto_fn)(bool))
+{
+	set_auto_fn(gtk_toggle_button_get_active(button));
+}
+
+static void
+update_scale(GtkToggleButton *button, GtkScale *scale)
+{
+	gtk_widget_set_sensitive(GTK_WIDGET(scale), !gtk_toggle_button_get_active(button));
+}
+
+static void
+open_controls(GtkWidget *parent, const char *title_name,
+	      double min_value, double max_value, double current,
+	      bool auto_enabled,
+	      void (*set_fn)(double),
+	      void (*set_auto_fn)(bool))
+{
+	GtkBuilder *builder = gtk_builder_new_from_resource(
+		"/org/postmarketos/Megapixels/controls-popover.ui");
+	GtkPopover *popover = GTK_POPOVER(gtk_builder_get_object(builder, "controls"));
+	GtkScale *scale = GTK_SCALE(gtk_builder_get_object(builder, "scale"));
+	GtkLabel *title = GTK_LABEL(gtk_builder_get_object(builder, "title"));
+	GtkLabel *value_label = GTK_LABEL(gtk_builder_get_object(builder, "value-label"));
+	GtkToggleButton *auto_button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "auto-button"));
+
+	gtk_label_set_label(title, title_name);
+
+	GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(scale));
+	gtk_adjustment_set_lower(adjustment, min_value);
+	gtk_adjustment_set_upper(adjustment, max_value);
+	gtk_adjustment_set_value(adjustment, current);
+	update_value(adjustment, value_label);
+
+	gtk_toggle_button_set_active(auto_button, auto_enabled);
+	update_scale(auto_button, scale);
+
+	g_signal_connect(adjustment, "value-changed", G_CALLBACK(on_controls_scale_changed), set_fn);
+	g_signal_connect(adjustment, "value-changed", G_CALLBACK(update_value), value_label);
+	g_signal_connect(auto_button, "toggled", G_CALLBACK(on_auto_controls_toggled), set_auto_fn);
+	g_signal_connect(auto_button, "toggled", G_CALLBACK(update_scale), scale);
+
+	gtk_widget_set_parent(GTK_WIDGET(popover), parent);
+	gtk_popover_popup(popover);
+	// g_object_unref(popover);
+}
+
+static void
+set_gain(double value)
+{
+	if (gain != (int)value) {
+		gain = value;
+		update_io_pipeline();
+	}
+}
+
+static void
+set_gain_auto(bool is_auto)
+{
+	if (gain_is_manual != !is_auto) {
+		gain_is_manual = !is_auto;
+		update_io_pipeline();
+	}
+}
+
+static void
+open_iso_controls(GtkWidget *button, gpointer user_data)
+{
+	open_controls(button, "ISO", 0, gain_max, gain, !gain_is_manual, set_gain, set_gain_auto);
+}
+
+static void
+set_shutter(double value)
+{
+	int new_exposure =
+		(int)(value / 360.0 * camera->capture_mode.height);
+	if (new_exposure != exposure) {
+		exposure = new_exposure;
+		update_io_pipeline();
+	}
+}
+
+static void
+set_shutter_auto(bool is_auto)
+{
+	if (exposure_is_manual != !is_auto) {
+		exposure_is_manual = !is_auto;
+		update_io_pipeline();
+	}
+}
+
+static void
+open_shutter_controls(GtkWidget *button, gpointer user_data)
+{
+	open_controls(button, "Shutter", 1.0, 360.0, exposure, !exposure_is_manual, set_shutter, set_shutter_auto);
+}
+
+/*
+static void
 on_control_auto_toggled(GtkToggleButton *widget, gpointer user_data)
 {
 	bool is_manual = gtk_toggle_button_get_active(widget) ? false : true;
@@ -737,7 +807,7 @@ on_control_auto_toggled(GtkToggleButton *widget, gpointer user_data)
 	}
 }
 
-void
+static void
 on_control_slider_changed(GtkAdjustment *widget, gpointer user_data)
 {
 	double value = gtk_adjustment_get_value(widget);
@@ -767,6 +837,7 @@ on_control_slider_changed(GtkAdjustment *widget, gpointer user_data)
 		draw_controls();
 	}
 }
+*/
 
 static void
 on_realize(GtkWidget *window, gpointer *data)
@@ -778,10 +849,11 @@ on_realize(GtkWidget *window, gpointer *data)
 	update_io_pipeline();
 }
 
-static GSimpleAction *create_simple_action(GtkApplication *app, const char *name, GCallback callback)
+static GSimpleAction *
+create_simple_action(GtkApplication *app, const char *name, GCallback callback)
 {
 	GSimpleAction *action = g_simple_action_new(name, NULL);
-	g_signal_connect(action, "activate", callback, NULL);
+	g_signal_connect(action, "activate", callback, app);
 	g_action_map_add_action(G_ACTION_MAP(app), G_ACTION(action));
 	return action;
 }
@@ -807,27 +879,15 @@ activate(GtkApplication *app, gpointer data)
 		"/org/postmarketos/Megapixels/camera.ui");
 
 	GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
-	GtkWidget *settings_back =
-		GTK_WIDGET(gtk_builder_get_object(builder, "settings_back"));
-	GtkWidget *error_close =
-		GTK_WIDGET(gtk_builder_get_object(builder, "error_close"));
+	GtkWidget *iso_button = GTK_WIDGET(gtk_builder_get_object(builder, "iso-controls-button"));
+	GtkWidget *shutter_button = GTK_WIDGET(gtk_builder_get_object(builder, "shutter-controls-button"));
 	preview = GTK_WIDGET(gtk_builder_get_object(builder, "preview"));
-	error_box = GTK_WIDGET(gtk_builder_get_object(builder, "error_box"));
-	error_message = GTK_WIDGET(gtk_builder_get_object(builder, "error_message"));
 	main_stack = GTK_WIDGET(gtk_builder_get_object(builder, "main_stack"));
 	open_last_stack = GTK_WIDGET(gtk_builder_get_object(builder, "open_last_stack"));
 	thumb_last = GTK_WIDGET(gtk_builder_get_object(builder, "thumb_last"));
 	process_spinner = GTK_WIDGET(gtk_builder_get_object(builder, "process_spinner"));
-	control_box = GTK_WIDGET(gtk_builder_get_object(builder, "control_box"));
-	control_name = GTK_WIDGET(gtk_builder_get_object(builder, "control_name"));
-	control_slider =
-		GTK_ADJUSTMENT(gtk_builder_get_object(builder, "control_adj"));
-	control_auto = GTK_WIDGET(gtk_builder_get_object(builder, "control_auto"));
+
 	g_signal_connect(window, "realize", G_CALLBACK(on_realize), NULL);
-	g_signal_connect(error_close, "clicked", G_CALLBACK(on_error_close_clicked),
-			 NULL);
-	g_signal_connect(settings_back, "clicked", G_CALLBACK(on_back_clicked),
-			 NULL);
 
 	g_signal_connect(preview, "realize", G_CALLBACK(preview_realize), NULL);
 	g_signal_connect(preview, "render", G_CALLBACK(preview_draw), NULL);
@@ -836,15 +896,14 @@ activate(GtkApplication *app, gpointer data)
 	g_signal_connect(click, "pressed", G_CALLBACK(preview_pressed), NULL);
 	gtk_widget_add_controller(preview, GTK_EVENT_CONTROLLER(click));
 
-	g_signal_connect(control_auto, "toggled",
-			 G_CALLBACK(on_control_auto_toggled), NULL);
-	g_signal_connect(control_slider, "value-changed",
-			 G_CALLBACK(on_control_slider_changed), NULL);
+	g_signal_connect(iso_button, "clicked", G_CALLBACK(open_iso_controls), NULL);
+	g_signal_connect(shutter_button, "clicked", G_CALLBACK(open_shutter_controls), NULL);
 
 	// Setup actions
 	create_simple_action(app, "capture", G_CALLBACK(run_capture_action));
 	create_simple_action(app, "camera-switch", G_CALLBACK(run_camera_switch_action));
 	create_simple_action(app, "open-settings", G_CALLBACK(run_open_settings_action));
+	create_simple_action(app, "close-settings", G_CALLBACK(run_close_settings_action));
 	create_simple_action(app, "open-last", G_CALLBACK(run_open_last_action));
 	create_simple_action(app, "open-photos", G_CALLBACK(run_open_photos_action));
 	create_simple_action(app, "quit", G_CALLBACK(run_quit_action));