1 /* vim:set et sts=4 sw=4:
5 * Copyright(c) 2011 Peng Huang <shawn.p.huang@gmail.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or(at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 * Boston, MA 02111-1307 USA
23 class CandidateArea : Gtk.Box {
24 private bool m_vertical;
25 private Gtk.Label[] m_labels;
26 private Gtk.Label[] m_candidates;
27 private Gtk.Widget[] m_widgets;
29 private IBus.Text[] m_ibus_candidates;
30 private uint m_focus_candidate;
31 private bool m_show_cursor;
33 private const string LABELS[] = {
34 "1.", "2.", "3.", "4.", "5.", "6.", "7.", "8.",
35 "9.", "0.", "a.", "b.", "c.", "d.", "e.", "f."
38 public signal void candidate_clicked(uint index, uint button, uint state);
39 public signal void page_up();
40 public signal void page_down();
41 public signal void cursor_up();
42 public signal void cursor_down();
44 public CandidateArea(bool vertical) {
46 orientation: vertical ? Gtk.Orientation.VERTICAL : Gtk.Orientation.HORIZONTAL
48 m_vertical = vertical;
53 public void set_vertical(bool vertical) {
54 if (m_vertical == vertical)
56 m_vertical = vertical;
59 // Workaround a vala issue https://bugzilla.gnome.org/show_bug.cgi?id=661130
60 set_candidates((owned)m_ibus_candidates, m_focus_candidate, m_show_cursor);
61 if (m_candidates.length > 0)
65 public void set_labels(IBus.Text[] labels) {
67 for (i = 0; i < int.min(16, labels.length); i++)
68 m_labels[i].set_text(labels[i].get_text());
70 m_labels[i].set_text(LABELS[i]);
73 public void set_candidates(IBus.Text[] candidates,
74 uint focus_candidate = 0,
75 bool show_cursor = true) {
76 m_ibus_candidates = candidates;
77 m_focus_candidate = focus_candidate;
78 m_show_cursor = show_cursor;
80 assert(candidates.length < 16);
81 for (int i = 0 ; i < 16 ; i++) {
82 Gtk.Label label = m_candidates[i];
84 if (i < candidates.length) {
85 Pango.AttrList attrs = get_pango_attr_list_from_ibus_text(candidates[i]);
86 if (i == focus_candidate && show_cursor) {
87 Gtk.StyleContext context = m_candidates[i].get_style_context();
88 Gdk.RGBA color = context.get_color(Gtk.StateFlags.SELECTED);
89 Pango.Attribute pango_attr = Pango.attr_foreground_new(
90 (uint16)(color.red * uint16.MAX),
91 (uint16)(color.green * uint16.MAX),
92 (uint16)(color.blue * uint16.MAX));
93 pango_attr.start_index = 0;
94 pango_attr.end_index = candidates[i].get_text().length;
95 attrs.insert((owned)pango_attr);
97 color = context.get_background_color(Gtk.StateFlags.SELECTED);
98 pango_attr = Pango.attr_background_new(
99 (uint16)(color.red * uint16.MAX),
100 (uint16)(color.green * uint16.MAX),
101 (uint16)(color.blue * uint16.MAX));
102 pango_attr.start_index = 0;
103 pango_attr.end_index = candidates[i].get_text().length;
104 attrs.insert((owned)pango_attr);
106 label.set_text(candidates[i].get_text());
107 label.set_attributes(attrs);
111 label.set_attributes(new Pango.AttrList());
114 m_widgets[i * 2].set_visible(visible);
115 m_widgets[i * 2 +1].set_visible(visible);
117 m_widgets[i].set_visible(visible);
122 private void recreate_ui() {
123 foreach (Gtk.Widget w in get_children()) {
127 Gtk.Button prev_button = new Gtk.Button();
128 prev_button.clicked.connect((b) => page_up());
129 prev_button.set_image(new Gtk.Image.from_icon_name(Gtk.Stock.GO_UP, Gtk.IconSize.MENU));
130 prev_button.set_relief(Gtk.ReliefStyle.NONE);
132 Gtk.Button next_button = new Gtk.Button();
133 next_button.clicked.connect((b) => page_down());
134 next_button.set_image(new Gtk.Image.from_icon_name(Gtk.Stock.GO_DOWN, Gtk.IconSize.MENU));
135 next_button.set_relief(Gtk.ReliefStyle.NONE);
139 Gtk.HBox candidates_hbox = new Gtk.HBox(false, 0);
140 pack_start(candidates_hbox, false, false, 0);
141 Gtk.VBox labels_vbox = new Gtk.VBox(true, 0);
142 Gtk.VBox candidates_vbox = new Gtk.VBox(true, 0);
143 candidates_hbox.pack_start(labels_vbox, false, false, 4);
144 candidates_hbox.pack_start(new VSeparator(), false, false, 0);
145 candidates_hbox.pack_start(candidates_vbox, true, true, 4);
148 pack_start(new HSeparator(), false, false, 0);
151 Gtk.HBox buttons_hbox = new Gtk.HBox(false, 0);
152 Gtk.Label state_label = new Gtk.Label(null);
153 state_label.set_size_request(20, -1);
154 buttons_hbox.pack_start(state_label, true, true, 0);
155 buttons_hbox.pack_start(prev_button, false, false, 0);
156 buttons_hbox.pack_start(next_button, false, false, 0);
157 pack_start(buttons_hbox, false, false, 0);
162 for (int i = 0; i < 16; i++) {
163 Gtk.Label label = new Gtk.Label(LABELS[i]);
164 label.set_alignment(0.0f, 0.5f);
168 Gtk.Label candidate = new Gtk.Label("test");
169 candidate.set_alignment(0.0f, 0.5f);
171 m_candidates += candidate;
173 label.set_property("xpad", 8);
174 candidate.set_property("xpad", 8);
176 // Make a copy of i to workaround a bug in vala.
177 // https://bugzilla.gnome.org/show_bug.cgi?id=628336
179 Gtk.EventBox label_ebox = new Gtk.EventBox();
180 label_ebox.set_no_show_all(true);
181 label_ebox.button_press_event.connect((w, e) => {
182 candidate_clicked(i, e.button, e.state);
185 label_ebox.add(label);
186 labels_vbox.pack_start(label_ebox, false, false, 2);
187 m_widgets += label_ebox;
189 Gtk.EventBox candidate_ebox = new Gtk.EventBox();
190 candidate_ebox.set_no_show_all(true);
191 candidate_ebox.button_press_event.connect((w, e) => {
192 candidate_clicked(index, e.button, e.state);
195 candidate_ebox.add(candidate);
196 candidates_vbox.pack_start(candidate_ebox, false, false, 2);
197 m_widgets += candidate_ebox;
200 Gtk.HBox hbox = new Gtk.HBox(false, 0);
206 for (int i = 0; i < 16; i++) {
207 Gtk.Label label = new Gtk.Label(LABELS[i]);
208 label.set_alignment(0.0f, 0.5f);
212 Gtk.Label candidate = new Gtk.Label("test");
213 candidate.set_alignment(0.0f, 0.5f);
215 m_candidates += candidate;
217 Gtk.HBox candidate_hbox = new Gtk.HBox(false, 0);
218 candidate_hbox.show();
219 candidate_hbox.pack_start(label, false, false, 2);
220 candidate_hbox.pack_start(candidate, false, false, 2);
222 // Make a copy of i to workaround a bug in vala.
223 // https://bugzilla.gnome.org/show_bug.cgi?id=628336
225 Gtk.EventBox ebox = new Gtk.EventBox();
226 ebox.set_no_show_all(true);
227 ebox.button_press_event.connect((w, e) => {
228 candidate_clicked(index, e.button, e.state);
231 ebox.add(candidate_hbox);
232 hbox.pack_start(ebox, false, false, 4);
235 hbox.pack_start(new VSeparator(), false, false, 0);
236 hbox.pack_start(prev_button, false, false, 0);
237 hbox.pack_start(next_button, false, false, 0);