1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /* Metacity 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 Street - Suite 500, Boston, MA
21 * 02110-1335, USA.
22 */
23
24 #include <config.h>
25 #include "resizepopup.h"
26 #include "util-private.h"
27 #include <gtk/gtk.h>
28 #include <gdk/gdkx.h>
29
30 struct _MetaResizePopup
31 {
32 GtkWidget *size_window;
33 GtkWidget *size_label;
34 Display *display;
35 int screen_number;
36
37 int vertical_size;
38 int horizontal_size;
39
40 gboolean showing;
41
42 MetaRectangle rect;
43 };
44
45 LOCAL_SYMBOL MetaResizePopup*
meta_ui_resize_popup_new(Display * display,int screen_number)46 meta_ui_resize_popup_new (Display *display,
47 int screen_number)
48 {
49 MetaResizePopup *popup;
50
51 popup = g_new0 (MetaResizePopup, 1);
52
53 popup->display = display;
54 popup->screen_number = screen_number;
55
56 return popup;
57 }
58
59 LOCAL_SYMBOL void
meta_ui_resize_popup_free(MetaResizePopup * popup)60 meta_ui_resize_popup_free (MetaResizePopup *popup)
61 {
62 g_return_if_fail (popup != NULL);
63
64 if (popup->size_window)
65 gtk_widget_destroy (popup->size_window);
66
67 free (popup);
68 }
69
70 static void
ensure_size_window(MetaResizePopup * popup)71 ensure_size_window (MetaResizePopup *popup)
72 {
73 GtkWidget *frame;
74
75 if (popup->size_window)
76 return;
77
78 popup->size_window = gtk_window_new (GTK_WINDOW_POPUP);
79
80 gtk_window_set_screen (GTK_WINDOW (popup->size_window),
81 gdk_display_get_screen (gdk_x11_lookup_xdisplay (popup->display),
82 popup->screen_number));
83
84 /* never shrink the size window */
85 gtk_window_set_resizable (GTK_WINDOW (popup->size_window),
86 TRUE);
87
88 frame = gtk_frame_new (NULL);
89 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
90
91 gtk_container_add (GTK_CONTAINER (popup->size_window), frame);
92
93 popup->size_label = gtk_label_new ("");
94 gtk_misc_set_padding (GTK_MISC (popup->size_label), 3, 3);
95
96 gtk_container_add (GTK_CONTAINER (frame), popup->size_label);
97
98 gtk_widget_show_all (frame);
99 }
100
101 static void
update_size_window(MetaResizePopup * popup)102 update_size_window (MetaResizePopup *popup)
103 {
104 char *str;
105 int x, y;
106 int width, height;
107
108 g_return_if_fail (popup->size_window != NULL);
109
110 /* Translators: This represents the size of a window. The first number is
111 * the width of the window and the second is the height.
112 */
113 str = g_strdup_printf (_("%d x %d"),
114 popup->horizontal_size,
115 popup->vertical_size);
116
117 gtk_label_set_text (GTK_LABEL (popup->size_label), str);
118
119 free (str);
120
121 gtk_window_get_size (GTK_WINDOW (popup->size_window), &width, &height);
122
123 x = popup->rect.x + (popup->rect.width - width) / 2;
124 y = popup->rect.y + (popup->rect.height - height) / 2;
125
126 if (gtk_widget_get_realized (popup->size_window))
127 {
128 /* using move_resize to avoid jumpiness */
129 gdk_window_move_resize (gtk_widget_get_window (popup->size_window),
130 x, y,
131 width, height);
132 }
133 else
134 {
135 gtk_window_move (GTK_WINDOW (popup->size_window),
136 x, y);
137 }
138 }
139
140 static void
sync_showing(MetaResizePopup * popup)141 sync_showing (MetaResizePopup *popup)
142 {
143 if (popup->showing)
144 {
145 if (popup->size_window)
146 gtk_widget_show (popup->size_window);
147
148 if (popup->size_window && gtk_widget_get_realized (popup->size_window))
149 gdk_window_raise (gtk_widget_get_window (popup->size_window));
150 }
151 else
152 {
153 if (popup->size_window)
154 gtk_widget_hide (popup->size_window);
155 }
156 }
157
158 LOCAL_SYMBOL void
meta_ui_resize_popup_set(MetaResizePopup * popup,MetaRectangle rect,int base_width,int base_height,int width_inc,int height_inc)159 meta_ui_resize_popup_set (MetaResizePopup *popup,
160 MetaRectangle rect,
161 int base_width,
162 int base_height,
163 int width_inc,
164 int height_inc)
165 {
166 gboolean need_update_size;
167 int display_w, display_h;
168
169 g_return_if_fail (popup != NULL);
170
171 need_update_size = FALSE;
172
173 display_w = rect.width - base_width;
174 if (width_inc > 0)
175 display_w /= width_inc;
176
177 display_h = rect.height - base_height;
178 if (height_inc > 0)
179 display_h /= height_inc;
180
181 if (!meta_rectangle_equal(&popup->rect, &rect) ||
182 display_w != popup->horizontal_size ||
183 display_h != popup->vertical_size)
184 need_update_size = TRUE;
185
186 popup->rect = rect;
187 popup->vertical_size = display_h;
188 popup->horizontal_size = display_w;
189
190 if (need_update_size)
191 {
192 ensure_size_window (popup);
193 update_size_window (popup);
194 }
195
196 sync_showing (popup);
197 }
198
199 LOCAL_SYMBOL void
meta_ui_resize_popup_set_showing(MetaResizePopup * popup,gboolean showing)200 meta_ui_resize_popup_set_showing (MetaResizePopup *popup,
201 gboolean showing)
202 {
203 g_return_if_fail (popup != NULL);
204
205 if (showing == popup->showing)
206 return;
207
208 popup->showing = !!showing;
209
210 if (popup->showing)
211 {
212 ensure_size_window (popup);
213 update_size_window (popup);
214 }
215
216 sync_showing (popup);
217 }
218