1 /*
2 * Copyright (C) 2013-2021 Graeme Gott <graeme@gottcode.org>
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "resizer.h"
19
20 #include "slot.h"
21 #include "window.h"
22
23 using namespace WhiskerMenu;
24
25 //-----------------------------------------------------------------------------
26
Resizer(Edge edge,Window * window)27 Resizer::Resizer(Edge edge, Window* window) :
28 m_window(window),
29 m_cursor(nullptr)
30 {
31 m_drawing = gtk_drawing_area_new();
32 gtk_widget_set_size_request(m_drawing, 6, 6);
33 gtk_widget_add_events(m_drawing, GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
34
35 connect(m_drawing, "button-press-event",
36 [this](GtkWidget*, GdkEvent* event) -> gboolean
37 {
38 m_window->set_child_has_focus();
39
40 GdkEventButton* event_button = reinterpret_cast<GdkEventButton*>(event);
41 gtk_window_begin_resize_drag(GTK_WINDOW(m_window->get_widget()),
42 m_edge,
43 event_button->button,
44 event_button->x_root,
45 event_button->y_root,
46 event_button->time);
47 return GDK_EVENT_STOP;
48 });
49
50 connect(m_drawing, "enter-notify-event",
51 [this](GtkWidget* widget, GdkEvent*) -> gboolean
52 {
53 gdk_window_set_cursor(gtk_widget_get_window(widget), m_cursor);
54 return GDK_EVENT_PROPAGATE;
55 });
56
57 connect(m_drawing, "leave-notify-event",
58 [](GtkWidget* widget, GdkEvent*) -> gboolean
59 {
60 gdk_window_set_cursor(gtk_widget_get_window(widget), nullptr);
61 return GDK_EVENT_PROPAGATE;
62 });
63
64 const char* type = nullptr;
65 switch (edge)
66 {
67 case BottomLeft:
68 m_edge = GDK_WINDOW_EDGE_SOUTH_WEST;
69 type = "nesw-resize";
70 break;
71
72 case Bottom:
73 m_edge = GDK_WINDOW_EDGE_SOUTH;
74 type = "ns-resize";
75 break;
76
77 case BottomRight:
78 m_edge = GDK_WINDOW_EDGE_SOUTH_EAST;
79 type = "nwse-resize";
80 break;
81
82 case Left:
83 m_edge = GDK_WINDOW_EDGE_WEST;
84 type = "ew-resize";
85 break;
86
87 case Right:
88 m_edge = GDK_WINDOW_EDGE_EAST;
89 type = "ew-resize";
90 break;
91
92 case TopLeft:
93 m_edge = GDK_WINDOW_EDGE_NORTH_WEST;
94 type = "nwse-resize";
95 break;
96
97 case Top:
98 m_edge = GDK_WINDOW_EDGE_NORTH;
99 type = "ns-resize";
100 break;
101
102 case TopRight:
103 default:
104 m_edge = GDK_WINDOW_EDGE_NORTH_EAST;
105 type = "nesw-resize";
106 break;
107 }
108 m_cursor = gdk_cursor_new_from_name(gtk_widget_get_display(m_drawing), type);
109 }
110
111 //-----------------------------------------------------------------------------
112
~Resizer()113 Resizer::~Resizer()
114 {
115 if (m_cursor)
116 {
117 g_object_unref(G_OBJECT(m_cursor));
118 }
119 }
120
121 //-----------------------------------------------------------------------------
122