From 3ddd408276a889aa4982c375ccc156f6501bec05 Mon Sep 17 00:00:00 2001
From: ochibani <11yzyv86j@relay.firefox.com>
Date: Mon, 16 Dec 2024 21:54:30 +0200
Subject: [PATCH] add selected area size indicator

---
 interfaces/area_selection.ui |  6 ++++--
 interfaces/select_window.ui  |  1 +
 src/area_capture.rs          | 42 ++++++++++++++++++++++++++++++++++++
 src/styles/global.css        | 16 +++++++++++---
 src/ui.rs                    | 28 +++++++++++++++++-------
 5 files changed, 80 insertions(+), 13 deletions(-)

diff --git a/interfaces/area_selection.ui b/interfaces/area_selection.ui
index dfaa0fb..8ed9bfb 100644
--- a/interfaces/area_selection.ui
+++ b/interfaces/area_selection.ui
@@ -37,9 +37,10 @@
 								<property name="margin-start">5</property>
 								<child>
 									<object class="GtkLabel" id="area_size_top">
+										<property name="name">area_size_top</property>
 										<property name="visible">True</property>
 										<property name="can-focus">True</property>
-										<property name="label" translatable="yes">label</property>
+										<property name="label" translatable="yes">loading</property>
 									</object>
 								</child>
 							</object>
@@ -97,9 +98,10 @@
 								<property name="margin-end">5</property>
 								<child>
 									<object class="GtkLabel" id="area_size_bottom">
+										<property name="name">area_size_bottom</property>
 										<property name="visible">True</property>
 										<property name="can-focus">True</property>
-										<property name="label" translatable="yes">label</property>
+										<property name="label" translatable="yes">loading</property>
 									</object>
 								</child>
 							</object>
diff --git a/interfaces/select_window.ui b/interfaces/select_window.ui
index e01cbb0..99691d5 100644
--- a/interfaces/select_window.ui
+++ b/interfaces/select_window.ui
@@ -7,6 +7,7 @@
 		<property name="destroy-with-parent">True</property>
 		<property name="deletable">False</property>
 		<property name="resizable">False</property>
+		<property name="decorated">False</property>
 		<property name="modal">True</property>
 	</object>
 </interface>
diff --git a/src/area_capture.rs b/src/area_capture.rs
index c4d01e7..69c0a4f 100644
--- a/src/area_capture.rs
+++ b/src/area_capture.rs
@@ -2,8 +2,14 @@ extern crate regex;
 
 use anyhow::{anyhow, Result};
 use display_info::DisplayInfo;
+use glib::Continue;
+use libadwaita::gtk::Label;
+use libadwaita::Window;
+use libadwaita::prelude::*;
 use regex::Regex;
+use std::cell::RefCell;
 use std::process::Command;
+use std::rc::Rc;
 #[cfg(target_os = "windows")]
 use x_win::get_active_window;
 
@@ -143,3 +149,39 @@ fn xwininfo_to_coordinate(xwininfo_output: String) -> Result<(u16, u16, u16, u16
 
     Ok((x, y, width, height))
 }
+
+// Display area chooser window size
+pub fn show_size(area_chooser_window: Window, area_size_bottom_label: Label, area_size_top_label: Label) -> Result<()> {
+    // Create a shared state for the area size
+    let size_labels = Rc::new(RefCell::new((area_size_top_label, area_size_bottom_label)));
+
+    // Use a timeout to periodically check the window size
+    glib::timeout_add_local(1000, {
+        let area_chooser_window = area_chooser_window.clone();
+        let size_labels = size_labels.clone();
+
+        move || {
+            if !area_chooser_window.is_active() {
+                return Continue(false); // Stop the timeout
+            }
+
+            let mut area_capture = AreaCapture::new().unwrap();
+            #[cfg(any(target_os = "freebsd", target_os = "linux"))]
+            let size = area_capture.get_window_by_name(
+                area_chooser_window.title().unwrap().as_str()
+            ).unwrap();
+
+            #[cfg(target_os = "windows")]
+            let size = area_capture.get_active_window().unwrap();
+
+            // Update the labels
+            let (top_label, bottom_label) = size_labels.borrow_mut().to_owned();
+            top_label.set_text(&format!("{}x{}", size.width, size.height));
+            bottom_label.set_text(&format!("{}x{}", size.width, size.height));
+
+            Continue(true) // Continue the timeout
+        }
+    });
+
+    Ok(())
+}
diff --git a/src/styles/global.css b/src/styles/global.css
index 5c58adf..77dd96f 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -4,15 +4,25 @@
     border-radius: 0px;
 }
 
