1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /* Marco resizing-terminal-window feedback */
4
5 /*
6 * Copyright (C) 2001 Havoc Pennington
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24 #include <config.h>
25 #include <glib/gi18n-lib.h>
26
27 #include "resizepopup.h"
28 #include "util.h"
29 #include <gtk/gtk.h>
30 #include <gdk/gdkx.h>
31
32 struct _MetaResizePopup
33 {
34 GtkWidget *size_window;
35 GtkWidget *size_label;
36 Display *display;
37 int screen_number;
38
39 int vertical_size;
40 int horizontal_size;
41
42 gboolean showing;
43
44 MetaRectangle rect;
45 };
46
47 MetaResizePopup*
meta_ui_resize_popup_new(Display * display,int screen_number)48 meta_ui_resize_popup_new (Display *display,
49 int screen_number)
50 {
51 MetaResizePopup *popup;
52
53 popup = g_new0 (MetaResizePopup, 1);
54
55 popup->display = display;
56 popup->screen_number = screen_number;
57
58 return popup;
59 }
60
61 void
meta_ui_resize_popup_free(MetaResizePopup * popup)62 meta_ui_resize_popup_free (MetaResizePopup *popup)
63 {
64 g_return_if_fail (popup != NULL);
65
66 if (popup->size_window)
67 gtk_widget_destroy (popup->size_window);
68
69 g_free (popup);
70 }
71
72 static void
ensure_size_window(MetaResizePopup * popup)73 ensure_size_window (MetaResizePopup *popup)
74 {
75 GtkWidget *frame;
76
77 if (popup->size_window)
78 return;
79
80 popup->size_window = gtk_window_new (GTK_WINDOW_POPUP);
81
82 gtk_window_set_screen (GTK_WINDOW (popup->size_window),
83 gdk_display_get_default_screen (gdk_x11_lookup_xdisplay (popup->display)));
84
85 /* never shrink the size window */
86 gtk_window_set_resizable (GTK_WINDOW (popup->size_window),
87 TRUE);
88
89 frame = gtk_frame_new (NULL);
90 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
91
92 gtk_container_add (GTK_CONTAINER (popup->size_window), frame);
93
94 popup->size_label = gtk_label_new ("");
95 gtk_widget_set_margin_start (popup->size_label, 3);
96 gtk_widget_set_margin_end (popup->size_label, 3);
97 gtk_widget_set_margin_top (popup->size_label, 3);
98 gtk_widget_set_margin_bottom (popup->size_label, 3);
99
100 gtk_container_add (GTK_CONTAINER (frame), popup->size_label);
101
102 gtk_widget_show_all (frame);
103 }
104
105 static void
update_size_window(MetaResizePopup * popup)106 update_size_window (MetaResizePopup *popup)
107 {
108 char *str;
109 int x, y;
110 int width, height;
111 int scale;
112
113 g_return_if_fail (popup->size_window != NULL);
114
115 scale = gtk_widget_get_scale_factor (GTK_WIDGET (popup->size_window));
116 /* Translators: This represents the size of a window. The first number is
117 * the width of the window and the second is the height.
118 */
119 str = g_strdup_printf (_("%d x %d"),
120 popup->horizontal_size,
121 popup->vertical_size);
122
123 gtk_label_set_text (GTK_LABEL (popup->size_label), str);
124
125 g_free (str);
126
127 gtk_window_get_size (GTK_WINDOW (popup->size_window), &width, &height);
128
129 x = popup->rect.x + (popup->rect.width - width) / 2;
130 y = popup->rect.y + (popup->rect.height - height) / 2;
131
132 if (scale)
133 {
134 x = x / scale;
135 y = y / scale;
136 }
137
138 if (gtk_widget_get_realized (popup->size_window))
139 {
140 /* using move_resize to avoid jumpiness */
141 gdk_window_move_resize (gtk_widget_get_window (popup->size_window),
142 x, y,
143 width, height);
144 }
145 else
146 {
147 gtk_window_move (GTK_WINDOW (popup->size_window),
148 x, y);
149 }
150 }
151
152 static void
sync_showing(MetaResizePopup * popup)153 sync_showing (MetaResizePopup *popup)
154 {
155 if (popup->showing)
156 {
157 if (popup->size_window)
158 gtk_widget_show (popup->size_window);
159
160 if (popup->size_window && gtk_widget_get_realized (popup->size_window))
161 gdk_window_raise (gtk_widget_get_window(GTK_WIDGET(popup->size_window)));
162 }
163 else
164 {
165 if (popup->size_window)
166 gtk_widget_hide (popup->size_window);
167 }
168 }
169
170 void
meta_ui_resize_popup_set(MetaResizePopup * popup,MetaRectangle rect,int base_width,int base_height,int width_inc,int height_inc)171 meta_ui_resize_popup_set (MetaResizePopup *popup,
172 MetaRectangle rect,
173 int base_width,
174 int base_height,
175 int width_inc,
176 int height_inc)
177 {
178 gboolean need_update_size;
179 int display_w, display_h;
180
181 g_return_if_fail (popup != NULL);
182
183 need_update_size = FALSE;
184
185 display_w = rect.width - base_width;
186 if (width_inc > 0)
187 display_w /= width_inc;
188
189 display_h = rect.height - base_height;
190 if (height_inc > 0)
191 display_h /= height_inc;
192
193 if (!meta_rectangle_equal(&popup->rect, &rect) ||
194 display_w != popup->horizontal_size ||
195 display_h != popup->vertical_size)
196 need_update_size = TRUE;
197
198 popup->rect = rect;
199 popup->vertical_size = display_h;
200 popup->horizontal_size = display_w;
201
202 if (need_update_size)
203 {
204 ensure_size_window (popup);
205 update_size_window (popup);
206 }
207
208 sync_showing (popup);
209 }
210
211 void
meta_ui_resize_popup_set_showing(MetaResizePopup * popup,gboolean showing)212 meta_ui_resize_popup_set_showing (MetaResizePopup *popup,
213 gboolean showing)
214 {
215 g_return_if_fail (popup != NULL);
216
217 if (showing == popup->showing)
218 return;
219
220 popup->showing = !!showing;
221
222 if (popup->showing)
223 {
224 ensure_size_window (popup);
225 update_size_window (popup);
226 }
227
228 sync_showing (popup);
229 }
230