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