+#area_grab_button:checked, #screen_grab_button:checked, #window_grab_button:checked {
+    color: @theme_selected_fg_color;
+    background: alpha(@theme_selected_bg_color, 0.5);
+    border: 1px solid @theme_selected_bg_color;
+}
+
 #area_set_button {
     color: @theme_selected_fg_color;
     background: @theme_selected_bg_color;
 }
 
-#area_grab_button:checked, #screen_grab_button:checked, #window_grab_button:checked {
+#area_size_bottom {
     color: @theme_selected_fg_color;
-    background: alpha(@theme_selected_bg_color, 0.5);
-    border: 1px solid @theme_selected_bg_color;
+    font-weight: bold;
+}
+
+#area_size_top {
+    color: @theme_selected_fg_color;
+    font-weight: bold;
 }
 
 #delay_window {
diff --git a/src/ui.rs b/src/ui.rs
index a4ab846..7367a63 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -15,7 +15,7 @@ use std::ops::Add;
 use std::path::Path;
 use std::rc::Rc;
 
-use crate::{/*area_capture,*/ config_management, fluent::get_bundle};
+use crate::{area_capture, config_management, fluent::get_bundle};
 use crate::timer::{recording_delay, start_timer, stop_timer};
 
 pub fn run_ui(application: &Application) {
@@ -131,7 +131,7 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag
     error_dialog.set_transient_for(Some(&main_window));
     select_window.set_transient_for(Some(&main_window));
     select_window.set_message_type(libadwaita::gtk::MessageType::Info);
-    select_window.set_text(Some(&get_bundle("click-window", None)));
+    select_window.set_secondary_text(Some(&get_bundle("click-window", None)));
     main_window.set_application(Some(application));
     main_window.set_title(Some(&get_bundle("blue-recorder", None)));
 
@@ -516,7 +516,7 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag
                                                    let text_buffer = TextBuffer::new(None);
                                                    if response == libadwaita::gtk::ResponseType::Accept {
                                                        if folder_chooser_native.file().is_none() {
-                                                           text_buffer.set_text("failed to get save file path");
+                                                           text_buffer.set_text("Failed to get save file path");
                                                            error_message.set_buffer(Some(&text_buffer));
                                                            error_dialog.show();
                                                        }
@@ -553,9 +553,21 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag
     let _area_chooser_window = area_chooser_window.clone();
     //let mut _area_capture = area_capture.clone();
     let _area_switch = area_switch.clone();
+    let _error_dialog = error_dialog.clone();
+    let _error_message = error_message.clone();
     area_grab_button.connect_clicked(move |_| {
         config_management::set("default", "mode", "area");
         _area_chooser_window.show();
+        if area_capture::show_size(
+            _area_chooser_window.clone(),
+            area_size_bottom_label.clone(),
+            area_size_top_label.clone(),
+        ).is_err() {
+            let text_buffer = TextBuffer::new(None);
+            text_buffer.set_text("Failed to get area size value");
+            _error_message.set_buffer(Some(&text_buffer));
+            _error_dialog.show();
+        }
         _area_switch.set_active(config_management::get_bool("default", "areacheck"));
         _area_switch.set_sensitive(true);
     });
@@ -570,7 +582,7 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag
         /*if _area_capture
             .borrow_mut()
             .get_window_by_name(_area_chooser_window.title().unwrap().as_str()).is_err() {
-                text_buffer.set_text("failed to get area size value");
+                text_buffer.set_text("Failed to get area size value");
                 _error_message.set_buffer(Some(&text_buffer));
                 _error_dialog.show();
             }*/
@@ -596,7 +608,7 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag
         screen_grab_button_record_window.replace(false);
         _area_chooser_window.hide();
         /*if _area_capture.borrow_mut().reset().is_err() {
-            text_buffer.set_text("failed to get reset area_capture value");
+            text_buffer.set_text("Failed to get reset area_capture value");
             _error_message.set_buffer(Some(&text_buffer));
             _error_dialog.show();
         }*/
@@ -610,8 +622,6 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag
     window_grab_button.set_tooltip_text(Some(&get_bundle("window-tooltip", None)));
     window_grab_label.set_label(&get_bundle("select-window", None));
     window_grab_button.connect_clicked(move |_| {
-        select_window.show();
-        select_window.set_hide_on_close(true);
         let text_buffer = TextBuffer::new(None);
         config_management::set_bool("default", "areacheck", _area_switch.is_active());
         _area_switch.set_active(false);
@@ -621,8 +631,10 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag
         if is_wayland() {
             window_grab_button_record_window.replace(true);
         } else {
+            select_window.show();
+            select_window.set_hide_on_close(true);
             /*if _area_capture.borrow_mut().get_area().is_err() {
-                text_buffer.set_text("failed to get window size value");
+                text_buffer.set_text("Failed to get window size value");
                 _error_message.set_buffer(Some(&text_buffer));
                 _error_dialog.show();
             }*/