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