diff --git a/data/io.gitlab.nekocwd.pipetap.gschema.xml b/data/io.gitlab.nekocwd.pipetap.gschema.xml
index 6d62d31..9876709 100644
--- a/data/io.gitlab.nekocwd.pipetap.gschema.xml
+++ b/data/io.gitlab.nekocwd.pipetap.gschema.xml
@@ -1,5 +1,23 @@
-
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ false
+
-
+
+
+
+
\ No newline at end of file
diff --git a/data/meson.build b/data/meson.build
index ce4c2d0..1df2113 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -28,7 +28,9 @@ test(
)
install_data(
- 'io.gitlab.nekocwd.pipetap.gschema.xml',
+ [
+ 'io.gitlab.nekocwd.pipetap.gschema.xml',
+ ],
install_dir: get_option('datadir') / 'glib-2.0' / 'schemas',
)
diff --git a/src/application.vala b/src/application.vala
index e355519..e7f6784 100644
--- a/src/application.vala
+++ b/src/application.vala
@@ -19,6 +19,9 @@
*/
public class PipeTap.Application : Adw.Application {
+ public Settings settings;
+ public bool adjust_overlay_visible { get; set; }
+
public Application () {
Object (
application_id: "io.gitlab.nekocwd.pipetap",
@@ -30,15 +33,25 @@ public class PipeTap.Application : Adw.Application {
ActionEntry[] action_entries = {
{ "about", this.on_about_action },
{ "preferences", this.on_preferences_action },
- { "quit", this.quit }
+ { "quit", this.quit },
+ { "adjust-overlays", () => { adjust_overlay_visible = !adjust_overlay_visible; } }
};
this.add_action_entries (action_entries, this);
this.set_accels_for_action ("app.quit", { "q" });
+ settings = new Settings ("io.gitlab.nekocwd.pipetap");
}
public override void activate () {
base.activate ();
- var win = this.active_window ?? new PipeTap.Window (this);
+
+ var styling = new Gtk.CssProvider ();
+ styling.load_from_resource ("/io/gitlab/nekocwd/pipetap/style.css");
+ Gtk.StyleContext.add_provider_for_display (Gdk.Display.get_default (),
+ styling,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ var win = this.active_window ?? new PipeTap.Ui.MainBar (this);
+ var win2 = new PipeTap.Ui.MainBar (this);
win.present ();
}
diff --git a/src/gui/main_bar.blp b/src/gui/main_bar.blp
new file mode 100644
index 0000000..e9fb49c
--- /dev/null
+++ b/src/gui/main_bar.blp
@@ -0,0 +1,75 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $PipeTapUiMainBar: $PipeTapUiFloatingWindow {
+ title: _("PipeTap");
+ window-name: "main-controls";
+ default-width: 60;
+ default-height: 60;
+
+ content: Gtk.Box {
+ orientation: bind template.orientation;
+ halign: fill;
+ homogeneous: true;
+ spacing: 10;
+
+ Gtk.Button {
+ icon-name: "camera-iso-symbolic";
+ tooltip-text: _("Exposure");
+
+ styles [
+ "flat",
+ ]
+ }
+
+ Gtk.Button {
+ icon-name: "camera-focus-symbolic";
+ tooltip-text: _("Focus");
+
+ styles [
+ "flat",
+ ]
+ }
+
+ Gtk.MenuButton {
+ primary: true;
+ icon-name: "open-menu-symbolic";
+ tooltip-text: _("Main Menu");
+ menu-model: primary_menu;
+
+ styles [
+ "flat",
+ ]
+ }
+ };
+}
+
+menu primary_menu {
+ section {
+ item {
+ label: _("_Adjust overlays");
+ action: "app.adjust-overlays";
+ }
+
+ item {
+ label: _("_Preferences");
+ action: "app.preferences";
+ }
+
+ /*
+ item {
+ label: _("_Keyboard Shortcuts");
+ action: "win.show-help-overlay";
+ }
+ */
+ item {
+ label: _("_About PipeTap");
+ action: "app.about";
+ }
+
+ item {
+ label: _("Quit");
+ action: "app.quit";
+ }
+ }
+}
diff --git a/src/gui/main_bar.vala b/src/gui/main_bar.vala
new file mode 100644
index 0000000..f9709a7
--- /dev/null
+++ b/src/gui/main_bar.vala
@@ -0,0 +1,6 @@
+[GtkTemplate (ui = "/io/gitlab/nekocwd/pipetap/gui/main_bar.ui")]
+public class PipeTap.Ui.MainBar : PipeTap.Ui.FloatingWindow {
+ public MainBar (Gtk.Application app) {
+ base (app);
+ }
+}
\ No newline at end of file
diff --git a/src/gui/window.blp b/src/gui/window.blp
new file mode 100644
index 0000000..dfd6b96
--- /dev/null
+++ b/src/gui/window.blp
@@ -0,0 +1,50 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $PipeTapUiFloatingWindow: Gtk.Window {
+ title: _("PipeTap");
+ default-width: 800;
+ default-height: 100;
+
+ styles [
+ "pt-transparent",
+ "osd",
+ ]
+
+ Box {
+ orientation: bind template.orientation;
+
+ Button resize {
+ visible: bind template.resize-visible;
+
+ styles [
+ "flat",
+ ]
+ }
+
+ Adw.Bin content_bin {
+ valign: fill;
+ halign: fill;
+ hexpand: true;
+ vexpand: true;
+ }
+
+ Button rotate {
+ visible: bind template.rotate-visible;
+ icon-name: "angled-arrows-symbolic";
+
+ styles [
+ "flat",
+ ]
+ }
+
+ Button move {
+ visible: bind template.move-visible;
+ icon-name: "move-tool-symbolic";
+
+ styles [
+ "flat",
+ ]
+ }
+ }
+}
diff --git a/src/gui/window.vala b/src/gui/window.vala
new file mode 100644
index 0000000..aa851b9
--- /dev/null
+++ b/src/gui/window.vala
@@ -0,0 +1,121 @@
+/* window.vala
+ *
+ * Copyright 2025 Vasiliy Doylov
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/*
+ * That's shitcode!!!!
+ * TODO: Refactor it before first release (or at least somewhen)
+ */
+
+[GtkTemplate (ui = "/io/gitlab/nekocwd/pipetap/gui/window.ui")]
+public class PipeTap.Ui.FloatingWindow : Gtk.Window, Gtk.Orientable {
+ [GtkChild]
+ private unowned Gtk.Button move;
+ [GtkChild]
+ private unowned Gtk.Button resize;
+ [GtkChild]
+ private unowned Gtk.Button rotate;
+ [GtkChild]
+ private unowned Adw.Bin content_bin;
+
+ public Gtk.Orientation orientation { get; set; default = Gtk.Orientation.HORIZONTAL; }
+
+ public bool resize_visible { get; set; }
+ public bool rotate_visible { get; set; }
+ public bool move_visible { get; set; }
+
+ public string window_name { get; set; default = ""; }
+
+ protected double pos_sy { get; set; }
+ protected double pos_sx { get; set; }
+ protected double pos_ex { get; set; }
+ protected double pos_ey { get; set; }
+
+ public Gtk.Widget content { get { return content_bin.get_child (); } set { content_bin.set_child (value); } }
+
+ public FloatingWindow (Gtk.Application app) {
+ Object (application: app);
+ GtkLayerShell.init_for_window (this);
+
+ var move_controller = new Gtk.GestureDrag ();
+ move_controller.drag_update.connect ((ox, oy) => {
+ pos_sy += (int) oy;
+ pos_sx -= (int) ox;
+ });
+ move_controller.end.connect (move_controller.reset);
+ move.add_controller (move_controller);
+
+ var resize_controller = new Gtk.GestureDrag ();
+ resize_controller.drag_update.connect ((ox, oy) => {
+ pos_ex += (int) ox;
+ pos_ey += (int) oy;
+ });
+ resize_controller.end.connect (resize_controller.reset);
+ resize.add_controller (resize_controller);
+
+ bind_property ("orientation", resize, "icon_name", GLib.BindingFlags.SYNC_CREATE, (binding, src, ref dst) => {
+ dst.set_string (orientation == Gtk.Orientation.VERTICAL ? "double-ended-arrows-vertical-symbolic" : "double-ended-arrows-horizontal-symbolic");
+ return true;
+ });
+
+ rotate.clicked.connect (() => {
+ orientation = orientation == Gtk.Orientation.HORIZONTAL ? Gtk.Orientation.VERTICAL : Gtk.Orientation.HORIZONTAL;
+ });
+
+ var positions = ((PipeTap.Application) app).settings.get_child (window_name + "-pos");
+ positions.bind_with_mapping ("orientation", this, "orientation", GLib.SettingsBindFlags.DEFAULT,
+ (value, variant) =>
+ { value = variant.get_boolean () ? Gtk.Orientation.VERTICAL : Gtk.Orientation.HORIZONTAL; return true; },
+ (value) =>
+ { return ((Gtk.Orientation) value) == Gtk.Orientation.VERTICAL; },
+ null, null
+ );
+ positions.bind ("start-x", this, "pos-sx", GLib.SettingsBindFlags.DEFAULT);
+ positions.bind ("start-y", this, "pos-sy", GLib.SettingsBindFlags.DEFAULT);
+ positions.bind ("end-x", this, "pos-ex", GLib.SettingsBindFlags.DEFAULT);
+ positions.bind ("end-y", this, "pos-ey", GLib.SettingsBindFlags.DEFAULT);
+
+ notify["pos-sx"].connect (set_position);
+ notify["pos-sy"].connect (set_position);
+ notify["pos-ex"].connect (set_position);
+ notify["pos-ey"].connect (set_position);
+ notify["orientation"].connect (set_position);
+ set_position ();
+
+ app.bind_property ("adjust-overlay-visible", this, "move-visible", GLib.BindingFlags.SYNC_CREATE);
+ app.bind_property ("adjust-overlay-visible", this, "resize-visible", GLib.BindingFlags.SYNC_CREATE);
+ app.bind_property ("adjust-overlay-visible", this, "rotate-visible", GLib.BindingFlags.SYNC_CREATE);
+ }
+
+ void set_position () {
+ var vertical = orientation == Gtk.Orientation.VERTICAL;
+ GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.TOP, true);
+ GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.BOTTOM, vertical);
+ GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.RIGHT, true);
+ GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.LEFT, !vertical);
+ var y = pos_sy;
+ if (vertical)
+ y = pos_ey + pos_sy;
+
+ GtkLayerShell.set_margin (this, GtkLayerShell.Edge.TOP, int.max ((int) y, 0));
+ GtkLayerShell.set_margin (this, GtkLayerShell.Edge.RIGHT, int.max ((int) pos_sx, 0));
+ GtkLayerShell.set_margin (this, GtkLayerShell.Edge.LEFT, int.max ((int) (pos_ex - pos_sx), 0));
+ GtkLayerShell.set_margin (this, GtkLayerShell.Edge.BOTTOM, int.max ((int) (-pos_sy), 0));
+ }
+}
\ No newline at end of file
diff --git a/src/icons/angled-arrows-symbolic.svg b/src/icons/angled-arrows-symbolic.svg
new file mode 100644
index 0000000..674097c
--- /dev/null
+++ b/src/icons/angled-arrows-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/icons/camera-focus-symbolic.svg b/src/icons/camera-focus-symbolic.svg
new file mode 100644
index 0000000..157e180
--- /dev/null
+++ b/src/icons/camera-focus-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/icons/camera-iso-symbolic.svg b/src/icons/camera-iso-symbolic.svg
new file mode 100644
index 0000000..480c255
--- /dev/null
+++ b/src/icons/camera-iso-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/icons/camera-photo-symbolic.svg b/src/icons/camera-photo-symbolic.svg
new file mode 100644
index 0000000..ad32b0d
--- /dev/null
+++ b/src/icons/camera-photo-symbolic.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/src/icons/double-ended-arrows-horizontal-symbolic.svg b/src/icons/double-ended-arrows-horizontal-symbolic.svg
new file mode 100644
index 0000000..d2e77f2
--- /dev/null
+++ b/src/icons/double-ended-arrows-horizontal-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/icons/double-ended-arrows-vertical-symbolic.svg b/src/icons/double-ended-arrows-vertical-symbolic.svg
new file mode 100644
index 0000000..c6a52a5
--- /dev/null
+++ b/src/icons/double-ended-arrows-vertical-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/icons/left-large-symbolic.svg b/src/icons/left-large-symbolic.svg
new file mode 100644
index 0000000..35ec1fe
--- /dev/null
+++ b/src/icons/left-large-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/icons/move-tool-symbolic.svg b/src/icons/move-tool-symbolic.svg
new file mode 100644
index 0000000..51a32ba
--- /dev/null
+++ b/src/icons/move-tool-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/icons/right-large-symbolic.svg b/src/icons/right-large-symbolic.svg
new file mode 100644
index 0000000..3d76598
--- /dev/null
+++ b/src/icons/right-large-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/meson.build b/src/meson.build
index 2f5619c..266a3e1 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,7 +1,8 @@
pipetap_sources = [
'main.vala',
'application.vala',
- 'window.vala',
+ 'gui/window.vala',
+ 'gui/main_bar.vala',
]
pipetap_deps = [
@@ -15,7 +16,8 @@ blueprints = custom_target(
'blueprints',
input: files(
'gtk/help-overlay.blp',
- 'window.blp',
+ 'gui/main_bar.blp',
+ 'gui/window.blp',
),
output: '.',
command: [
diff --git a/src/pipetap.gresource.xml b/src/pipetap.gresource.xml
index 96f2d97..3d04e2e 100644
--- a/src/pipetap.gresource.xml
+++ b/src/pipetap.gresource.xml
@@ -1,7 +1,20 @@
- window.ui
+ gui/window.ui
+ gui/main_bar.ui
gtk/help-overlay.ui
+ style.css
-
+
+ icons/right-large-symbolic.svg
+ icons/left-large-symbolic.svg
+ icons/camera-photo-symbolic.svg
+ icons/move-tool-symbolic.svg
+ icons/double-ended-arrows-horizontal-symbolic.svg
+ icons/double-ended-arrows-vertical-symbolic.svg
+ icons/camera-iso-symbolic.svg
+ icons/camera-focus-symbolic.svg
+ icons/angled-arrows-symbolic.svg
+
+
\ No newline at end of file
diff --git a/src/style.css b/src/style.css
new file mode 100644
index 0000000..27a928f
--- /dev/null
+++ b/src/style.css
@@ -0,0 +1,3 @@
+.pt-transparent {
+ border-radius: 10px;
+}
\ No newline at end of file
diff --git a/src/window.blp b/src/window.blp
deleted file mode 100644
index ea5dedc..0000000
--- a/src/window.blp
+++ /dev/null
@@ -1,48 +0,0 @@
-using Gtk 4.0;
-using Adw 1;
-
-template $PipeTapWindow: Adw.ApplicationWindow {
- title: _("PipeTap");
- default-width: 800;
- default-height: 600;
-
- content: Adw.ToolbarView {
- [top]
- Adw.HeaderBar {
- [end]
- MenuButton {
- primary: true;
- icon-name: "open-menu-symbolic";
- tooltip-text: _("Main Menu");
- menu-model: primary_menu;
- }
- }
-
- content: Label label {
- label: _("Hello, World!");
-
- styles [
- "title-1",
- ]
- };
- };
-}
-
-menu primary_menu {
- section {
- item {
- label: _("_Preferences");
- action: "app.preferences";
- }
-
- item {
- label: _("_Keyboard Shortcuts");
- action: "win.show-help-overlay";
- }
-
- item {
- label: _("_About PipeTap");
- action: "app.about";
- }
- }
-}
diff --git a/src/window.vala b/src/window.vala
deleted file mode 100644
index ff3a7b7..0000000
--- a/src/window.vala
+++ /dev/null
@@ -1,41 +0,0 @@
-/* window.vala
- *
- * Copyright 2025 Vasiliy Doylov
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-[GtkTemplate(ui = "/io/gitlab/nekocwd/pipetap/window.ui")]
-public class PipeTap.Window : Adw.ApplicationWindow {
- [GtkChild]
- private unowned Gtk.Label label;
-
- public Window(Gtk.Application app) {
- Object(application: app);
- GtkLayerShell.init_for_window(this);
- set_position();
- }
-
- void set_position() {
- GtkLayerShell.set_anchor(this, GtkLayerShell.Edge.BOTTOM, true);
- GtkLayerShell.set_anchor(this, GtkLayerShell.Edge.BOTTOM, true);
- GtkLayerShell.set_anchor(this, GtkLayerShell.Edge.LEFT, true);
-
- GtkLayerShell.set_margin(this, GtkLayerShell.Edge.TOP, 100);
- GtkLayerShell.set_margin(this, GtkLayerShell.Edge.BOTTOM, 100);
- GtkLayerShell.set_margin(this, GtkLayerShell.Edge.LEFT, 100);
- }
-}
\ No newline at end of file