1 #include "IBusChewingSystray.h"
2
3 /*=== Internal functions start ===*/
4
ibus_chewing_systray_left_click_callback_interface(GtkStatusIcon * icon,gpointer userData)5 void ibus_chewing_systray_left_click_callback_interface(GtkStatusIcon *
6 icon,
7 gpointer userData)
8 {
9 IBusChewingSystrayIcon *systrayIcon =
10 (IBusChewingSystrayIcon *) userData;
11 systrayIcon->leftClickFunc(systrayIcon, systrayIcon->leftClickData);
12 }
13
ibus_chewing_systray_right_click_callback_interface(GtkStatusIcon * icon,GdkEvent * event,gpointer userData)14 void ibus_chewing_systray_right_click_callback_interface(GtkStatusIcon *
15 icon,
16 GdkEvent * event,
17 gpointer userData)
18 {
19 IBusChewingSystrayIcon *systrayIcon =
20 (IBusChewingSystrayIcon *) userData;
21 if (event->type == GDK_BUTTON_RELEASE) {
22 if (((GdkEventButton *) event)->button == 3) {
23 /* Right Click release */
24 systrayIcon->rightClickFunc(systrayIcon,
25 systrayIcon->rightClickData);
26 }
27 }
28 }
29
30 /*=== Member functions start ===*/
31 IBusChewingSystrayIcon
ibus_chewing_systray_icon_new(guint defaultValue,IBusChewingSystrayClickFunc leftClickFunc,gpointer leftClickData,IBusChewingSystrayClickFunc rightClickFunc,gpointer rightClickData,...)32 * ibus_chewing_systray_icon_new(guint defaultValue,
33 IBusChewingSystrayClickFunc
34 leftClickFunc,
35 gpointer leftClickData,
36 IBusChewingSystrayClickFunc
37 rightClickFunc,
38 gpointer rightClickData, ...)
39 {
40 IBUS_CHEWING_LOG(DEBUG, "* ibus_chewing_systray_icon_new()");
41 va_list argList;
42 const gchar *iconFile;
43
44 IBusChewingSystrayIcon *self = g_new0(IBusChewingSystrayIcon, 1);
45 self->icon = gtk_status_icon_new();
46 self->iconFileArray = g_ptr_array_new();
47 self->iconCacheArray = g_ptr_array_new();
48
49 va_start(argList, rightClickData);
50 for (gint i = 0; i < IBUS_CHEWING_SYSTRAY_ICON_COUNT_MAX; i++) {
51 iconFile = va_arg(argList, const gchar *);
52 if (iconFile == NULL) {
53 break;
54 }
55 gtk_status_icon_set_from_file(self->icon, iconFile);
56 GdkPixbuf *pbuf=gtk_status_icon_get_pixbuf(self->icon);
57 GVariant *cacheGVar=g_icon_serialize(G_ICON(pbuf));
58 g_ptr_array_add(self->iconFileArray, (gpointer) iconFile);
59 g_ptr_array_add(self->iconCacheArray, (gpointer) cacheGVar);
60 }
61 va_end(argList);
62
63 self->leftClickFunc = leftClickFunc;
64 self->leftClickData = leftClickData;
65 if (leftClickFunc != NULL) {
66 g_signal_connect(G_OBJECT(self->icon), "activate",
67 G_CALLBACK
68 (ibus_chewing_systray_left_click_callback_interface),
69 self);
70 }
71 self->rightClickFunc = rightClickFunc;
72 self->rightClickData = rightClickData;
73 if (rightClickFunc != NULL) {
74 g_signal_connect(G_OBJECT(self->icon), "button-release-event",
75 G_CALLBACK
76 (ibus_chewing_systray_right_click_callback_interface),
77 self);
78 }
79 ibus_chewing_systray_icon_set_value(self, defaultValue);
80 gtk_status_icon_set_visible(self->icon, TRUE);
81 return self;
82 }
83
ibus_chewing_systray_icon_free(IBusChewingSystrayIcon * self)84 void ibus_chewing_systray_icon_free(IBusChewingSystrayIcon * self)
85 {
86 gtk_status_icon_set_visible(self->icon, FALSE);
87 g_object_unref(self->icon);
88 g_ptr_array_free(self->iconCacheArray, TRUE);
89 g_ptr_array_free(self->iconFileArray, TRUE);
90 g_free(self);
91 }
92
ibus_chewing_systray_icon_set_value(IBusChewingSystrayIcon * self,guint value)93 void ibus_chewing_systray_icon_set_value(IBusChewingSystrayIcon *
94 self, guint value)
95 {
96 self->value = value;
97 }
98
ibus_chewing_systray_icon_set_visible(IBusChewingSystrayIcon * self,gboolean visible)99 void ibus_chewing_systray_icon_set_visible(IBusChewingSystrayIcon *
100 self, gboolean visible)
101 {
102 gtk_status_icon_set_visible(self->icon, visible);
103 }
104
105
ibus_chewing_systray_icon_update(IBusChewingSystrayIcon * self)106 void ibus_chewing_systray_icon_update(IBusChewingSystrayIcon * self)
107 {
108 GVariant *cacheGVar =
109 (GVariant *) g_ptr_array_index(self->iconCacheArray, self->value);
110 GIcon *cachedIcon=g_icon_deserialize(g_variant_ref_sink(cacheGVar));
111 g_variant_unref(cacheGVar);
112 gtk_status_icon_set_from_gicon(self->icon, cachedIcon);
113 ibus_chewing_systray_icon_set_visible(self, TRUE);
114 }
115
116 /*=== Chi_Eng systray Icon ===*/
117 /**
118 * ibus_chewing_systray_chi_eng_toggle_callback:
119 */
ibus_chewing_systray_chi_eng_toggle_callback(IBusChewingSystrayIcon * self,gpointer userData)120 void ibus_chewing_systray_chi_eng_toggle_callback(IBusChewingSystrayIcon *
121 self, gpointer userData)
122 {
123 IBusChewingEngine *iEngine = (IBusChewingEngine *) userData;
124 ibus_chewing_pre_edit_toggle_chi_eng_mode(iEngine->icPreEdit);
125 ibus_chewing_systray_chi_eng_icon_refresh_value(iEngine);
126 }
127
128 /**
129 * ibus_chewing_systray_full_half_toggle_callback:
130 */
ibus_chewing_systray_full_half_toggle_callback(IBusChewingSystrayIcon * self,gpointer userData)131 void ibus_chewing_systray_full_half_toggle_callback(IBusChewingSystrayIcon
132 * self,
133 gpointer userData)
134 {
135 IBusChewingEngine *iEngine = (IBusChewingEngine *) userData;
136 ibus_chewing_pre_edit_toggle_full_half_mode(iEngine->icPreEdit);
137 ibus_chewing_systray_chi_eng_icon_refresh_value(iEngine);
138 }
139
140 IBusChewingSystrayIcon
ibus_chewing_systray_chi_eng_icon_new(IBusChewingEngine * iEngine)141 * ibus_chewing_systray_chi_eng_icon_new(IBusChewingEngine * iEngine)
142 {
143 IBusChewingSystrayIcon *iChiEngSystrayIcon =
144 ibus_chewing_systray_icon_new(1,
145 ibus_chewing_systray_chi_eng_toggle_callback,
146 (gpointer)
147 iEngine,
148 ibus_chewing_systray_full_half_toggle_callback,
149 iEngine,
150 QUOTE_ME(PRJ_ICON_DIR)
151 "/ibus-chewing-eng-half.svg",
152 QUOTE_ME(PRJ_ICON_DIR)
153 "/ibus-chewing-chi-half.svg",
154 QUOTE_ME(PRJ_ICON_DIR)
155 "/ibus-chewing-eng-full.svg",
156 QUOTE_ME(PRJ_ICON_DIR)
157 "/ibus-chewing-chi-full.svg",
158 NULL);
159 gtk_status_icon_set_tooltip_text(iChiEngSystrayIcon->icon,
160 _
161 ("Left click to toggle Chi/Eng; Right click to toggle full/half shape"));
162 return iChiEngSystrayIcon;
163 }
164
165 gboolean
ibus_chewing_systray_chi_eng_icon_create_or_hide(IBusChewingEngine * iEngine)166 ibus_chewing_systray_chi_eng_icon_create_or_hide(IBusChewingEngine *
167 iEngine)
168 {
169 if (ibus_chewing_pre_edit_get_property_boolean
170 (iEngine->icPreEdit, "show-systray")) {
171 if (iEngine->iChiEngSystrayIcon == NULL) {
172 iEngine->iChiEngSystrayIcon =
173 ibus_chewing_systray_chi_eng_icon_new(iEngine);
174 }
175 ibus_chewing_systray_icon_set_visible(iEngine->iChiEngSystrayIcon,
176 TRUE);
177 return TRUE;
178 }
179 if (iEngine->iChiEngSystrayIcon != NULL) {
180 ibus_chewing_systray_icon_set_visible(iEngine->iChiEngSystrayIcon,
181 FALSE);
182 }
183 return FALSE;
184 }
185
ibus_chewing_systray_chi_eng_icon_refresh_value(IBusChewingEngine * iEngine)186 void ibus_chewing_systray_chi_eng_icon_refresh_value(IBusChewingEngine *
187 iEngine)
188 {
189 if (ibus_chewing_pre_edit_get_chi_eng_mode(iEngine->icPreEdit)) {
190 mkdg_set_flag(iEngine->iChiEngSystrayIcon->value,
191 IBUS_CHEWING_SYSTRAY_CHINESE_FLAG);
192 } else {
193 mkdg_clear_flag(iEngine->iChiEngSystrayIcon->value,
194 IBUS_CHEWING_SYSTRAY_CHINESE_FLAG);
195 }
196
197 if (ibus_chewing_pre_edit_get_full_half_mode(iEngine->icPreEdit)) {
198 mkdg_set_flag(iEngine->iChiEngSystrayIcon->value,
199 IBUS_CHEWING_SYSTRAY_FULL_HALF_SHAPE_FLAG);
200 } else {
201 mkdg_clear_flag(iEngine->iChiEngSystrayIcon->value,
202 IBUS_CHEWING_SYSTRAY_FULL_HALF_SHAPE_FLAG);
203 }
204 ibus_chewing_systray_icon_update(iEngine->iChiEngSystrayIcon);
205 }
206