Skip to content

Commit 2dd3881

Browse files
authored
Merge pull request #1393 from techee/preferences_label
projectorganizer: Create a copy of GeanyWrapLabel and use it for pref…
2 parents 8d924fd + 91cc097 commit 2dd3881

File tree

4 files changed

+268
-4
lines changed

4 files changed

+268
-4
lines changed

projectorganizer/src/Makefile.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ projectorganizer_la_SOURCES = \
1616
prjorg-goto-panel.h \
1717
prjorg-goto-panel.c \
1818
prjorg-goto-anywhere.h \
19-
prjorg-goto-anywhere.c
19+
prjorg-goto-anywhere.c \
20+
prjorg-wraplabel.h \
21+
prjorg-wraplabel.c
2022

2123
projectorganizer_la_CPPFLAGS = $(AM_CPPFLAGS) \
2224
-DG_LOG_DOMAIN=\"ProjectOrganizer\"

projectorganizer/src/prjorg-project.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "prjorg-utils.h"
2929
#include "prjorg-project.h"
3030
#include "prjorg-sidebar.h"
31+
#include "prjorg-wraplabel.h"
3132

3233
extern GeanyPlugin *geany_plugin;
3334
extern GeanyData *geany_data;
@@ -736,10 +737,10 @@ GtkWidget *prjorg_project_add_properties_tab(GtkWidget *notebook)
736737
gtk_box_pack_start(GTK_BOX(vbox), table_box, FALSE, FALSE, 6);
737738

738739
hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
739-
label = gtk_label_new(_("The patterns above affect only sidebar and indexing and are not used in the Find in Files\n"
740-
"dialog. You can further restrict the files belonging to the project by setting the\n"
740+
label = prjorg_wrap_label_new(_("The patterns above affect only sidebar and indexing and are not used in the Find in Files "
741+
"dialog. You can further restrict the files belonging to the project by setting the"
741742
"File Patterns under the Project tab (these are also used for the Find in Files dialog)."));
742-
gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 12);
743+
gtk_box_pack_start(GTK_BOX(hbox1), label, TRUE, TRUE, 12);
743744
gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 0);
744745

