1 /*
2 * fm-tab-label.c
3 *
4 * Copyright 2010 PCMan <pcman.tw@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 /**
23 * SECTION:fm-tab-label
24 * @short_description: A tab label widget.
25 * @title: FmTabLabel
26 *
27 * @include: libfm/fm-gtk.h
28 *
29 * The #FmTabLabel is a widget that can be used as a label of tab in
30 * notebook-like folders view.
31 */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include <glib/gi18n-lib.h>
38
39 #include "fm-tab-label.h"
40
41 G_DEFINE_TYPE(FmTabLabel, fm_tab_label, GTK_TYPE_EVENT_BOX);
42
43 #if GTK_CHECK_VERSION(3, 0, 0)
44 GtkCssProvider *provider;
45 #endif
46
fm_tab_label_class_init(FmTabLabelClass * klass)47 static void fm_tab_label_class_init(FmTabLabelClass *klass)
48 {
49 /* special style used by close button */
50 #if GTK_CHECK_VERSION(3, 0, 0)
51 provider = gtk_css_provider_new();
52 gtk_css_provider_load_from_data(provider,
53 "#tab-close-btn {\n"
54 "-GtkWidget-focus-padding : 0;\n"
55 "-GtkWidget-focus-line-width : 0;\n"
56 "padding : 0;\n"
57 "}\n", -1, NULL);
58 #else
59 gtk_rc_parse_string(
60 "style \"close-btn-style\" {\n"
61 "GtkWidget::focus-padding = 0\n"
62 "GtkWidget::focus-line-width = 0\n"
63 "xthickness = 0\n"
64 "ythickness = 0\n"
65 "}\n"
66 "widget \"*.tab-close-btn\" style \"close-btn-style\"");
67 #endif
68 }
69
70 /* FIXME: add g_object_unref (provider); on class destroy? */
71
on_close_btn_style_set(GtkWidget * btn,GtkRcStyle * prev,gpointer data)72 static void on_close_btn_style_set(GtkWidget *btn, GtkRcStyle *prev, gpointer data)
73 {
74 gint w, h;
75 gtk_icon_size_lookup_for_settings(gtk_widget_get_settings(btn), GTK_ICON_SIZE_MENU, &w, &h);
76 gtk_widget_set_size_request(btn, w + 2, h + 2);
77 }
78
on_query_tooltip(GtkWidget * widget,gint x,gint y,gboolean keyboard_mode,GtkTooltip * tooltip,gpointer user_data)79 static gboolean on_query_tooltip(GtkWidget *widget, gint x, gint y,
80 gboolean keyboard_mode,
81 GtkTooltip *tooltip, gpointer user_data)
82 {
83 /* We should only show the tooltip if the text is ellipsized */
84 GtkLabel* label = GTK_LABEL(widget);
85 PangoLayout* layout = gtk_label_get_layout(label);
86 if(pango_layout_is_ellipsized(layout))
87 {
88 gtk_tooltip_set_text(tooltip, gtk_label_get_text(label));
89 return TRUE;
90 }
91 return FALSE;
92 }
93
fm_tab_label_init(FmTabLabel * self)94 static void fm_tab_label_init(FmTabLabel *self)
95 {
96 GtkBox* hbox;
97 #if GTK_CHECK_VERSION(3, 0, 0)
98 GtkStyleContext *context = gtk_widget_get_style_context(GTK_WIDGET(self));
99 #endif
100
101 gtk_event_box_set_visible_window(GTK_EVENT_BOX(self), FALSE);
102 #if GTK_CHECK_VERSION(3, 2, 0)
103 /* FIXME: migrate to GtkGrid */
104 hbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
105 #else
106 hbox = GTK_BOX(gtk_hbox_new(FALSE, 0));
107 #endif
108
109 self->label = (GtkLabel*)gtk_label_new("");
110 gtk_widget_set_has_tooltip((GtkWidget*)self->label, TRUE);
111 gtk_box_pack_start(hbox, (GtkWidget*)self->label, FALSE, FALSE, 4 );
112 g_signal_connect(self->label, "query-tooltip", G_CALLBACK(on_query_tooltip), self);
113
114 self->close_btn = (GtkButton*)gtk_button_new();
115 gtk_button_set_focus_on_click(self->close_btn, FALSE);
116 gtk_button_set_relief(self->close_btn, GTK_RELIEF_NONE );
117 gtk_container_add ( GTK_CONTAINER ( self->close_btn ),
118 gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
119 gtk_container_set_border_width(GTK_CONTAINER(self->close_btn), 0);
120 gtk_widget_set_name((GtkWidget*)self->close_btn, "tab-close-btn");
121 g_signal_connect(self->close_btn, "style-set", G_CALLBACK(on_close_btn_style_set), NULL);
122
123 gtk_box_pack_end( hbox, (GtkWidget*)self->close_btn, FALSE, FALSE, 0 );
124
125 gtk_container_add(GTK_CONTAINER(self), (GtkWidget*)hbox);
126 gtk_widget_show_all((GtkWidget*)hbox);
127
128 #if GTK_CHECK_VERSION(3, 0, 0)
129 gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider),
130 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
131 #endif
132
133 /*
134 gtk_drag_dest_set ( GTK_WIDGET( evt_box ), GTK_DEST_DEFAULT_ALL,
135 drag_targets,
136 sizeof( drag_targets ) / sizeof( GtkTargetEntry ),
137 GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK );
138 g_signal_connect ( ( gpointer ) evt_box, "drag-motion",
139 G_CALLBACK ( on_tab_drag_motion ),
140 file_browser );
141 */
142 }
143
144 /**
145 * fm_tab_label_new
146 * @text: text to display as a tab label
147 *
148 * Creates new tab label widget.
149 *
150 * Returns: (transfer full): a new #FmTabLabel widget.
151 *
152 * Since: 0.1.10
153 */
fm_tab_label_new(const char * text)154 FmTabLabel *fm_tab_label_new(const char* text)
155 {
156 FmTabLabel* label = (FmTabLabel*)g_object_new(FM_TYPE_TAB_LABEL, NULL);
157 AtkObject *obj;
158 obj = gtk_widget_get_accessible(GTK_WIDGET(label));
159 atk_object_set_description(obj, _("Changes active tab"));
160 gtk_label_set_text(label->label, text);
161 return label;
162 }
163
164 /**
165 * fm_tab_label_set_text
166 * @label: a tab label widget
167 * @text: text to display as a tab label
168 *
169 * Changes text on the @label.
170 *
171 * Since: 0.1.10
172 */
fm_tab_label_set_text(FmTabLabel * label,const char * text)173 void fm_tab_label_set_text(FmTabLabel* label, const char* text)
174 {
175 gtk_label_set_text(label->label, text);
176 }
177
178 /**
179 * fm_tab_label_set_tooltip_text
180 * @label: a tab label widget
181 * @text: text to display in label tooltip
182 *
183 * Changes text of tooltip on the @label.
184 *
185 * Since: 1.0.0
186 */
fm_tab_label_set_tooltip_text(FmTabLabel * label,const char * text)187 void fm_tab_label_set_tooltip_text(FmTabLabel* label, const char* text)
188 {
189 gtk_widget_set_tooltip_text(GTK_WIDGET(label->label), text);
190 }
191
192 /**
193 * fm_tab_label_set_icon
194 * @label: a tab label widget
195 * @icon: (allow-none): an icon to show before text or %NULL
196 *
197 * Sets an optional @icon to be shown before text in the @label.
198 *
199 * Since: 1.2.0
200 */
fm_tab_label_set_icon(FmTabLabel * label,FmIcon * icon)201 void fm_tab_label_set_icon(FmTabLabel *label, FmIcon *icon)
202 {
203 g_return_if_fail(FM_IS_TAB_LABEL(label));
204 if (icon)
205 {
206 gint height, width;
207 GdkPixbuf *pixbuf;
208
209 if (!gtk_icon_size_lookup(GTK_ICON_SIZE_BUTTON, &width, &height))
210 height = 20; /* fallback size, is that ever needed? */
211 pixbuf = fm_pixbuf_from_icon(icon, height);
212 if (pixbuf == NULL)
213 goto _no_image;
214 if (label->image)
215 {
216 gtk_image_set_from_pixbuf((GtkImage*)label->image, pixbuf);
217 gtk_widget_queue_draw(GTK_WIDGET(label));
218 }
219 else
220 {
221 /* hbox is only child of the label */
222 GtkWidget *hbox = gtk_bin_get_child(GTK_BIN(label));
223
224 label->image = gtk_image_new_from_pixbuf(pixbuf);
225 gtk_box_pack_start(GTK_BOX(hbox), label->image, FALSE, FALSE, 0);
226 gtk_widget_show(label->image);
227 }
228 g_object_unref(pixbuf);
229 return;
230 }
231 _no_image:
232 if (label->image)
233 {
234 gtk_widget_destroy(label->image);
235 label->image = NULL;
236 }
237 }
238