1 /*
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail    : see the 'copyright' file.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program 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 General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 
21 #ifndef __CAIRO_DIALOG_FACTORY__
22 #define  __CAIRO_DIALOG_FACTORY__
23 
24 #include "cairo-dock-container.h"
25 #include "cairo-dock-dialog-manager.h"  // CairoDialogAttr
26 G_BEGIN_DECLS
27 
28 /** @file cairo-dock-dialog-factory.h This class defines the Dialog container, useful to bring interaction with the user.
29 * A Dialog is a container that points to an icon. It contains the following optionnal components :
30 * - a message
31 * - an image on its left
32 * - a interaction widget below it
33 * - some buttons at the bottom.
34 *
35 * A Dialog is constructed with a set of attributes grouped inside a _CairoDialogAttribute.
36 * It has a Decorator that draws its shape, and a Renderer that draws its content.
37 *
38 * To add buttons, you specify a list of images in the attributes. "ok" and "cancel" are key words for the default ok/cancel buttons. You also has to provide a callback function that will be called on click. When the user clicks on a button, the function is called with the number of the clicked button, counted from 0. -1 and -2 are set if the user pushed the Return or Escape keys. The dialog is unreferenced after the user's answer, so <i>you have to reference the dialog in the callback if you want to keep the dialog alive</i>.
39 *
40 * This class defines various helper functions to build a Dialog.
41 *
42 * Note that Dialogs and Menus share the same rendering.
43 */
44 
45 typedef gpointer CairoDialogRendererDataParameter;
46 typedef CairoDialogRendererDataParameter* CairoDialogRendererDataPtr;
47 typedef gpointer CairoDialogRendererConfigParameter;
48 typedef CairoDialogRendererConfigParameter* CairoDialogRendererConfigPtr;
49 
50 typedef void (* CairoDialogRenderFunc) (cairo_t *pCairoContext, CairoDialog *pDialog, double fAlpha);
51 typedef void (* CairoDialogGLRenderFunc) (CairoDialog *pDialog, double fAlpha);
52 typedef gpointer (* CairoDialogConfigureRendererFunc) (CairoDialog *pDialog, CairoDialogRendererConfigPtr pConfig);
53 typedef void (* CairoDialogUpdateRendererDataFunc) (CairoDialog *pDialog, CairoDialogRendererDataPtr pNewData);
54 typedef void (* CairoDialogFreeRendererDataFunc) (CairoDialog *pDialog);
55 /// Definition of a Dialog renderer. It draws the inside of the Dialog.
56 struct _CairoDialogRenderer {
57 	CairoDialogRenderFunc 				render;
58 	CairoDialogConfigureRendererFunc 	configure;
59 	CairoDialogFreeRendererDataFunc 	free_data;
60 	CairoDialogUpdateRendererDataFunc 	update;
61 	CairoDialogGLRenderFunc 			render_opengl;
62 };
63 
64 typedef void (* CairoDialogSetDecorationSizeFunc) (CairoDialog *pDialog);
65 typedef void (* CairoDialogRenderDecorationFunc) (cairo_t *pCairoContext, CairoDialog *pDialog);
66 typedef void (* CairoDialogGLRenderDecorationFunc) (CairoDialog *pDialog);
67 typedef void (* CairoMenuSetupFunc) (GtkWidget *pMenu);
68 typedef void (* CairoMenuRenderFunc) (GtkWidget *pMenu, cairo_t *pCairoContext);
69 /// Definition of a Dialog/Menu decorator. It draws the frame of the Dialog/Menu.
70 struct _CairoDialogDecorator {
71 	/// defines the various margins and alignment of the dialog
72 	CairoDialogSetDecorationSizeFunc    set_size;
73 	/// draw the dialog's frame (outline and background)
74 	CairoDialogRenderDecorationFunc     render;
75 	CairoDialogGLRenderDecorationFunc   render_opengl;  // not used, all drawings are done with cairo
76 	/// defines the GldiMenuParams of the menu (radius, alignment, arrow height)
77 	CairoMenuSetupFunc                  setup_menu;
78 	/// draw the menu's frame (outline and background); in the end, must clip the shape of the frame on the context
79 	CairoMenuRenderFunc                 render_menu;
80 	/// readable name of the decorator
81 	const gchar *cDisplayedName;
82 };
83 
84 struct _CairoDialogButton {
85 	cairo_surface_t *pSurface;
86 	GLuint iTexture;
87 	gint iOffset;  // offset courant du au clic.
88 	gint iDefaultType;  // used if no surface, 0 = Cancel image, 1 = Ok image.
89 };
90 
91 /// Definition of a Dialog.
92 struct _CairoDialog {
93 	/// container.
94 	GldiContainer container;
95 	//\_____________________ Position
96 	Icon *pIcon;// icon sur laquelle pointe the dialog.
97 	gint iAimedX;// position en X visee par la pointe dans le referentiel de l'ecran.
98 	gint iAimedY;// position en Y visee par la pointe dans le referentiel de l'ecran.
99 	gboolean bRight;// TRUE ssi the dialog est a droite de l'écran; dialog a droite <=> pointe a gauche.
100 	gint iComputedPositionX;  // position du coin du dialogue dependant de sa gravite.
101 	gint iComputedPositionY;
102 	gint iComputedWidth;
103 	gint iComputedHeight;
104 	//\_____________________ Structure interne.
105 	gint iBubbleWidth, iBubbleHeight;// dimensions de la bulle (message + widget utilisateur + boutons).
106 	gint iMessageWidth, iMessageHeight;// dimensions du message en comptant la marge du texte + vgap en bas si necessaire.
107 	gint iButtonsWidth, iButtonsHeight;// dimensions des boutons + vgap en haut.
108 	gint iInteractiveWidth, iInteractiveHeight;// dimensions du widget interactif.
109 	GtkWidget *pLeftPaddingBox, *pRightPaddingBox, *pWidgetLayout;// la structure interne du widget.
110 	GtkWidget *pMessageWidget;// le widget de remplissage ou l'on dessine le message.
111 	GtkWidget *pButtonsWidget;// le widget de remplissage ou l'on dessine les boutons.
112 	GtkWidget *pTipWidget;// le widget de remplissage ou l'on dessine la pointe.
113 	GtkWidget *pTopWidget;// le widget de remplissage de la marge du haut.
114 
115 	//\_____________________ Elements visibles.
116 	gint iTextWidth, iTextHeight;// dimension de la surface du texte.
117 	cairo_surface_t* pTextBuffer;// surface representant the message to display.
118 	GLuint iTextTexture;
119 	gint iIconSize;// dimension de the icon, sans les marges (0 si aucune icon).
120 	cairo_surface_t* pIconBuffer;// surface representant the icon dans la marge a gauche du texte.
121 	GLuint iIconTexture;
122 	GtkWidget *pInteractiveWidget;// le widget d'interaction utilisateur (GtkEntry, GtkHScale, zone de dessin, etc).
123 	gint iNbButtons;// number of buttons.
124 	CairoDialogButton *pButtons;// List of buttons.
125 	//\_____________________ Renderer
126 	CairoDialogRenderer *pRenderer;// le moteur de rendu utilise pour dessiner the dialog.
127 	gpointer pRendererData;// donnees pouvant etre utilisees par le moteur de rendu.
128 	//\_____________________ Decorateur
129 	CairoDialogDecorator *pDecorator;// le decorateur de fenetre.
130 	gint iLeftMargin, iRightMargin, iTopMargin, iBottomMargin, iMinFrameWidth, iMinBottomGap;// taille que s'est reserve le decorateur.
131 	gdouble fAlign;// alignement de la pointe.
132 	gint iIconOffsetX, iIconOffsetY;// decalage de l'icone.
133 	//\_____________________ Actions
134 	CairoDockActionOnAnswerFunc action_on_answer;// fonction appelee au clique sur l'un des boutons.
135 	gpointer pUserData;// donnees transmises a la fonction.
136 	GFreeFunc pFreeUserDataFunc;// fonction appelee pour liberer les donnees.
137 
138 	gint iSidTimer;// le timer pour la destruction automatique du dialog.
139 	gboolean bUseMarkup;// whether markup is used to draw the text (as defined in the attributes on init)
140 	gboolean bNoInput;// whether the dialog is transparent to mouse input.
141 	gboolean bAllowMinimize;  // TRUE to allow the dialog to be minimized once. The flag is reseted to FALSE after the desklet has minimized.
142 	GTimer *pUnmapTimer;  // timer to filter 2 consecutive unmap events
143 	cairo_region_t* pShapeBitmap;
144 	gboolean bPositionForced;
145 	gdouble fAppearanceCounter;
146 	gboolean bTopBottomDialog;
147 	gboolean bHideOnClick;
148 	guint iButtonPressTime;
149 	gboolean bInAnswer;
150 	gchar *cText;
151 	gpointer reserved[1];
152 };
153 
154 #define CAIRO_DIALOG_FIRST_BUTTON 0
155 #define CAIRO_DIALOG_ENTER_KEY -1
156 #define CAIRO_DIALOG_ESCAPE_KEY -2
157 
158 #define CAIRO_DIALOG_MIN_SIZE 20
159 #define CAIRO_DIALOG_TEXT_MARGIN 3
160 #define CAIRO_DIALOG_MIN_ENTRY_WIDTH 150
161 #define CAIRO_DIALOG_MIN_SCALE_WIDTH 150
162 #define CAIRO_DIALOG_BUTTON_OFFSET 3
163 #define CAIRO_DIALOG_VGAP 4
164 #define CAIRO_DIALOG_BUTTON_GAP 16
165 
166 /** Say if an object is a Dialog.
167 *@param obj the object.
168 *@return TRUE if the object is a dialog.
169 */
170 #define CAIRO_DOCK_IS_DIALOG(obj) gldi_object_is_manager_child (GLDI_OBJECT(obj), &myDialogObjectMgr)
171 
172 /** Cast a Container into a Dialog.
173 *@param pContainer the container.
174 *@return the dialog.
175 */
176 #define CAIRO_DIALOG(pContainer) ((CairoDialog *)pContainer)
177 
178 void gldi_dialog_init_internals (CairoDialog *pDialog, CairoDialogAttr *pAttribute);
179 
180 /** Create a new dialog.
181 *@param pAttribute attributes of the dialog.
182 *@return the dialog.
183 */
184 CairoDialog *gldi_dialog_new (CairoDialogAttr *pAttribute);
185 
186 /** Pop up a dialog with a message, a widget, 2 buttons ok/cancel and an icon, all optionnal.
187 *@param cText the message to display.
188 *@param pIcon the icon that will hold the dialog.
189 *@param pContainer the container of the icon.
190 *@param fTimeLength the duration of the dialog (in ms), or 0 for an unlimited dialog.
191 *@param cIconPath path to an icon to display in the margin.
192 *@param pInteractiveWidget a GTK widget; It is destroyed with the dialog. Use 'cairo_dock_steal_interactive_widget_from_dialog()' before if you want to keep it alive.
193 *@param pActionFunc the callback called when the user makes its choice. NULL means there will be no buttons.
194 *@param data data passed as a parameter of the callback.
195 *@param pFreeDataFunc function used to free the data when the dialog is destroyed, or NULL if unnecessary.
196 *@return the newly created dialog.
197 */
198 CairoDialog *gldi_dialog_show (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength, const gchar *cIconPath, GtkWidget *pInteractiveWidget, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc);
199 
200 /** Pop up a dialog with a message, and a limited duration, and an icon in the margin.
201 *@param cText the message to display.
202 *@param pIcon the icon that will hold the dialog.
203 *@param pContainer the container of the icon.
204 *@param fTimeLength the duration of the dialog (in ms), or 0 for an unlimited dialog.
205 *@param cIconPath path to an icon.
206 *@param ... arguments to insert in the message, in a printf way.
207 *@return the newly created dialog.
208 */
209 CairoDialog *gldi_dialog_show_temporary_with_icon_printf (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength, const gchar *cIconPath, ...) G_GNUC_PRINTF (1, 6);
210 
211 /** Pop up a dialog with a message, and a limited duration, and an icon in the margin.
212 *@param cText the message to display.
213 *@param pIcon the icon that will hold the dialog.
214 *@param pContainer the container of the icon.
215 *@param fTimeLength the duration of the dialog (in ms), or 0 for an unlimited dialog.
216 *@param cIconPath path to an icon.
217 *@return the newly created dialog.
218 */
219 CairoDialog *gldi_dialog_show_temporary_with_icon (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength, const gchar *cIconPath);
220 
221 /** Pop up a dialog with a message, and a limited duration, with no icon.
222 *@param cText the message to display.
223 *@param pIcon the icon that will hold the dialog.
224 *@param pContainer the container of the icon.
225 *@param fTimeLength the duration of the dialog (in ms), or 0 for an unlimited dialog.
226 *@return the newly created dialog et visible, avec une reference a 1.
227 */
228 CairoDialog *gldi_dialog_show_temporary (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength);
229 
230 /** Pop up a dialog with a message, and a limited duration, and a default icon.
231 *@param cText the format of the message to display.
232 *@param pIcon the icon that will hold the dialog.
233 *@param pContainer the container of the icon.
234 *@param fTimeLength the duration of the dialog (in ms), or 0 for an unlimited dialog.
235 *@return the newly created dialog et visible, avec une reference a 1.
236 */
237 CairoDialog *gldi_dialog_show_temporary_with_default_icon (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, double fTimeLength);
238 
239 /** Pop up a dialog with a question and 2 buttons ok/cancel.
240 * The dialog is unreferenced after the user has answered, so if you want to keep it alive, you have to reference it in the callback.
241 *@param cText the message to display.
242 *@param pIcon the icon that will hold the dialog.
243 *@param pContainer the container of the icon.
244 *@param cIconPath path to an icon to display in the margin.
245 *@param pActionFunc the callback.
246 *@param data data passed as a parameter of the callback.
247 *@param pFreeDataFunc function used to free the data.
248 *@return the newly created dialog et visible, avec une reference a 1.
249 */
250 CairoDialog *gldi_dialog_show_with_question (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, const gchar *cIconPath, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc);
251 
252 /** Pop up a dialog with a text entry and 2 buttons ok/cancel.
253 * The dialog is unreferenced after the user has answered, so if you want to keep it alive, you have to reference it in the callback.
254 *@param cText the message to display.
255 *@param pIcon the icon that will hold the dialog.
256 *@param pContainer the container of the icon.
257 *@param cIconPath path to an icon to display in the margin.
258 *@param cTextForEntry text to display initially in the entry.
259 *@param pActionFunc the callback.
260 *@param data data passed as a parameter of the callback.
261 *@param pFreeDataFunc function used to free the data.
262 *@return the newly created dialog.
263 */
264 CairoDialog *gldi_dialog_show_with_entry (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, const gchar *cIconPath, const gchar *cTextForEntry, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc);
265 
266 /** Pop up a dialog with an horizontal scale between 0 and fMaxValue and 2 buttons ok/cancel.
267 * The dialog is unreferenced after the user has answered, so if you want to keep it alive, you have to reference it in the callback.
268 *@param cText the message to display.
269 *@param pIcon the icon that will hold the dialog.
270 *@param pContainer the container of the icon.
271 *@param cIconPath path to an icon to display in the margin.
272 *@param fValue initial value of the scale.
273 *@param fMaxValue maximum value of the scale.
274 *@param pActionFunc the callback.
275 *@param data data passed as a parameter of the callback.
276 *@param pFreeDataFunc function used to free the data.
277 *@return the newly created dialog.
278 */
279 CairoDialog *gldi_dialog_show_with_value (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, const gchar *cIconPath, double fValue, double fMaxValue, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc);
280 
281 /** Pop up a dialog, pointing on "the best icon possible". This allows to display a general message.
282 *@param cMessage the message.
283 *@param fTimeLength life time of the dialog, in ms.
284 *@return the newly created dialog, visible and with a reference of 1.
285 */
286 CairoDialog * gldi_dialog_show_general_message (const gchar *cMessage, double fTimeLength);
287 
288 /** Pop up a dialog with GTK widget and 2 buttons ok/cancel, and block until the user makes its choice.
289 *@param cText the message to display.
290 *@param pIcon the icon that will hold the dialog.
291 *@param pContainer the container of the icon.
292 *@param cIconPath path to an icon to display in the margin.
293 *@param pInteractiveWidget an interactive widget.
294 *@return the number of the button that was clicked : 0 or -1 for OK, 1 or -2 for CANCEL, -3 if the dialog has been destroyed before. The dialog is destroyed after the user choosed, but the interactive widget is not destroyed, which allows to retrieve the changes made by the user. Destroy it with 'gtk_widget_destroy' when you're done with it.
295 */
296 int gldi_dialog_show_and_wait (const gchar *cText, Icon *pIcon, GldiContainer *pContainer, const gchar *cIconPath, GtkWidget *pInteractiveWidget);
297 
298 
299 GtkWidget *cairo_dock_steal_widget_from_its_container (GtkWidget *pWidget);  // should be elsewhere
300 
301 /** Detach the interactive widget from a dialog. The widget can then be placed anywhere after that. You have to unref it after you placed it into a container, or to destroy it.
302 *@param pDialog the desklet with an interactive widget.
303 *@return the widget.
304 */
305 GtkWidget *gldi_dialog_steal_interactive_widget (CairoDialog *pDialog);
306 
307 void gldi_dialog_redraw_interactive_widget (CairoDialog *pDialog);
308 
309 void gldi_dialog_set_icon (CairoDialog *pDialog, const gchar *cImageFilePath);
310 void gldi_dialog_set_icon_surface (CairoDialog *pDialog, cairo_surface_t *pNewIconSurface, int iNewIconSize);
311 
312 void gldi_dialog_set_message (CairoDialog *pDialog, const gchar *cMessage);
313 void gldi_dialog_set_message_printf (CairoDialog *pDialog, const gchar *cMessageFormat, ...);
314 
315 void gldi_dialog_reload (CairoDialog *pDialog);
316 
317 #define gldi_dialog_set_widget_text_color(...)
318 #define gldi_dialog_set_widget_bg_color(...)
319 
320 G_END_DECLS
321 #endif
322