745746
hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*
2+
* prjorg-wraplabel.c - renamed copy of geanywraplabel.c from Geany
3+
*
4+
* Copyright 2009 The Geany contributors
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 along
17+
* with this program; if not, write to the Free Software Foundation, Inc.,
18+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*/
20+
21+
/*
22+
* A GtkLabel subclass that can wrap to any width, unlike GtkLabel which has a fixed wrap point.
23+
* (inspired by libview's WrapLabel, https://view.sourceforge.net/)
24+
*/
25+
26+
#ifdef HAVE_CONFIG_H
27+
# include "config.h"
28+
#endif
29+
30+
#include "prjorg-wraplabel.h"
31+
32+
33+
struct _PrjorgWrapLabelClass
34+
{
35+
GtkLabelClass parent_class;
36+
};
37+
38+
typedef struct
39+
{
40+
gint wrap_width;
41+
gint wrap_height;
42+
} PrjorgWrapLabelPrivate;
43+
44+
struct _PrjorgWrapLabel
45+
{
46+
GtkLabel parent;
47+
PrjorgWrapLabelPrivate *priv;
48+
};
49+
50+
51+
static gboolean prjorg_wrap_label_draw(GtkWidget *widget, cairo_t *cr);
52+
static void prjorg_wrap_label_get_preferred_width (GtkWidget *widget,
53+
gint *minimal_width, gint *natural_width);
54+
static void prjorg_wrap_label_get_preferred_height (GtkWidget *widget,
55+
gint *minimal_height, gint *natural_height);
56+
static void prjorg_wrap_label_get_preferred_width_for_height (GtkWidget *widget,
57+
gint height, gint *minimal_width, gint *natural_width);
58+
static void prjorg_wrap_label_get_preferred_height_for_width (GtkWidget *widget,
59+
gint width, gint *minimal_height, gint *natural_height);
60+
static GtkSizeRequestMode prjorg_wrap_label_get_request_mode(GtkWidget *widget);
61+
static void prjorg_wrap_label_size_allocate (GtkWidget *widget, GtkAllocation *alloc);
62+
static void prjorg_wrap_label_set_wrap_width (GtkWidget *widget, gint width);
63+
static void prjorg_wrap_label_label_notify (GObject *object, GParamSpec *pspec, gpointer data);
64+
65+
G_DEFINE_TYPE(PrjorgWrapLabel, prjorg_wrap_label, GTK_TYPE_LABEL)
66+
67+
68+
static void prjorg_wrap_label_class_init(PrjorgWrapLabelClass *klass)
69+
{
70+
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
71+
72+
widget_class->size_allocate = prjorg_wrap_label_size_allocate;
73+
widget_class->draw = prjorg_wrap_label_draw;
74+
widget_class->get_preferred_width = prjorg_wrap_label_get_preferred_width;
75+
widget_class->get_preferred_width_for_height = prjorg_wrap_label_get_preferred_width_for_height;
76+
widget_class->get_preferred_height = prjorg_wrap_label_get_preferred_height;
77+
widget_class->get_preferred_height_for_width = prjorg_wrap_label_get_preferred_height_for_width;
78+
widget_class->get_request_mode = prjorg_wrap_label_get_request_mode;
79+
80+
g_type_class_add_private(klass, sizeof (PrjorgWrapLabelPrivate));
81+
}
82+
83+
84+
static void prjorg_wrap_label_init(PrjorgWrapLabel *self)
85+
{
86+
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
87+
PRJORG_WRAP_LABEL_TYPE, PrjorgWrapLabelPrivate);
88+
89+
self->priv->wrap_width = 0;
90+
self->priv->wrap_height = 0;
91+
92+
g_signal_connect(self, "notify::label", G_CALLBACK(prjorg_wrap_label_label_notify), NULL);
93+
gtk_misc_set_alignment(GTK_MISC(self), 0.0, 0.0);
94+
}
95+
96+
97+
/* Sets the point at which the text should wrap. */
98+
static void prjorg_wrap_label_set_wrap_width(GtkWidget *widget, gint width)
99+
{
100+
PrjorgWrapLabel *self = PRJORG_WRAP_LABEL(widget);
101+
PangoLayout *layout;
102+
103+
if (width <= 0)
104+
return;
105+
106+
layout = gtk_label_get_layout(GTK_LABEL(widget));
107+
108+
/*
109+
* We may need to reset the wrap width, so do this regardless of whether
110+
* or not we've changed the width.
111+
*/
112+
pango_layout_set_width(layout, width * PANGO_SCALE);
113+
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
114+
pango_layout_get_pixel_size(layout, NULL, &self->priv->wrap_height);
115+
116+
if (self->priv->wrap_width != width)
117+
{
118+
self->priv->wrap_width = width;
119+
gtk_widget_queue_resize(widget);
120+
}
121+
}
122+
123+
124+
/* updates the wrap width when the label text changes */
125+
static void prjorg_wrap_label_label_notify(GObject *object, GParamSpec *pspec, gpointer data)
126+
{
127+
PrjorgWrapLabel *self = PRJORG_WRAP_LABEL(object);
128+
129+
prjorg_wrap_label_set_wrap_width(GTK_WIDGET(object), self->priv->wrap_width);
130+
}
131+
132+
133+
/* makes sure the layout is setup for rendering and chains to parent renderer */
134+
static gboolean prjorg_wrap_label_draw(GtkWidget *widget, cairo_t *cr)
135+
{
136+
PrjorgWrapLabel *self = PRJORG_WRAP_LABEL(widget);
137+
PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));
138+
139+
pango_layout_set_width(layout, self->priv->wrap_width * PANGO_SCALE);
140+
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
141+
142+
return (* GTK_WIDGET_CLASS(prjorg_wrap_label_parent_class)->draw)(widget, cr);
143+
}
144+
145+
146+
static void prjorg_wrap_label_get_preferred_width (GtkWidget *widget,
147+
gint *minimal_width, gint *natural_width)
148+
{
149+
*minimal_width = *natural_width = 0;
150+
}
151+
152+
153+
static void prjorg_wrap_label_get_preferred_width_for_height (GtkWidget *widget,
154+
gint height, gint *minimal_width, gint *natural_width)
155+
{
156+
PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));;
157+
158+
pango_layout_set_height(layout, height * PANGO_SCALE);
159+
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
160+
pango_layout_get_pixel_size(layout, natural_width, NULL);
161+
162+
*minimal_width = 0;
163+
}
164+
165+
166+
static void prjorg_wrap_label_get_preferred_height (GtkWidget *widget,
167+
gint *minimal_height, gint *natural_height)
168+
{
169+
*minimal_height = *natural_height = PRJORG_WRAP_LABEL(widget)->priv->wrap_height;
170+
}
171+
172+
173+
static void prjorg_wrap_label_get_preferred_height_for_width (GtkWidget *widget,
174+
gint width, gint *minimal_height, gint *natural_height)
175+
{
176+
PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));
177+
178+
pango_layout_set_width(layout, width * PANGO_SCALE);
179+
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
180+
pango_layout_get_pixel_size(layout, NULL, natural_height);
181+
182+
*minimal_height = *natural_height;
183+
}
184+
185+
186+
static GtkSizeRequestMode prjorg_wrap_label_get_request_mode(GtkWidget *widget)
187+
{
188+
return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
189+
}
190+
191+
192+
/* Sets the wrap width to the width allocated to us. */
193+
static void prjorg_wrap_label_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
194+
{
195+
GtkWidget *parent;
196+
197+
(* GTK_WIDGET_CLASS(prjorg_wrap_label_parent_class)->size_allocate)(widget, alloc);
198+
199+
prjorg_wrap_label_set_wrap_width(widget, alloc->width);
200+
201+
/* ask the parent to recompute our size, because it seems GTK size
202+
* caching is too aggressive */
203+
parent = gtk_widget_get_parent(widget);
204+
if (GTK_IS_CONTAINER(parent))
205+
gtk_container_check_resize(GTK_CONTAINER(parent));
206+
}
207+
208+
209+
GtkWidget *prjorg_wrap_label_new(const gchar *text)
210+
{
211+
return g_object_new(PRJORG_WRAP_LABEL_TYPE, "label", text, NULL);
212+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* prjorg- wraplabel.h - renamed copy of geanywraplabel.h from Geany
3+
*
4+
* Copyright 2009 The Geany contributors
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 along
17+
* with this program; if not, write to the Free Software Foundation, Inc.,
18+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*/
20+
21+
#ifndef PRJORG_WRAP_LABEL_H
22+
#define PRJORG_WRAP_LABEL_H 1
23+
24+
#include "gtkcompat.h"
25+
26+
G_BEGIN_DECLS
27+
28+
29+
#define PRJORG_WRAP_LABEL_TYPE (prjorg_wrap_label_get_type())
30+
#define PRJORG_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
31+
PRJORG_WRAP_LABEL_TYPE, PrjorgWrapLabel))
32+
#define PRJORG_WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
33+
PRJORG_WRAP_LABEL_TYPE, PrjorgWrapLabelClass))
34+
#define IS_PRJORG_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
35+
PRJORG_WRAP_LABEL_TYPE))
36+
#define IS_PRJORG_WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
37+
PRJORG_WRAP_LABEL_TYPE))
38+
39+
40+
typedef struct _PrjorgWrapLabel PrjorgWrapLabel;
41+
typedef struct _PrjorgWrapLabelClass PrjorgWrapLabelClass;
42+
43+
GType prjorg_wrap_label_get_type (void);
44+
GtkWidget* prjorg_wrap_label_new (const gchar *text);
45+
46+
47+
G_END_DECLS
48+
49+
#endif /* PRJORG_WRAP_LABEL_H */

0 commit comments

Comments
 (0)