2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
23
#include <gdk/gdkkeysyms.h>
25
#include <gtk/gtkgl.h>
29
#include <gdk/x11/gdkglx.h>
31
#include "cairo-dock-icons.h"
32
#include "cairo-dock-container.h"
33
#include "cairo-dock-load.h"
34
#include "cairo-dock-draw.h"
35
#include "cairo-dock-draw-opengl.h"
36
#include "cairo-dock-log.h"
37
#include "cairo-dock-desklet.h"
38
#include "cairo-dock-dock-manager.h"
39
#include "cairo-dock-dock-facility.h"
40
#include "cairo-dock-renderer-manager.h"
41
#include "cairo-dock-surface-factory.h"
42
#include "cairo-dock-internal-accessibility.h"
43
#include "cairo-dock-internal-dialogs.h"
44
#include "cairo-dock-internal-system.h"
45
#include "cairo-dock-animations.h"
46
#include "cairo-dock-notifications.h"
47
#include "cairo-dock-callbacks.h"
48
#include "cairo-dock-launcher-factory.h"
49
#include "cairo-dock-gui-manager.h"
50
#include "cairo-dock-applications-manager.h"
51
#include "cairo-dock-dialogs.h"
53
extern CairoDock *g_pMainDock;
54
extern gint g_iXScreenWidth[2], g_iXScreenHeight[2];
55
extern gint g_iScreenWidth[2], g_iScreenHeight[2];
56
extern gboolean g_bSticky;
57
extern gboolean g_bKeepAbove;
58
extern gboolean g_bUseOpenGL;
60
static GSList *s_pDialogList = NULL;
61
static cairo_surface_t *s_pButtonOkSurface = NULL;
62
static cairo_surface_t *s_pButtonCancelSurface = NULL;
63
static GLuint s_iButtonOkTexture = 0;
64
static GLuint s_iButtonCancelTexture = 0;
66
#define CAIRO_DIALOG_MIN_SIZE 20
67
#define CAIRO_DIALOG_TEXT_MARGIN 3
68
#define CAIRO_DIALOG_MIN_ENTRY_WIDTH 150
69
#define CAIRO_DIALOG_MIN_SCALE_WIDTH 150
70
#define CAIRO_DIALOG_BUTTON_OFFSET 3
71
#define CAIRO_DIALOG_VGAP 4
72
#define CAIRO_DIALOG_BUTTON_GAP 16
74
gboolean on_enter_dialog (GtkWidget* pWidget,
75
GdkEventCrossing* pEvent,
79
pDialog->container.bInside = TRUE;
83
static gboolean on_leave_dialog (GtkWidget* pWidget,
84
GdkEventCrossing* pEvent,
87
/*cd_debug ("debut d'attente...");
88
while (gtk_events_pending ())
89
gtk_main_iteration ();
90
cd_debug ("fin d'attente, bInside : %d\n", pDialog->container.bInside);*/
92
gdk_window_get_pointer (pDialog->container.pWidget->window, &iMouseX, &iMouseY, NULL);
93
if (iMouseX > 0 && iMouseX < pDialog->container.iWidth && iMouseY > 0 && iMouseY < pDialog->container.iHeight)
95
cd_debug ("en fait on est dedans");
99
//cd_debug ("outside (%d;%d / %dx%d)", iMouseX, iMouseY, pDialog->container.iWidth, pDialog->container.iHeight);
100
pDialog->container.bInside = FALSE;
101
Icon *pIcon = pDialog->pIcon;
102
if (pIcon != NULL /*&& (pEvent->state & GDK_BUTTON1_MASK) == 0*/)
104
pDialog->container.iWindowPositionX = pEvent->x_root;
105
pDialog->container.iWindowPositionY = pEvent->y_root;
106
CairoContainer *pContainer = cairo_dock_search_container_from_icon (pIcon);
107
cairo_dock_place_dialog (pDialog, pContainer);
108
///gtk_widget_queue_draw (pDialog->container.pWidget);
114
static int _cairo_dock_find_clicked_button_in_dialog (GdkEventButton* pButton, CairoDialog *pDialog)
116
int iButtonX, iButtonY;
117
int i, n = pDialog->iNbButtons;
118
iButtonY = (pDialog->container.bDirectionUp ?
119
pDialog->iTopMargin + pDialog->iMessageHeight + pDialog->iInteractiveHeight + CAIRO_DIALOG_VGAP :
120
pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iButtonsHeight));
121
int iMinButtonX = .5 * (pDialog->container.iWidth - (n - 1) * CAIRO_DIALOG_BUTTON_GAP - n * myDialogs.iDialogButtonWidth);
122
for (i = 0; i < pDialog->iNbButtons; i++)
124
iButtonX = iMinButtonX + i * (CAIRO_DIALOG_BUTTON_GAP + myDialogs.iDialogButtonWidth);
125
if (pButton->x >= iButtonX && pButton->x <= iButtonX + myDialogs.iDialogButtonWidth && pButton->y >= iButtonY && pButton->y <= iButtonY + myDialogs.iDialogButtonHeight)
133
static gboolean on_button_press_dialog (GtkWidget* pWidget,
134
GdkEventButton* pButton,
135
CairoDialog *pDialog)
137
if (pButton->button == 1) // clique gauche.
139
if (pButton->type == GDK_BUTTON_PRESS)
141
if (pDialog->pButtons == NULL && pDialog->pInteractiveWidget == NULL) // ce n'est pas un dialogue interactif.
143
cairo_dock_dialog_unreference (pDialog);
145
else if (pDialog->pButtons != NULL)
147
int iButton = _cairo_dock_find_clicked_button_in_dialog (pButton, pDialog);
148
if (iButton >= 0 && iButton < pDialog->iNbButtons)
150
pDialog->pButtons[iButton].iOffset = CAIRO_DIALOG_BUTTON_OFFSET;
151
gtk_widget_queue_draw (pDialog->container.pWidget);
155
else if (pButton->type == GDK_BUTTON_RELEASE)
157
if (pDialog->pButtons != NULL)
159
int iButton = _cairo_dock_find_clicked_button_in_dialog (pButton, pDialog);
160
cd_debug ("clic on button %d", iButton);
161
if (iButton >= 0 && iButton < pDialog->iNbButtons && pDialog->pButtons[iButton].iOffset != 0)
163
g_print (" -> action !\n");
164
pDialog->pButtons[iButton].iOffset = 0;
165
pDialog->action_on_answer (iButton, pDialog->pInteractiveWidget, pDialog->pUserData, pDialog);
166
gtk_widget_queue_draw (pDialog->container.pWidget); // au cas ou le unref ci-dessous ne le detruirait pas.
167
cairo_dock_dialog_unreference (pDialog);
172
for (i = 0; i < pDialog->iNbButtons; i++)
173
pDialog->pButtons[i].iOffset = 0;
174
gtk_widget_queue_draw (pDialog->container.pWidget);
182
static gboolean on_key_press_dialog (GtkWidget *pWidget,
184
CairoDialog *pDialog)
186
cd_debug ("key pressed");
188
if (pKey->type == GDK_KEY_PRESS && pDialog->action_on_answer != NULL)
190
GdkEventScroll dummyScroll;
192
switch (pKey->keyval)
195
pDialog->action_on_answer (-1, pDialog->pInteractiveWidget, pDialog->pUserData, pDialog);
196
cairo_dock_dialog_unreference (pDialog);
199
pDialog->action_on_answer (-2, pDialog->pInteractiveWidget, pDialog->pUserData, pDialog);
200
cairo_dock_dialog_unreference (pDialog);
207
gboolean cairo_dock_render_dialog_opengl_notification (cairo_t *pCairoContext, CairoDialog *pDialog, double fAlpha)
209
_cairo_dock_enable_texture ();
210
_cairo_dock_set_blend_alpha ();
211
_cairo_dock_set_alpha (fAlpha);
214
if (pDialog->iIconTexture != 0)
216
x = pDialog->iLeftMargin;
217
y = (pDialog->container.bDirectionUp ? pDialog->iTopMargin : pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight));
219
glBindTexture (GL_TEXTURE_2D, pDialog->iIconTexture);
220
_cairo_dock_apply_current_texture_portion_at_size_with_offset (1.*pDialog->iCurrentFrame/pDialog->iNbFrames, 0.,
221
1. / pDialog->iNbFrames, 1.,
222
pDialog->iIconSize, pDialog->iIconSize,
223
x + pDialog->iIconSize/2, pDialog->container.iHeight - y - pDialog->iIconSize/2);
226
if (pDialog->iTextTexture != 0)
228
x = pDialog->iLeftMargin + pDialog->iIconSize + CAIRO_DIALOG_TEXT_MARGIN;
229
y = (pDialog->container.bDirectionUp ? pDialog->iTopMargin : pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight));
230
if (pDialog->iTextHeight < pDialog->iMessageHeight) // on centre le texte.
231
y += (pDialog->iMessageHeight - pDialog->iTextHeight) / 2;
233
glBindTexture (GL_TEXTURE_2D, pDialog->iTextTexture);
234
if (pDialog->iMaxTextWidth != 0 && pDialog->iTextWidth > pDialog->iMaxTextWidth)
236
double w = MIN (pDialog->iMaxTextWidth, pDialog->iTextWidth - pDialog->iCurrentTextOffset); // taille de la portion de texte a gauche.
237
_cairo_dock_apply_current_texture_portion_at_size_with_offset (1.*pDialog->iCurrentTextOffset/pDialog->iTextWidth, 0.,
238
1.*(pDialog->iTextWidth - pDialog->iCurrentTextOffset) / pDialog->iTextWidth, 1.,
239
w, pDialog->iTextHeight,
240
x + w/2, pDialog->container.iHeight - y - pDialog->iTextHeight/2);
242
if (pDialog->iTextWidth - pDialog->iCurrentTextOffset < pDialog->iMaxTextWidth)
244
w = pDialog->iMaxTextWidth - (pDialog->iTextWidth - pDialog->iCurrentTextOffset); // taille de la portion de texte a droite.
245
_cairo_dock_apply_current_texture_portion_at_size_with_offset (0., 0.,
246
w / pDialog->iTextWidth, 1.,
247
w, pDialog->iTextHeight,
248
x + pDialog->iMaxTextWidth - w/2, pDialog->container.iHeight - y - pDialog->iTextHeight/2);
253
_cairo_dock_apply_current_texture_at_size_with_offset (pDialog->iTextWidth, pDialog->iTextHeight,
254
x + pDialog->iTextWidth/2, pDialog->container.iHeight - y - pDialog->iTextHeight/2);
258
if (pDialog->pButtons != NULL)
260
int iButtonX, iButtonY;
261
int i, n = pDialog->iNbButtons;
262
iButtonY = (pDialog->container.bDirectionUp ? pDialog->iTopMargin + pDialog->iMessageHeight + pDialog->iInteractiveHeight + CAIRO_DIALOG_VGAP : pDialog->container.iHeight - pDialog->iTopMargin - pDialog->iButtonsHeight - CAIRO_DIALOG_VGAP);
263
int iMinButtonX = .5 * (pDialog->container.iWidth - (n - 1) * CAIRO_DIALOG_BUTTON_GAP - n * myDialogs.iDialogButtonWidth);
264
for (i = 0; i < pDialog->iNbButtons; i++)
266
iButtonX = iMinButtonX + i * (CAIRO_DIALOG_BUTTON_GAP + myDialogs.iDialogButtonWidth);
267
glBindTexture (GL_TEXTURE_2D, pDialog->pButtons[i].iTexture);
268
_cairo_dock_apply_current_texture_at_size_with_offset (myDialogs.iDialogButtonWidth,
269
myDialogs.iDialogButtonWidth,
270
iButtonX + pDialog->pButtons[i].iOffset + myDialogs.iDialogButtonWidth/2,
271
pDialog->container.iHeight - (iButtonY + pDialog->pButtons[i].iOffset + myDialogs.iDialogButtonWidth/2)); }
274
if (pDialog->pRenderer != NULL && pDialog->pRenderer->render_opengl)
275
pDialog->pRenderer->render_opengl (pDialog, fAlpha);
276
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
279
#define _drawn_text_width(pDialog) (pDialog->iMaxTextWidth != 0 && pDialog->iTextWidth > pDialog->iMaxTextWidth ? pDialog->iMaxTextWidth : pDialog->iTextWidth)
280
#define _paint_inside_dialog(pCairoContext, fAlpha) do { \
282
cairo_paint_with_alpha (pCairoContext, fAlpha); \
284
cairo_paint (pCairoContext); } while (0)
285
static void _cairo_dock_draw_inside_dialog (cairo_t *pCairoContext, CairoDialog *pDialog, double fAlpha)
288
if (pDialog->pIconBuffer != NULL)
290
x = pDialog->iLeftMargin;
291
y = (pDialog->container.bDirectionUp ? pDialog->iTopMargin : pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight));
292
if (pDialog->iNbFrames > 1)
294
cairo_save (pCairoContext);
295
cairo_rectangle (pCairoContext,
300
cairo_clip (pCairoContext);
303
cairo_set_source_surface (pCairoContext,
304
pDialog->pIconBuffer,
305
x - (pDialog->iCurrentFrame * pDialog->iIconSize),
307
_paint_inside_dialog(pCairoContext, fAlpha);
308
if (pDialog->iNbFrames > 1)
309
cairo_restore (pCairoContext);
312
if (pDialog->pTextBuffer != NULL)
314
x = pDialog->iLeftMargin + pDialog->iIconSize + CAIRO_DIALOG_TEXT_MARGIN;
315
y = (pDialog->container.bDirectionUp ? pDialog->iTopMargin : pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight));
316
if (pDialog->iTextHeight < pDialog->iMessageHeight) // on centre le texte.
317
y += (pDialog->iMessageHeight - pDialog->iTextHeight) / 2;
318
if (pDialog->iMaxTextWidth != 0 && pDialog->iTextWidth > pDialog->iMaxTextWidth)
320
cairo_save (pCairoContext);
321
cairo_rectangle (pCairoContext,
324
pDialog->iMaxTextWidth,
325
pDialog->iTextHeight);
326
cairo_clip (pCairoContext);
328
cairo_set_source_surface (pCairoContext,
329
pDialog->pTextBuffer,
330
x - pDialog->iCurrentTextOffset,
332
_paint_inside_dialog(pCairoContext, fAlpha);
334
if (pDialog->iMaxTextWidth != 0 && pDialog->iTextWidth > pDialog->iMaxTextWidth)
336
cairo_set_source_surface (pCairoContext,
337
pDialog->pTextBuffer,
338
x - pDialog->iCurrentTextOffset + pDialog->iTextWidth + 10,
340
_paint_inside_dialog (pCairoContext, fAlpha);
341
cairo_restore (pCairoContext);
345
if (pDialog->pButtons != NULL)
347
int iButtonX, iButtonY;
348
int i, n = pDialog->iNbButtons;
349
iButtonY = (pDialog->container.bDirectionUp ? pDialog->iTopMargin + pDialog->iMessageHeight + pDialog->iInteractiveHeight + CAIRO_DIALOG_VGAP : pDialog->container.iHeight - pDialog->iTopMargin - pDialog->iButtonsHeight - CAIRO_DIALOG_VGAP);
350
int iMinButtonX = .5 * (pDialog->container.iWidth - (n - 1) * CAIRO_DIALOG_BUTTON_GAP - n * myDialogs.iDialogButtonWidth);
351
for (i = 0; i < pDialog->iNbButtons; i++)
353
iButtonX = iMinButtonX + i * (CAIRO_DIALOG_BUTTON_GAP + myDialogs.iDialogButtonWidth);
354
cairo_set_source_surface (pCairoContext,
355
pDialog->pButtons[i].pSurface,
356
iButtonX + pDialog->pButtons[i].iOffset,
357
iButtonY + pDialog->pButtons[i].iOffset);
358
_paint_inside_dialog(pCairoContext, fAlpha);
362
if (pDialog->pRenderer != NULL)
363
pDialog->pRenderer->render (pCairoContext, pDialog, fAlpha);
365
static gboolean on_expose_dialog (GtkWidget *pWidget,
366
GdkEventExpose *pExpose,
367
CairoDialog *pDialog)
369
//g_print ("%s (%dx%d)\n", __func__, pDialog->container.iWidth, pDialog->container.iHeight);
371
if (0 && g_bUseOpenGL && (pDialog->pDecorator == NULL || pDialog->pDecorator->render_opengl != NULL) && (pDialog->pRenderer == NULL || pDialog->pRenderer->render_opengl != NULL))
373
GdkGLContext *pGlContext = gtk_widget_get_gl_context (pDialog->container.pWidget);
374
GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pDialog->container.pWidget);
375
if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
378
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
381
cairo_dock_apply_desktop_background_opengl (CAIRO_CONTAINER (pDialog));
383
if (pDialog->pDecorator != NULL && pDialog->pDecorator->render_opengl != NULL)
386
pDialog->pDecorator->render_opengl (pDialog);
390
cairo_dock_notify (CAIRO_DOCK_RENDER_DIALOG, pDialog, 1.);
391
if (pDialog->container.bUseReflect)
394
pDialog->container.iHeight - 2* (pDialog->iTopMargin + pDialog->iBubbleHeight),
396
glScalef (1., -1., 1.);
397
cairo_dock_notify (CAIRO_DOCK_RENDER_DIALOG, pDialog, pDialog->container.fRatio);
400
if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
401
gdk_gl_drawable_swap_buffers (pGlDrawable);
404
gdk_gl_drawable_gl_end (pGlDrawable);
408
cairo_t *pCairoContext;
410
if ((pExpose->area.x != 0 || pExpose->area.y != 0) && !pDialog->container.bUseReflect)
412
if (pDialog->pIconBuffer != NULL)
414
x = pDialog->iLeftMargin;
415
y = (pDialog->container.bDirectionUp ? pDialog->iTopMargin : pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight));
416
if (pExpose->area.x >= x &&
417
pExpose->area.x + pExpose->area.width <= x + pDialog->iIconSize &&
418
pExpose->area.y >= y &&
419
pExpose->area.y + pExpose->area.height <= y + pDialog->iIconSize)
421
//cd_debug ("icon redraw");
422
pCairoContext = cairo_dock_create_drawing_context_on_area (CAIRO_CONTAINER (pDialog), &pExpose->area, myDialogs.fDialogColor);
423
cairo_set_source_surface (pCairoContext,
424
pDialog->pIconBuffer,
425
x - (pDialog->iCurrentFrame * pDialog->iIconSize),
427
cairo_paint (pCairoContext);
428
cairo_destroy (pCairoContext);
433
if (pDialog->pTextBuffer != NULL)
435
x = pDialog->iLeftMargin + pDialog->iIconSize + CAIRO_DIALOG_TEXT_MARGIN;
436
y = (pDialog->container.bDirectionUp ? pDialog->iTopMargin : pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight));
437
if (pExpose->area.x >= x &&
438
pExpose->area.x + pExpose->area.width <= x + _drawn_text_width (pDialog) &&
439
pExpose->area.y >= y &&
440
pExpose->area.y + pExpose->area.height <= y + pDialog->iTextHeight)
442
//cd_debug ("text redraw");
443
pCairoContext = cairo_dock_create_drawing_context_on_area (CAIRO_CONTAINER (pDialog), &pExpose->area, myDialogs.fDialogColor);
444
if (pDialog->iTextHeight < pDialog->iMessageHeight) // on centre le texte.
445
y += (pDialog->iMessageHeight - pDialog->iTextHeight) / 2;
446
cairo_set_source_surface (pCairoContext,
447
pDialog->pTextBuffer,
448
x - pDialog->iCurrentTextOffset,
450
cairo_paint (pCairoContext);
452
if (pDialog->iMaxTextWidth != 0 && pDialog->iTextWidth > pDialog->iMaxTextWidth)
454
cairo_set_source_surface (pCairoContext,
455
pDialog->pTextBuffer,
456
x - pDialog->iCurrentTextOffset + pDialog->iTextWidth + 10,
458
cairo_paint (pCairoContext);
459
cairo_restore (pCairoContext);
462
cairo_destroy (pCairoContext);
467
pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDialog));
468
//cd_debug ("redraw");
470
if (pDialog->pDecorator != NULL)
472
cairo_save (pCairoContext);
473
pDialog->pDecorator->render (pCairoContext, pDialog);
474
cairo_restore (pCairoContext);
477
_cairo_dock_draw_inside_dialog (pCairoContext, pDialog, 0.);
479
if (pDialog->container.bUseReflect)
481
cairo_save (pCairoContext);
482
cairo_rectangle (pCairoContext,
484
pDialog->iTopMargin + pDialog->iBubbleHeight,
485
pDialog->iBubbleWidth,
486
pDialog->iBottomMargin);
487
g_print( "pDialog->iBottomMargin:%d\n", pDialog->iBottomMargin);
488
cairo_clip (pCairoContext);
490
cairo_translate (pCairoContext,
492
2* (pDialog->iTopMargin + pDialog->iBubbleHeight));
493
cairo_scale (pCairoContext, 1., -1.);
494
_cairo_dock_draw_inside_dialog (pCairoContext, pDialog, pDialog->container.fRatio);
497
cairo_destroy (pCairoContext);
503
static gboolean on_configure_dialog (GtkWidget* pWidget,
504
GdkEventConfigure* pEvent,
505
CairoDialog *pDialog)
507
//g_print ("%s (%dx%d)\n", __func__, pEvent->width, pEvent->height);
508
if (pEvent->width == CAIRO_DIALOG_MIN_SIZE && pEvent->height == CAIRO_DIALOG_MIN_SIZE && ! pDialog->bNoInput)
511
int iWidth = pDialog->container.iWidth, iHeight = pDialog->container.iHeight;
512
//\____________ On recupere la taille du widget interactif qui a pu avoir change.
513
if (pDialog->pInteractiveWidget != NULL)
515
GtkRequisition requisition;
516
gtk_widget_size_request (pDialog->pInteractiveWidget, &requisition);
517
pDialog->iInteractiveWidth = requisition.width;
518
pDialog->iInteractiveHeight = requisition.height;
519
//g_print (" pInteractiveWidget : %dx%d\n", pDialog->iInteractiveWidth, pDialog->iInteractiveHeight);
521
pDialog->iBubbleWidth = MAX (pDialog->iMessageWidth, MAX (pDialog->iInteractiveWidth, pDialog->iButtonsWidth));
522
pDialog->iBubbleHeight = pDialog->iMessageHeight + pDialog->iInteractiveHeight + pDialog->iButtonsHeight;
523
//g_print (" -> iBubbleWidth: %d , iBubbleHeight : %d\n", pDialog->iBubbleWidth, pDialog->iBubbleHeight);
524
cairo_dock_compute_dialog_sizes (pDialog);
527
if (iWidth != pEvent->width || iHeight != pEvent->height)
529
if ((pEvent->width != CAIRO_DIALOG_MIN_SIZE || pEvent->height != CAIRO_DIALOG_MIN_SIZE) && (pEvent->width < iWidth || pEvent->height < iHeight))
531
//g_print ("non, on a dit %dx%d !\n", pDialog->iBubbleWidth + pDialog->iLeftMargin + pDialog->iRightMargin,
532
// pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iDistanceToDock);
533
gtk_window_resize (GTK_WINDOW (pDialog->container.pWidget),
534
pDialog->iBubbleWidth + pDialog->iLeftMargin + pDialog->iRightMargin,
535
pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iDistanceToDock);
537
pDialog->container.iWidth = pEvent->width;
538
pDialog->container.iHeight = pEvent->height;
540
if (pDialog->pIcon != NULL && (! pDialog->container.bInside || pDialog->bNoInput))
542
CairoContainer *pContainer = cairo_dock_search_container_from_icon (pDialog->pIcon);
543
//g_print ("configure (%d) => place (%s, %s, %x)\n", pDialog->container.bInside, pDialog->pIcon->cName, pDialog->pIcon->cParentDockName, pContainer);
544
cairo_dock_place_dialog (pDialog, pContainer);
547
if (pDialog->bNoInput)
549
if (pDialog->pShapeBitmap != NULL)
550
g_object_unref ((gpointer) pDialog->pShapeBitmap);
551
pDialog->pShapeBitmap = (GdkBitmap*) gdk_pixmap_new (NULL,
555
cairo_t *pCairoContext = gdk_cairo_create (pDialog->pShapeBitmap);
556
cairo_set_source_rgba (pCairoContext, 0.0f, 0.0f, 0.0f, 0.0f);
557
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
558
cairo_paint (pCairoContext);
559
cairo_destroy (pCairoContext);
561
gtk_widget_input_shape_combine_mask (pDialog->container.pWidget,
562
pDialog->pShapeBitmap,
568
/**if (pEvent->x != pDialog->container.iWindowPositionX || pEvent->y != pDialog->container.iWindowPositionY)
570
g_print (" => force move to (%d;%d) %dx%d\n", pDialog->container.iWindowPositionX, pDialog->container.iWindowPositionY, pDialog->container.iWidth, pDialog->container.iHeight);
571
gtk_window_move (GTK_WINDOW (pDialog->container.pWidget),
572
pDialog->container.iWindowPositionX,
573
pDialog->container.iWindowPositionY);
576
gtk_widget_queue_draw (pDialog->container.pWidget); // les widgets internes peuvent avoir changer de taille sans que le dialogue n'en ait change, il faut donc redessiner tout le temps.
582
gboolean on_unmap_dialog (GtkWidget* pWidget,
584
CairoDialog *pDialog)
586
//g_print ("unmap dialog (bAllowMinimize:%d, visible:%d)\n", pDialog->bAllowMinimize, GTK_WIDGET_VISIBLE (pWidget));
587
if (! pDialog->bAllowMinimize)
589
if (pDialog->pUnmapTimer)
591
double fElapsedTime = g_timer_elapsed (pDialog->pUnmapTimer, NULL);
592
//g_print ("fElapsedTime : %fms\n", fElapsedTime);
593
g_timer_destroy (pDialog->pUnmapTimer);
594
pDialog->pUnmapTimer = NULL;
595
if (fElapsedTime < .2)
598
gtk_window_present (GTK_WINDOW (pWidget));
602
pDialog->bAllowMinimize = FALSE;
603
if (pDialog->pUnmapTimer == NULL)
604
pDialog->pUnmapTimer = g_timer_new (); // starts the timer.
606
return TRUE; // stops other handlers from being invoked for the event.
610
static cairo_surface_t *_cairo_dock_load_button_icon (cairo_t *pCairoContext, const gchar *cButtonImage, const gchar *cDefaultButtonImage)
612
//g_print ("%s (%d ; %d)\n", __func__, myDialogs.iDialogButtonWidth, myDialogs.iDialogButtonHeight);
613
cairo_surface_t *pButtonSurface = cairo_dock_create_surface_from_image_simple (cButtonImage,
615
myDialogs.iDialogButtonWidth,
616
myDialogs.iDialogButtonHeight);
618
if (pButtonSurface == NULL)
620
gchar *cIconPath = g_strdup_printf ("%s/%s", CAIRO_DOCK_SHARE_DATA_DIR, cDefaultButtonImage);
621
//g_print (" on charge %s par defaut\n", cIconPath);
622
pButtonSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
624
myDialogs.iDialogButtonWidth,
625
myDialogs.iDialogButtonHeight);
629
return pButtonSurface;
632
#define _load_button_texture(iTexture, pSurface) do {\
634
_cairo_dock_delete_texture (iTexture);\
635
if (pSurface != NULL)\
636
iTexture = cairo_dock_create_texture_from_surface (pSurface);\
638
iTexture = 0; } while (0)
639
void cairo_dock_load_dialog_buttons (CairoContainer *pContainer, gchar *cButtonOkImage, gchar *cButtonCancelImage)
641
//g_print ("%s (%s ; %s)\n", __func__, cButtonOkImage, cButtonCancelImage);
642
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (pContainer);
644
if (s_pButtonOkSurface != NULL)
645
cairo_surface_destroy (s_pButtonOkSurface);
646
s_pButtonOkSurface = _cairo_dock_load_button_icon (pCairoContext, cButtonOkImage, "cairo-dock-ok.svg");
648
if (s_pButtonCancelSurface != NULL)
649
cairo_surface_destroy (s_pButtonCancelSurface);
650
s_pButtonCancelSurface = _cairo_dock_load_button_icon (pCairoContext, cButtonCancelImage, "cairo-dock-cancel.svg");
652
cairo_destroy (pCairoContext);
654
if (0 && g_bUseOpenGL)
656
_load_button_texture (s_iButtonOkTexture, s_pButtonOkSurface);
657
_load_button_texture (s_iButtonCancelTexture, s_pButtonCancelSurface);
660
void cairo_dock_unload_dialog_buttons (void)
662
if (s_pButtonOkSurface != NULL)
664
cairo_surface_destroy (s_pButtonOkSurface);
665
s_pButtonOkSurface = NULL;
667
if (s_pButtonCancelSurface != NULL)
669
cairo_surface_destroy (s_pButtonCancelSurface);
670
s_pButtonCancelSurface = NULL;
672
if (s_iButtonOkTexture != 0)
674
_cairo_dock_delete_texture (s_iButtonOkTexture);
675
s_iButtonOkTexture = 0;
677
if (s_iButtonCancelTexture != 0)
679
_cairo_dock_delete_texture (s_iButtonCancelTexture);
680
s_iButtonCancelTexture = 0;
684
gboolean cairo_dock_dialog_reference (CairoDialog *pDialog)
686
if (pDialog != NULL && pDialog->iRefCount > 0)
688
pDialog->iRefCount ++;
689
return TRUE; // on peut l'utiliser.
695
gboolean cairo_dock_dialog_unreference (CairoDialog *pDialog)
697
//g_print ("%s (%d)\n", __func__, pDialog->iRefCount);
698
if (pDialog != NULL && pDialog->iRefCount > 0)
700
pDialog->iRefCount --;
701
if (pDialog->iRefCount == 0) // devient nul.
703
cairo_dock_free_dialog (pDialog);
704
cairo_dock_replace_all_dialogs ();
708
return FALSE; // il n'est pas mort.
714
void cairo_dock_free_dialog (CairoDialog *pDialog)
719
if (pDialog->iSidTimer > 0)
721
g_source_remove (pDialog->iSidTimer);
722
pDialog->iSidTimer = 0;
724
if (pDialog->iSidAnimateIcon > 0)
726
g_source_remove (pDialog->iSidAnimateIcon);
727
pDialog->iSidAnimateIcon = 0;
729
if (pDialog->iSidAnimateText > 0)
731
g_source_remove (pDialog->iSidAnimateText);
732
pDialog->iSidAnimateText = 0;
736
s_pDialogList = g_slist_remove (s_pDialogList, pDialog);
738
if (pDialog->pTextBuffer != NULL)
739
cairo_surface_destroy (pDialog->pTextBuffer);
740
if (pDialog->pIconBuffer != NULL)
741
cairo_surface_destroy (pDialog->pIconBuffer);
742
if (pDialog->iIconTexture != 0)
743
_cairo_dock_delete_texture (pDialog->iIconTexture);
744
if (pDialog->iTextTexture != 0)
745
_cairo_dock_delete_texture (pDialog->iTextTexture);
747
if (pDialog->pButtons != NULL)
749
cairo_surface_t *pSurface;
752
for (i = 0; i < pDialog->iNbButtons; i++)
754
pSurface = pDialog->pButtons[i].pSurface;
755
if (pSurface != NULL && pSurface != s_pButtonOkSurface && pSurface != s_pButtonCancelSurface)
756
cairo_surface_destroy (pSurface);
757
iTexture = pDialog->pButtons[i].iTexture;
758
if (iTexture != 0 && iTexture != s_iButtonOkTexture && iTexture != s_iButtonCancelTexture)
759
_cairo_dock_delete_texture (iTexture);
761
g_free (pDialog->pButtons);
764
gtk_widget_destroy (pDialog->container.pWidget); // detruit aussi le widget interactif.
766
if (pDialog->pUnmapTimer != NULL)
767
g_timer_destroy (pDialog->pUnmapTimer);
769
if (pDialog->pShapeBitmap != NULL)
770
g_object_unref ((gpointer) pDialog->pShapeBitmap);
772
if (pDialog->pUserData != NULL && pDialog->pFreeUserDataFunc != NULL)
773
pDialog->pFreeUserDataFunc (pDialog->pUserData);
775
if (pDialog->pIcon && pDialog->pIcon->cParentDockName != NULL)
776
cairo_dock_dialog_window_destroyed ();
780
gboolean cairo_dock_remove_dialog_if_any_full (Icon *icon, gboolean bAll)
782
g_return_val_if_fail (icon != NULL, FALSE);
783
cd_debug ("%s (%s)", __func__, (icon?icon->cName : "nobody"));
784
CairoDialog *pDialog;
785
GSList *dl, *next_dl;
786
gboolean bDialogRemoved = FALSE;
788
if (s_pDialogList == NULL)
794
next_dl = dl->next; // si on enleve l'element courant, on perd 'dl'.
796
if (pDialog->pIcon == icon && (bAll || pDialog->action_on_answer == NULL))
798
cairo_dock_dialog_unreference (pDialog);
799
bDialogRemoved = TRUE;
802
} while (dl != NULL);
804
return bDialogRemoved;
807
static GtkWidget *_cairo_dock_make_entry_for_dialog (const gchar *cTextForEntry)
809
GtkWidget *pWidget = gtk_entry_new ();
810
gtk_entry_set_has_frame (GTK_ENTRY (pWidget), FALSE);
811
gtk_widget_set (pWidget, "width-request", CAIRO_DIALOG_MIN_ENTRY_WIDTH, NULL);
812
if (cTextForEntry != NULL)
813
gtk_entry_set_text (GTK_ENTRY (pWidget), cTextForEntry);
816
static GtkWidget *_cairo_dock_make_hscale_for_dialog (double fValueForHScale, double fMaxValueForHScale)
818
GtkWidget *pWidget = gtk_hscale_new_with_range (0, fMaxValueForHScale, fMaxValueForHScale / 100.);
819
gtk_scale_set_digits (GTK_SCALE (pWidget), 2);
820
gtk_range_set_value (GTK_RANGE (pWidget), fValueForHScale);
822
gtk_widget_set (pWidget, "width-request", CAIRO_DIALOG_MIN_SCALE_WIDTH, NULL);
826
GtkWidget *cairo_dock_add_dialog_internal_box (CairoDialog *pDialog, int iWidth, int iHeight, gboolean bCanResize)
828
GtkWidget *pBox = gtk_hbox_new (0, FALSE);
829
if (iWidth != 0 && iHeight != 0)
830
gtk_widget_set (pBox, "height-request", iHeight, "width-request", iWidth, NULL);
831
else if (iWidth != 0)
832
gtk_widget_set (pBox, "width-request", iWidth, NULL);
833
else if (iHeight != 0)
834
gtk_widget_set (pBox, "height-request", iHeight, NULL);
835
gtk_box_pack_start (GTK_BOX (pDialog->pWidgetLayout),
843
static CairoDialog *_cairo_dock_create_new_dialog (gboolean bInteractive)
845
//\________________ On cree un dialogue qu'on insere immediatement dans la liste.
846
CairoDialog *pDialog = g_new0 (CairoDialog, 1);
847
pDialog->container.iType = CAIRO_DOCK_TYPE_DIALOG;
848
pDialog->iRefCount = 1;
849
pDialog->container.fRatio = 1.;
850
pDialog->container.iAnimationDeltaT = mySystem.iCairoAnimationDeltaT;
851
s_pDialogList = g_slist_prepend (s_pDialogList, pDialog);
853
//\________________ On construit la fenetre du dialogue.
854
//GtkWidget* pWindow = gtk_window_new (bInteractiveWindow ? GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP); // les popus ne prennent pas le focus. En fait, ils ne sont meme pas controles par le WM.
855
GtkWidget* pWindow = cairo_dock_create_container_window_no_opengl ();
857
pDialog->container.pWidget = pWindow;
859
//gtk_window_set_keep_above (GTK_WINDOW (pWindow), g_bKeepAbove || myAccessibility.bPopUp);
860
gtk_window_set_gravity (GTK_WINDOW (pWindow), GDK_GRAVITY_STATIC);
862
gtk_window_set_title (GTK_WINDOW (pWindow), "cairo-dock-dialog");
864
gtk_window_set_type_hint (GTK_WINDOW (pDialog->container.pWidget), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN); // pour ne pas prendre le focus.
866
gtk_widget_add_events (pWindow, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
867
gtk_window_resize (GTK_WINDOW (pWindow), CAIRO_DIALOG_MIN_SIZE, CAIRO_DIALOG_MIN_SIZE);
868
gtk_window_set_keep_above (GTK_WINDOW (pWindow), TRUE);
869
gtk_widget_show_all (pWindow);
874
static cairo_surface_t *_cairo_dock_create_dialog_text_surface (const gchar *cText, CairoDockLabelDescription *pTextDescription, cairo_t *pSourceContext, int *iTextWidth, int *iTextHeight)
878
//g_print ("%x;%x\n", pTextDescription, pSourceContext);
879
cairo_surface_t *pTextBuffer = cairo_dock_create_surface_from_text_full (cText,
881
(pTextDescription ? pTextDescription : &myDialogs.dialogTextDescription),
891
static cairo_surface_t *_cairo_dock_create_dialog_icon_surface (const gchar *cImageFilePath, int iNbFrames, cairo_t *pSourceContext, Icon *pIcon, CairoContainer *pContainer, int iDesiredSize, int *iIconSize)
893
if (cImageFilePath == NULL)
895
if (iDesiredSize == 0)
896
iDesiredSize = myDialogs.iDialogIconSize;
897
cairo_surface_t *pIconBuffer = NULL;
898
if (strcmp (cImageFilePath, "same icon") == 0 && pIcon != NULL && pContainer != NULL)
900
if (pContainer == NULL)
901
pContainer = cairo_dock_search_container_from_icon (pIcon);
903
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
904
pIconBuffer = cairo_dock_duplicate_surface (pIcon->pIconBuffer,
907
iDesiredSize, iDesiredSize);
911
double fImageWidth = iNbFrames * iDesiredSize, fImageHeight = iDesiredSize;
912
pIconBuffer = cairo_dock_create_surface_from_image_simple (cImageFilePath,
917
if (pIconBuffer != NULL)
918
*iIconSize = iDesiredSize;
922
static gboolean _cairo_dock_animate_dialog_icon (CairoDialog *pDialog)
924
pDialog->iCurrentFrame ++;
925
if (pDialog->iCurrentFrame == pDialog->iNbFrames)
926
pDialog->iCurrentFrame = 0;
927
cairo_dock_damage_icon_dialog (pDialog);
930
static gboolean _cairo_dock_animate_dialog_text (CairoDialog *pDialog)
932
if (pDialog->iTextWidth <= pDialog->iMaxTextWidth)
934
pDialog->iCurrentTextOffset += 3;
935
if (pDialog->iCurrentTextOffset >= pDialog->iTextWidth)
936
pDialog->iCurrentTextOffset -= pDialog->iTextWidth;
937
cairo_dock_damage_text_dialog (pDialog);
940
static gboolean _cairo_dock_dialog_auto_delete (CairoDialog *pDialog)
944
pDialog->iSidTimer = 0;
945
cairo_dock_dialog_unreference (pDialog); // on pourrait eventuellement faire un fondu avant.
949
CairoDialog *cairo_dock_build_dialog (CairoDialogAttribute *pAttribute, Icon *pIcon, CairoContainer *pContainer)
951
g_return_val_if_fail (pAttribute != NULL, NULL);
952
if (cairo_dock_search_window_on_our_way (g_pMainDock, FALSE, TRUE) != NULL)
954
cd_debug ("skip dialog since a fullscreen window would mask it");
957
cd_debug ("%s (%s, %s, %x, %x, %x (%x;%x))", __func__, pAttribute->cText, pAttribute->cImageFilePath, pAttribute->pInteractiveWidget, pAttribute->pActionFunc, pAttribute->pTextDescription, pIcon, pContainer);
959
//\________________ On cree un nouveau dialogue.
960
CairoDialog *pDialog = _cairo_dock_create_new_dialog (pAttribute->pInteractiveWidget || pAttribute->pActionFunc);
961
///if (pContainer != NULL)
962
/// gtk_window_set_transient_for (GTK_WINDOW (pDialog->container.pWidget), GTK_WINDOW (pContainer->pWidget));
963
pDialog->pIcon = pIcon;
964
cairo_t *pSourceContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDialog));
966
//\________________ On cree la surface du message.
967
if (pAttribute->cText != NULL)
969
pDialog->iMaxTextWidth = pAttribute->iMaxTextWidth;
970
pDialog->pTextBuffer = _cairo_dock_create_dialog_text_surface (pAttribute->cText,
971
pAttribute->pTextDescription, pSourceContext,
972
&pDialog->iTextWidth, &pDialog->iTextHeight);
973
///pDialog->iTextTexture = cairo_dock_create_texture_from_surface (pDialog->pTextBuffer);
974
if (pDialog->iMaxTextWidth > 0 && pDialog->pTextBuffer != NULL && pDialog->iTextWidth > pDialog->iMaxTextWidth)
976
pDialog->iSidAnimateText = g_timeout_add (200, (GSourceFunc) _cairo_dock_animate_dialog_text, (gpointer) pDialog); // multiple du timeout de l'icone animee.
980
//\________________ On cree la surface de l'icone a afficher sur le cote.
981
if (pAttribute->cImageFilePath != NULL)
983
pDialog->iNbFrames = (pAttribute->iNbFrames > 0 ? pAttribute->iNbFrames : 1);
984
pDialog->pIconBuffer = _cairo_dock_create_dialog_icon_surface (pAttribute->cImageFilePath, pDialog->iNbFrames, pSourceContext, pIcon, pContainer, pAttribute->iIconSize, &pDialog->iIconSize);
985
///pDialog->iIconTexture = cairo_dock_create_texture_from_surface (pDialog->pIconBuffer);
986
if (pDialog->pIconBuffer != NULL && pDialog->iNbFrames > 1)
988
pDialog->iSidAnimateIcon = g_timeout_add (100, (GSourceFunc) _cairo_dock_animate_dialog_icon, (gpointer) pDialog);
992
//\________________ On prend en compte le widget interactif.
993
if (pAttribute->pInteractiveWidget != NULL)
995
pDialog->pInteractiveWidget = pAttribute->pInteractiveWidget;
997
GtkRequisition requisition;
998
gtk_widget_size_request (pAttribute->pInteractiveWidget, &requisition);
999
pDialog->iInteractiveWidth = requisition.width;
1000
pDialog->iInteractiveHeight = requisition.height;
1003
//\________________ On prend en compte les boutons.
1004
pDialog->action_on_answer = pAttribute->pActionFunc;
1005
pDialog->pUserData = pAttribute->pUserData;
1006
pDialog->pFreeUserDataFunc = pAttribute->pFreeDataFunc;
1007
if (pAttribute->cButtonsImage != NULL && pAttribute->pActionFunc != NULL)
1009
if (s_pButtonOkSurface == NULL || s_pButtonCancelSurface == NULL)
1010
cairo_dock_load_dialog_buttons (CAIRO_CONTAINER (pDialog), myDialogs.cButtonOkImage, myDialogs.cButtonCancelImage);
1013
for (i = 0; pAttribute->cButtonsImage[i] != NULL; i++);
1014
pDialog->iNbButtons = i;
1016
pDialog->pButtons = g_new0 (CairoDialogButton, pDialog->iNbButtons);
1017
gchar *cButtonImage;
1018
for (i = 0; i < pDialog->iNbButtons; i++)
1020
cButtonImage = pAttribute->cButtonsImage[i];
1021
if (strcmp (cButtonImage, "ok") == 0)
1023
pDialog->pButtons[i].pSurface = s_pButtonOkSurface;
1024
pDialog->pButtons[i].iTexture = s_iButtonOkTexture;
1026
else if (strcmp (cButtonImage, "cancel") == 0)
1028
pDialog->pButtons[i].pSurface = s_pButtonCancelSurface;
1029
pDialog->pButtons[i].iTexture = s_iButtonCancelTexture;
1034
if (*cButtonImage != '/')
1035
cButtonPath = cairo_dock_search_icon_s_path (cButtonImage);
1037
cButtonPath = cButtonImage;
1038
pDialog->pButtons[i].pSurface = cairo_dock_create_surface_from_image_simple (cButtonPath,
1040
myDialogs.iDialogButtonWidth,
1041
myDialogs.iDialogButtonHeight);
1042
if (cButtonPath != cButtonImage)
1043
g_free (cButtonPath);
1044
///pDialog->pButtons[i].iTexture = cairo_dock_create_texture_from_surface (pDialog->pButtons[i].pSurface);
1050
pDialog->bNoInput = pAttribute->bNoInput;
1053
//\________________ On lui affecte un decorateur.
1054
cairo_dock_set_dialog_decorator_by_name (pDialog, (pAttribute->cDecoratorName ? pAttribute->cDecoratorName : myDialogs.cDecoratorName));
1055
if (pDialog->pDecorator != NULL)
1056
pDialog->pDecorator->set_size (pDialog);
1058
//\________________ Maintenant qu'on connait tout, on calcule les tailles des divers elements.
1059
cairo_dock_compute_dialog_sizes (pDialog);
1062
cairo_dock_place_dialog (pDialog, pContainer); // renseigne aussi bDirectionUp, bIsHorizontal, et iHeight.
1065
//\________________ On reserve l'espace pour les decorations.
1066
GtkWidget *pMainHBox = gtk_hbox_new (0, FALSE);
1067
gtk_container_add (GTK_CONTAINER (pDialog->container.pWidget), pMainHBox);
1068
pDialog->pLeftPaddingBox = gtk_vbox_new (0, FALSE);
1069
gtk_widget_set (pDialog->pLeftPaddingBox, "width-request", pDialog->iLeftMargin, NULL);
1070
gtk_box_pack_start (GTK_BOX (pMainHBox),
1071
pDialog->pLeftPaddingBox,
1076
pDialog->pWidgetLayout = gtk_vbox_new (0, FALSE);
1077
gtk_box_pack_start (GTK_BOX (pMainHBox),
1078
pDialog->pWidgetLayout,
1083
pDialog->pRightPaddingBox = gtk_vbox_new (0, FALSE);
1084
gtk_widget_set (pDialog->pRightPaddingBox, "width-request", pDialog->iRightMargin, NULL);
1085
gtk_box_pack_start (GTK_BOX (pMainHBox),
1086
pDialog->pRightPaddingBox,
1091
//\________________ On reserve l'espace pour les elements.
1092
if (pDialog->container.bDirectionUp)
1093
pDialog->pTopWidget = cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iTopMargin, TRUE);
1095
pDialog->pTipWidget = cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iMinBottomGap + pDialog->iBottomMargin, TRUE);
1096
if (pDialog->iMessageWidth != 0 && pDialog->iMessageHeight != 0)
1098
pDialog->pMessageWidget = cairo_dock_add_dialog_internal_box (pDialog, pDialog->iMessageWidth, pDialog->iMessageHeight, FALSE);
1100
if (pDialog->pInteractiveWidget != NULL)
1102
cd_debug (" ref = %d", pAttribute->pInteractiveWidget->object.parent_instance.ref_count);
1103
gtk_box_pack_start (GTK_BOX (pDialog->pWidgetLayout),
1104
pDialog->pInteractiveWidget,
1108
cd_debug (" pack -> ref = %d", pAttribute->pInteractiveWidget->object.parent_instance.ref_count);
1109
g_print ("grab focus\n");
1110
gtk_window_present (GTK_WINDOW (pDialog->container.pWidget));
1111
gtk_widget_grab_focus (pDialog->pInteractiveWidget);
1113
if (pDialog->pButtons != NULL)
1115
pDialog->pButtonsWidget = cairo_dock_add_dialog_internal_box (pDialog, pDialog->iButtonsWidth, pDialog->iButtonsHeight, FALSE);
1117
if (pDialog->container.bDirectionUp)
1118
pDialog->pTipWidget = cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iMinBottomGap + pDialog->iBottomMargin, TRUE);
1120
pDialog->pTopWidget = cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iTopMargin, TRUE);
1121
gtk_widget_show_all (pDialog->container.pWidget);
1123
//\________________ On connecte les signaux utiles.
1124
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
1126
G_CALLBACK (on_expose_dialog),
1128
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
1130
G_CALLBACK (on_configure_dialog),
1132
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
1133
"button-press-event",
1134
G_CALLBACK (on_button_press_dialog),
1136
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
1137
"button-release-event",
1138
G_CALLBACK (on_button_press_dialog),
1140
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
1142
G_CALLBACK (on_key_press_dialog),
1144
if (pIcon != NULL) // on inhibe le deplacement du dialogue lorsque l'utilisateur est dedans.
1146
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
1147
"enter-notify-event",
1148
G_CALLBACK (on_enter_dialog),
1150
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
1151
"leave-notify-event",
1152
G_CALLBACK (on_leave_dialog),
1155
g_signal_connect (G_OBJECT (pDialog->container.pWidget),
1157
G_CALLBACK (on_unmap_dialog),
1160
cairo_destroy (pSourceContext);
1162
if (pAttribute->iTimeLength != 0)
1163
pDialog->iSidTimer = g_timeout_add (pAttribute->iTimeLength, (GSourceFunc) _cairo_dock_dialog_auto_delete, (gpointer) pDialog);
1165
if (pIcon && pIcon->cParentDockName != NULL)
1166
cairo_dock_dialog_window_created ();
1171
void cairo_dock_dialog_calculate_aimed_point (Icon *pIcon, CairoContainer *pContainer, int *iX, int *iY, gboolean *bRight, CairoDockTypeHorizontality *bIsHorizontal, gboolean *bDirectionUp, double fAlign)
1173
g_return_if_fail (pIcon != NULL && pContainer != NULL);
1174
//g_print ("%s (%.2f, %.2f)\n", __func__, pIcon->fXAtRest, pIcon->fDrawX);
1175
if (CAIRO_DOCK_IS_DOCK (pContainer))
1177
CairoDock *pDock = CAIRO_DOCK (pContainer);
1178
if (pDock->iRefCount > 0 && ! GTK_WIDGET_VISIBLE (pDock->container.pWidget)) // sous-dock invisible. // pDock->bAtBottom
1180
CairoDock *pParentDock = NULL;
1181
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
1182
cairo_dock_dialog_calculate_aimed_point (pPointingIcon, CAIRO_CONTAINER (pParentDock), iX, iY, bRight, bIsHorizontal, bDirectionUp, fAlign);
1184
else/* if (pDock->iRefCount == 0)*/ // un dock principal au repos. // && pDock->bAtBottom
1186
*bIsHorizontal = (pDock->container.bIsHorizontal == CAIRO_DOCK_HORIZONTAL);
1188
if (pDock->iInputState == CAIRO_DOCK_INPUT_ACTIVE)
1190
else if (cairo_dock_is_hidden (pDock))
1191
dy = pDock->container.iHeight - MIN (myAccessibility.iVisibleZoneHeight, pDock->iMaxDockHeight);
1193
dy = pDock->container.iHeight - pDock->iMinDockHeight;
1194
if (pDock->container.bIsHorizontal)
1196
*bRight = (pIcon->fXAtRest > pDock->fFlatDockWidth / 2);
1197
*bDirectionUp = pDock->container.bDirectionUp;
1199
//g_print ("y = %d + %d\n", pDock->container.iWindowPositionY, dy);
1202
*iY = pDock->container.iWindowPositionY + dy;
1204
*iY = pDock->container.iWindowPositionY + pDock->container.iHeight - dy;
1208
*bRight = (pDock->container.iWindowPositionY < g_iScreenWidth[CAIRO_DOCK_HORIZONTAL] / 2);
1209
*bDirectionUp = (pIcon->fXAtRest > pDock->fFlatDockWidth / 2);
1210
*iY = (! (*bRight) ? pDock->container.iWindowPositionY : pDock->container.iWindowPositionY + pDock->container.iHeight) + (pDock->container.bDirectionUp ? dy : -dy);
1213
if (cairo_dock_is_hidden (pDock))
1215
*iX = pDock->container.iWindowPositionX +
1216
pDock->iMaxDockWidth/2 -
1217
MIN (myAccessibility.iVisibleZoneWidth, pDock->iMaxDockWidth)/2 +
1218
(pIcon->fXAtRest + pIcon->fWidth * (.5 + (*bRight ? .2 : -.2) * 2*(.5-fAlign))) / pDock->fFlatDockWidth * MIN (myAccessibility.iVisibleZoneWidth, pDock->iMaxDockWidth);
1219
cd_debug ("placement sur un dock cache -> %d", *iX);
1223
*iX = pDock->container.iWindowPositionX +
1224
pIcon->fDrawX + pIcon->fWidth * pIcon->fScale * (.5 + (*bRight ? .2 : -.2) * 2*(.5-fAlign));
1227
/*else // dock actif.
1229
*bIsHorizontal = (pDock->container.bIsHorizontal == CAIRO_DOCK_HORIZONTAL);
1230
if (pDock->container.bIsHorizontal)
1232
*bRight = (pIcon->fXAtRest > pDock->fFlatDockWidth / 2);
1233
*bDirectionUp = (pDock->container.iWindowPositionY > g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] / 2);
1234
*iY = (*bDirectionUp ? pDock->container.iWindowPositionY : pDock->container.iWindowPositionY + pDock->container.iHeight);
1238
*bRight = (pDock->container.iWindowPositionY < g_iScreenWidth[CAIRO_DOCK_HORIZONTAL] / 2);
1239
*bDirectionUp = (pIcon->fXAtRest > pDock->fFlatDockWidth / 2);
1240
*iY = (! (*bRight) ? pDock->container.iWindowPositionY : pDock->container.iWindowPositionY + pDock->container.iHeight);
1242
*iX = pDock->container.iWindowPositionX + pIcon->fDrawX + pIcon->fWidth * pIcon->fScale * pIcon->fWidthFactor / 2 + pIcon->fWidth * (*bRight ? .2 : - .2);
1245
else if (CAIRO_DOCK_IS_DESKLET (pContainer))
1247
CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
1248
*bDirectionUp = (pDesklet->container.iWindowPositionY > g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] / 2);
1249
*bIsHorizontal = (pDesklet->container.iWindowPositionX > 50 && pDesklet->container.iWindowPositionX + pDesklet->container.iHeight < g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - 50);
1253
*bRight = (pDesklet->container.iWindowPositionX > g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] / 2);
1254
*iX = pDesklet->container.iWindowPositionX + pDesklet->container.iWidth * (*bRight ? .7 : .3);
1255
*iY = (*bDirectionUp ? pDesklet->container.iWindowPositionY : pDesklet->container.iWindowPositionY + pDesklet->container.iHeight);
1259
*bRight = (pDesklet->container.iWindowPositionX < g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] / 2);
1260
*iY = pDesklet->container.iWindowPositionX + pDesklet->container.iWidth * (*bRight ? 1 : 0);
1261
*iX =pDesklet->container.iWindowPositionY + pDesklet->container.iHeight / 2;
1267
static void _cairo_dock_dialog_find_optimal_placement (CairoDialog *pDialog)
1269
//g_print ("%s (Ybulle:%d; width:%d)\n", __func__, pDialog->container.iWindowPositionY, pDialog->container.iWidth);
1270
g_return_if_fail (pDialog->container.iWindowPositionY > 0);
1273
CairoDialog *pDialogOnOurWay;
1275
double fXLeft = 0, fXRight = g_iXScreenWidth[pDialog->container.bIsHorizontal];
1276
if (pDialog->bRight)
1279
fXRight = MAX (g_iXScreenWidth[pDialog->container.bIsHorizontal], pDialog->iAimedX + pDialog->iMinFrameWidth + pDialog->iRightMargin + 1); // 2*CAIRO_DIALOG_TIP_MARGIN + CAIRO_DIALOG_TIP_BASE
1283
fXLeft = MIN (0, pDialog->iAimedX - (pDialog->iMinFrameWidth + pDialog->iLeftMargin + 1)); // 2*CAIRO_DIALOG_TIP_MARGIN + CAIRO_DIALOG_TIP_BASE
1286
gboolean bCollision = FALSE;
1287
double fNextYStep = (pDialog->container.bDirectionUp ? -1e4 : 1e4);
1290
for (ic = s_pDialogList; ic != NULL; ic = ic->next)
1292
pDialogOnOurWay = ic->data;
1293
if (pDialogOnOurWay == NULL)
1295
if (pDialogOnOurWay != pDialog)
1297
if (GTK_WIDGET_VISIBLE (pDialogOnOurWay->container.pWidget) && pDialogOnOurWay->pIcon != NULL)
1299
iYInf = (pDialog->container.bDirectionUp ? pDialogOnOurWay->container.iWindowPositionY : pDialogOnOurWay->container.iWindowPositionY + pDialogOnOurWay->container.iHeight - (pDialogOnOurWay->iBubbleHeight + 0));
1300
iYSup = (pDialog->container.bDirectionUp ? pDialogOnOurWay->container.iWindowPositionY + pDialogOnOurWay->iBubbleHeight + 0 : pDialogOnOurWay->container.iWindowPositionY + pDialogOnOurWay->container.iHeight);
1301
if (iYInf < pDialog->container.iWindowPositionY + pDialog->iBubbleHeight + 0 && iYSup > pDialog->container.iWindowPositionY)
1303
//g_print ("pDialogOnOurWay : %d - %d ; pDialog : %d - %d\n", iYInf, iYSup, pDialog->container.iWindowPositionY, pDialog->container.iWindowPositionY + (pDialog->iBubbleHeight + 2 * myBackground.iDockLineWidth));
1304
if (pDialogOnOurWay->iAimedX < pDialog->iAimedX)
1305
fXLeft = MAX (fXLeft, pDialogOnOurWay->container.iWindowPositionX + pDialogOnOurWay->container.iWidth);
1307
fXRight = MIN (fXRight, pDialogOnOurWay->container.iWindowPositionX);
1309
fNextYStep = (pDialog->container.bDirectionUp ? MAX (fNextYStep, iYInf) : MIN (fNextYStep, iYSup));
1314
//g_print (" -> [%.2f ; %.2f]\n", fXLeft, fXRight);
1316
if ((fXRight - fXLeft > pDialog->container.iWidth) && (
1317
(pDialog->bRight && fXLeft + pDialog->iLeftMargin < pDialog->iAimedX && fXRight > pDialog->iAimedX + pDialog->iMinFrameWidth + pDialog->iRightMargin)
1319
(! pDialog->bRight && fXLeft < pDialog->iAimedX - pDialog->iMinFrameWidth - pDialog->iLeftMargin && fXRight > pDialog->iAimedX + pDialog->iRightMargin)
1322
if (pDialog->bRight)
1323
pDialog->container.iWindowPositionX = MIN (pDialog->iAimedX - pDialog->fAlign * pDialog->iBubbleWidth - pDialog->iLeftMargin, fXRight - pDialog->container.iWidth);
1325
pDialog->container.iWindowPositionX = MAX (pDialog->iAimedX - pDialog->iRightMargin - pDialog->container.iWidth + pDialog->fAlign * pDialog->iBubbleWidth, fXLeft); /// pDialog->iBubbleWidth (?)
1329
//g_print (" * Aim : (%d ; %d) ; Width : %d\n", pDialog->iAimedX, pDialog->iAimedY, pDialog->container.iWidth);
1330
pDialog->container.iWindowPositionY = fNextYStep - (pDialog->container.bDirectionUp ? pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin : 0);
1331
_cairo_dock_dialog_find_optimal_placement (pDialog);
1335
void cairo_dock_place_dialog (CairoDialog *pDialog, CairoContainer *pContainer)
1337
//g_print ("%s (%x;%d)\n", __func__, pDialog->pIcon, pContainer);
1338
int iPrevPositionX = pDialog->container.iWindowPositionX, iPrevPositionY = pDialog->container.iWindowPositionY;
1339
if (pContainer != NULL && pDialog->pIcon != NULL)
1341
cairo_dock_dialog_calculate_aimed_point (pDialog->pIcon, pContainer, &pDialog->iAimedX, &pDialog->iAimedY, &pDialog->bRight, &pDialog->container.bIsHorizontal, &pDialog->container.bDirectionUp, pDialog->fAlign);
1342
//g_print (" Aim (%d;%d) / %d,%d,%d\n", pDialog->iAimedX, pDialog->iAimedY, pDialog->container.bIsHorizontal, pDialog->container.bDirectionUp, pDialog->container.bInside);
1344
if (pDialog->container.bIsHorizontal)
1346
if (! pDialog->container.bInside)
1348
pDialog->container.iWindowPositionY = (pDialog->container.bDirectionUp ? pDialog->iAimedY - (pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iMinBottomGap) : pDialog->iAimedY + pDialog->iMinBottomGap); // on place la bulle d'abord sans prendre en compte la pointe.
1349
_cairo_dock_dialog_find_optimal_placement (pDialog);
1351
else if (! pDialog->container.bDirectionUp)
1352
pDialog->container.iWindowPositionY += pDialog->iDistanceToDock;
1356
int tmp = pDialog->iAimedX;
1357
pDialog->iAimedX = pDialog->iAimedY;
1358
pDialog->iAimedY = tmp;
1359
if (! pDialog->container.bInside)
1361
pDialog->container.iWindowPositionX = (pDialog->bRight ? pDialog->iAimedX - pDialog->fAlign * pDialog->iBubbleWidth : pDialog->iAimedX - pDialog->container.iWidth + pDialog->fAlign * pDialog->iBubbleWidth);
1362
pDialog->container.iWindowPositionY = (pDialog->container.bDirectionUp ? pDialog->iAimedY - (pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iMinBottomGap) : pDialog->iAimedY + pDialog->iMinBottomGap); // on place la bulle (et non pas la fenetre) sans faire d'optimisation.
1365
//g_print (" => position : (%d;%d)\n", pDialog->container.iWindowPositionX, pDialog->container.iWindowPositionY);
1366
int iOldDistance = pDialog->iDistanceToDock;
1367
pDialog->iDistanceToDock = (pDialog->container.bDirectionUp ? pDialog->iAimedY - pDialog->container.iWindowPositionY - (pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin) : pDialog->container.iWindowPositionY - pDialog->iAimedY);
1368
if (! pDialog->container.bDirectionUp) // iPositionY est encore la position du coin haut gauche de la bulle et non de la fenetre.
1369
pDialog->container.iWindowPositionY = pDialog->iAimedY;
1371
if (pDialog->iDistanceToDock != iOldDistance)
1373
//g_print (" On change la taille de la pointe a : %d pixels ( -> %d)\n", pDialog->iDistanceToDock, pDialog->iMessageHeight + pDialog->iInteractiveHeight +pDialog->iButtonsHeight + pDialog->iDistanceToDock);
1374
if (pDialog->pTipWidget)
1375
gtk_widget_set (pDialog->pTipWidget, "height-request", MAX (0, pDialog->iDistanceToDock + pDialog->iBottomMargin), NULL);
1376
//g_print ("pTipWidget set\n");
1378
if ((iOldDistance == 0) || (pDialog->iDistanceToDock < iOldDistance))
1380
//g_print (" cela reduit la fenetre a %dx%d\n", pDialog->iBubbleWidth + pDialog->iLeftMargin + pDialog->iRightMargin, pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iDistanceToDock);
1381
gtk_window_resize (GTK_WINDOW (pDialog->container.pWidget),
1382
pDialog->iBubbleWidth + pDialog->iLeftMargin + pDialog->iRightMargin,
1383
pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iDistanceToDock);
1387
else // au milieu de l'ecran courant.
1389
pDialog->container.bDirectionUp = TRUE;
1390
pDialog->container.iWindowPositionX = (g_pMainDock ? g_pMainDock->iScreenOffsetX : 0) + (g_iScreenWidth [CAIRO_DOCK_HORIZONTAL] - pDialog->container.iWidth) / 2;
1391
pDialog->container.iWindowPositionY = (g_pMainDock ? g_pMainDock->iScreenOffsetY : 0) + (g_iScreenHeight[CAIRO_DOCK_HORIZONTAL] - pDialog->container.iHeight) / 2;
1392
pDialog->container.iHeight = pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin;
1393
//g_print (" au milieu de l'ecran (%d;%d) %dx%d\n", pDialog->container.iWindowPositionX, pDialog->container.iWindowPositionY, pDialog->container.iWidth, pDialog->container.iHeight);
1395
gtk_window_resize (GTK_WINDOW (pDialog->container.pWidget),
1396
pDialog->iBubbleWidth + pDialog->iLeftMargin + pDialog->iRightMargin,
1397
pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin);
1400
///if (iPrevPositionX != pDialog->container.iWindowPositionX || iPrevPositionY != pDialog->container.iWindowPositionY)
1402
//g_print (" => move to (%d;%d) %dx%d\n", pDialog->container.iWindowPositionX, pDialog->container.iWindowPositionY, pDialog->container.iWidth, pDialog->container.iHeight);
1403
gtk_window_move (GTK_WINDOW (pDialog->container.pWidget),
1404
pDialog->container.iWindowPositionX,
1405
pDialog->container.iWindowPositionY);
1409
void cairo_dock_compute_dialog_sizes (CairoDialog *pDialog)
1411
pDialog->iMessageWidth = pDialog->iIconSize + _drawn_text_width (pDialog) + (pDialog->iTextWidth != 0 ? 2 : 0) * CAIRO_DIALOG_TEXT_MARGIN; // icone + marge + texte + marge.
1412
pDialog->iMessageHeight = MAX (pDialog->iIconSize, pDialog->iTextHeight) + (pDialog->pInteractiveWidget != NULL ? CAIRO_DIALOG_VGAP : 0); // (icone/texte + marge) + widget + (marge + boutons) + pointe.
1414
if (pDialog->pButtons != NULL)
1416
pDialog->iButtonsWidth = pDialog->iNbButtons * myDialogs.iDialogButtonWidth + (pDialog->iNbButtons - 1) * CAIRO_DIALOG_BUTTON_GAP + 2 * CAIRO_DIALOG_TEXT_MARGIN; // marge + bouton1 + ecart + bouton2 + marge.
1417
pDialog->iButtonsHeight = CAIRO_DIALOG_VGAP + myDialogs.iDialogButtonHeight; // il y'a toujours quelque chose au-dessus (texte et/out widget)
1420
pDialog->iBubbleWidth = MAX (pDialog->iInteractiveWidth, MAX (pDialog->iButtonsWidth, MAX (pDialog->iMessageWidth, pDialog->iMinFrameWidth)));
1421
pDialog->iBubbleHeight = pDialog->iMessageHeight + pDialog->iInteractiveHeight + pDialog->iButtonsHeight;
1422
if (pDialog->iBubbleWidth == 0) // precaution.
1423
pDialog->iBubbleWidth = 20;
1424
if (pDialog->iBubbleHeight == 0)
1425
pDialog->iBubbleHeight = 20;
1427
pDialog->container.iWidth = pDialog->iBubbleWidth + pDialog->iLeftMargin + pDialog->iRightMargin;
1428
pDialog->container.iHeight = pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iMinBottomGap; // resultat temporaire, sans la pointe.
1433
void cairo_dock_replace_all_dialogs (void)
1435
//g_print ("%s ()\n", __func__);
1437
CairoDialog *pDialog;
1438
CairoContainer *pContainer;
1441
if (s_pDialogList == NULL)
1444
for (ic = s_pDialogList; ic != NULL; ic = ic->next)
1448
pIcon = pDialog->pIcon;
1449
if (pIcon != NULL && GTK_WIDGET_VISIBLE (pDialog->container.pWidget)) // on ne replace pas les dialogues en cours de destruction ou caches.
1451
pContainer = cairo_dock_search_container_from_icon (pIcon);
1452
//if (CAIRO_DOCK_IS_DOCK (pContainer))
1454
int iPositionX = pDialog->container.iWindowPositionX;
1455
int iPositionY = pDialog->container.iWindowPositionY;
1456
int iAimedX = pDialog->iAimedX;
1457
int iAimedY = pDialog->iAimedY;
1458
cairo_dock_place_dialog (pDialog, pContainer);
1460
if (iPositionX != pDialog->container.iWindowPositionX || iPositionY != pDialog->container.iWindowPositionY || iAimedX != pDialog->iAimedX || iAimedY != pDialog->iAimedY)
1461
gtk_widget_queue_draw (pDialog->container.pWidget); // on redessine meme si la position n'a pas changee, car la pointe, elle, change.
1468
CairoDialog *cairo_dock_show_dialog_full (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, double fTimeLength, const gchar *cIconPath, GtkWidget *pInteractiveWidget, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc)
1470
if (pIcon != NULL && cairo_dock_icon_is_being_removed (pIcon)) // icone en cours de suppression.
1472
g_print ("dialog skipped for %s (%.2f)\n", pIcon->cName, pIcon->fInsertRemoveFactor);
1476
CairoDialogAttribute attr;
1477
memset (&attr, 0, sizeof (CairoDialogAttribute));
1478
attr.cText = (gchar *)cText;
1479
attr.cImageFilePath = (gchar *)cIconPath;
1480
attr.pInteractiveWidget = pInteractiveWidget;
1481
attr.pActionFunc = pActionFunc;
1482
attr.pUserData = data;
1483
attr.pFreeDataFunc = pFreeDataFunc;
1484
attr.iTimeLength = (int) fTimeLength;
1485
if (pActionFunc != NULL)
1487
const gchar *cButtons[3] = {"ok", "cancel", NULL};
1488
attr.cButtonsImage = (gchar **)cButtons;
1491
CairoDialog *pDialog = cairo_dock_build_dialog (&attr, pIcon, pContainer);
1497
CairoDialog *cairo_dock_show_temporary_dialog_with_icon_printf (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, double fTimeLength, const gchar *cIconPath, ...)
1499
g_return_val_if_fail (cText != NULL, NULL);
1501
va_start (args, cIconPath);
1502
gchar *cFullText = g_strdup_vprintf (cText, args);
1503
CairoDialog *pDialog = cairo_dock_show_dialog_full (cFullText, pIcon, pContainer, fTimeLength, cIconPath, NULL, NULL, NULL, NULL);
1509
CairoDialog *cairo_dock_show_temporary_dialog_with_icon (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, double fTimeLength, const gchar *cIconPath)
1511
g_return_val_if_fail (cText != NULL, NULL);
1512
return cairo_dock_show_dialog_full (cText, pIcon, pContainer, fTimeLength, cIconPath, NULL, NULL, NULL, NULL);
1515
CairoDialog *cairo_dock_show_temporary_dialog (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, double fTimeLength)
1517
g_return_val_if_fail (cText != NULL, NULL);
1518
return cairo_dock_show_dialog_full (cText, pIcon, pContainer, fTimeLength, NULL, NULL, NULL, NULL, NULL);
1521
CairoDialog *cairo_dock_show_temporary_dialog_with_default_icon (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, double fTimeLength)
1523
g_return_val_if_fail (cText != NULL, NULL);
1525
gchar *cIconPath = g_strdup_printf ("%s/%s", CAIRO_DOCK_SHARE_DATA_DIR, CAIRO_DOCK_ICON);
1526
cIconPath = g_strdup_printf ("%s/%s", CAIRO_DOCK_SHARE_DATA_DIR, "cairo-dock-animated.xpm");
1528
CairoDialogAttribute attr;
1529
memset (&attr, 0, sizeof (CairoDialogAttribute));
1531
attr.cImageFilePath = cIconPath;
1532
attr.iNbFrames = 12;
1533
attr.iIconSize = 32;
1534
attr.iTimeLength = (int) fTimeLength;
1535
CairoDialog *pDialog = cairo_dock_build_dialog (&attr, pIcon, pContainer);
1543
CairoDialog *cairo_dock_show_dialog_with_question (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, const gchar *cIconPath, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc)
1545
return cairo_dock_show_dialog_full (cText, pIcon, pContainer, 0, cIconPath, NULL, pActionFunc, data, pFreeDataFunc);
1548
CairoDialog *cairo_dock_show_dialog_with_entry (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, const gchar *cIconPath, const gchar *cTextForEntry, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc)
1550
//GtkWidget *pWidget = cairo_dock_build_common_interactive_widget_for_dialog (cTextForEntry, -1, -1);
1551
GtkWidget *pWidget = _cairo_dock_make_entry_for_dialog (cTextForEntry);
1553
return cairo_dock_show_dialog_full (cText, pIcon, pContainer, 0, cIconPath, pWidget, pActionFunc, data, pFreeDataFunc);
1556
CairoDialog *cairo_dock_show_dialog_with_value (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, const gchar *cIconPath, double fValue, double fMaxValue, CairoDockActionOnAnswerFunc pActionFunc, gpointer data, GFreeFunc pFreeDataFunc)
1558
fValue = MAX (0., fValue);
1559
fValue = MIN (fMaxValue, fValue);
1560
//GtkWidget *pWidget = cairo_dock_build_common_interactive_widget_for_dialog (NULL, fValue, 1.);
1561
GtkWidget *pWidget = _cairo_dock_make_hscale_for_dialog (fValue, fMaxValue);
1563
return cairo_dock_show_dialog_full (cText, pIcon, pContainer, 0, cIconPath, pWidget, pActionFunc, data, pFreeDataFunc);
1569
static void _cairo_dock_get_answer_from_dialog (int iClickedButton, GtkWidget *pInteractiveWidget, gpointer *data, CairoDialog *pDialog)
1571
cd_message ("%s (%d)", __func__, iClickedButton);
1572
int *iAnswerBuffer = data[0];
1573
GMainLoop *pBlockingLoop = data[1];
1574
GtkWidget *pWidgetCatcher = data[2];
1575
if (pInteractiveWidget != NULL)
1576
gtk_widget_reparent (pInteractiveWidget, pWidgetCatcher); // j'ai rien trouve de mieux pour empecher que le 'pInteractiveWidget' ne soit pas detruit avec le dialogue apres l'appel de la callback (g_object_ref ne marche pas).
1578
*iAnswerBuffer = iClickedButton;
1580
if (g_main_loop_is_running (pBlockingLoop))
1581
g_main_loop_quit (pBlockingLoop);
1583
static gboolean _cairo_dock_dialog_destroyed (GtkWidget *pWidget, GdkEvent *event, GMainLoop *pBlockingLoop)
1585
g_print ("dialogue detruit, on sort de la boucle\n");
1586
gtk_window_set_modal (GTK_WINDOW (pWidget), FALSE);
1587
if (g_main_loop_is_running (pBlockingLoop))
1588
g_main_loop_quit (pBlockingLoop);
1591
int cairo_dock_show_dialog_and_wait (const gchar *cText, Icon *pIcon, CairoContainer *pContainer, double fTimeLength, const gchar *cIconPath, GtkWidget *pInteractiveWidget)
1593
static GtkWidget *pWidgetCatcher = NULL; // voir l'astuce plus haut.
1594
int iClickedButton = -3;
1595
GMainLoop *pBlockingLoop = g_main_loop_new (NULL, FALSE);
1596
if (pWidgetCatcher == NULL)
1597
pWidgetCatcher = gtk_hbox_new (0, FALSE);
1598
gpointer data[3] = {&iClickedButton, pBlockingLoop, pWidgetCatcher}; // inutile d'allouer 'data' puisqu'on va bloquer.
1600
CairoDialog *pDialog = cairo_dock_show_dialog_full (cText,
1606
(CairoDockActionOnAnswerFunc)_cairo_dock_get_answer_from_dialog,
1610
if (pDialog != NULL)
1612
gtk_window_set_modal (GTK_WINDOW (pDialog->container.pWidget), TRUE);
1613
g_signal_connect (pDialog->container.pWidget,
1615
G_CALLBACK (_cairo_dock_dialog_destroyed),
1618
if (myAccessibility.bPopUp && CAIRO_DOCK_IS_DOCK (pContainer))
1620
cairo_dock_pop_up (CAIRO_DOCK (pContainer));
1622
g_print ("debut de boucle bloquante ...\n");
1623
GDK_THREADS_LEAVE ();
1624
g_main_loop_run (pBlockingLoop);
1625
GDK_THREADS_ENTER ();
1626
g_print ("fin de boucle bloquante -> %d\n", iClickedButton);
1627
if (myAccessibility.bPopUp && CAIRO_DOCK_IS_DOCK (pContainer))
1628
cairo_dock_pop_down (CAIRO_DOCK (pContainer));
1629
if (CAIRO_DOCK_IS_DOCK (pContainer)/* && ! pDock->container.bInside*/)
1631
cd_message ("on force a quitter");
1632
CairoDock *pDock = CAIRO_DOCK (pContainer);
1633
pDock->container.bInside = TRUE;
1634
///pDock->bAtBottom = FALSE;
1635
cairo_dock_emit_leave_signal (pDock);
1636
/*cairo_dock_on_leave_notify (pDock->container.pWidget,
1642
g_main_loop_unref (pBlockingLoop);
1644
return iClickedButton;
1647
gchar *cairo_dock_show_demand_and_wait (const gchar *cMessage, Icon *pIcon, CairoContainer *pContainer, const gchar *cInitialAnswer)
1649
//GtkWidget *pWidget = cairo_dock_build_common_interactive_widget_for_dialog ((cInitialAnswer != NULL ? cInitialAnswer : ""), -1, -1);
1650
GtkWidget *pWidget = _cairo_dock_make_entry_for_dialog (cInitialAnswer);
1651
const gchar *cIconPath = CAIRO_DOCK_SHARE_DATA_DIR"/"CAIRO_DOCK_ICON;
1653
int iClickedButton = cairo_dock_show_dialog_and_wait (cMessage, pIcon, pContainer, 0, cIconPath, pWidget);
1655
gchar *cAnswer = (iClickedButton == 0 || iClickedButton == -1 ? g_strdup (gtk_entry_get_text (GTK_ENTRY (pWidget))) : NULL);
1656
cd_message ("cAnswer : %s", cAnswer);
1658
gtk_widget_destroy (pWidget);
1662
double cairo_dock_show_value_and_wait (const gchar *cMessage, Icon *pIcon, CairoContainer *pContainer, double fInitialValue, double fMaxValue)
1664
fInitialValue = MAX (0, fInitialValue);
1665
fInitialValue = MIN (fMaxValue, fInitialValue);
1666
//GtkWidget *pWidget = cairo_dock_build_common_interactive_widget_for_dialog (NULL, fInitialValue, fMaxValue);
1667
GtkWidget *pWidget = _cairo_dock_make_hscale_for_dialog (fInitialValue, fMaxValue);
1668
gchar *cIconPath = g_strdup_printf ("%s/%s", CAIRO_DOCK_SHARE_DATA_DIR, CAIRO_DOCK_ICON);
1670
int iClickedButton = cairo_dock_show_dialog_and_wait (cMessage, pIcon, pContainer, 0, cIconPath, pWidget);
1673
double fValue = (iClickedButton == 0 || iClickedButton == -1 ? gtk_range_get_value (GTK_RANGE (pWidget)) : -1);
1674
cd_message ("fValue : %.2f", fValue);
1676
gtk_widget_destroy (pWidget);
1680
int cairo_dock_ask_question_and_wait (const gchar *cQuestion, Icon *pIcon, CairoContainer *pContainer)
1682
gchar *cIconPath = g_strdup_printf ("%s/%s", CAIRO_DOCK_SHARE_DATA_DIR, CAIRO_DOCK_ICON); // trouver une icone de question...
1683
int iClickedButton = cairo_dock_show_dialog_and_wait (cQuestion, pIcon, pContainer, 0, cIconPath, NULL);
1686
return (iClickedButton == 0 || iClickedButton == -1 ? GTK_RESPONSE_YES : GTK_RESPONSE_NO);
1691
gboolean cairo_dock_icon_has_dialog (Icon *pIcon)
1694
CairoDialog *pDialog;
1695
for (ic = s_pDialogList; ic != NULL; ic = ic->next)
1698
if (pDialog->pIcon == pIcon)
1702
return (ic != NULL);
1705
Icon *cairo_dock_get_dialogless_icon (void)
1707
if (g_pMainDock == NULL || g_pMainDock->icons == NULL)
1710
Icon *pIcon = cairo_dock_get_first_icon_of_type (g_pMainDock->icons, CAIRO_DOCK_SEPARATOR12);
1711
if (pIcon != NULL && ! cairo_dock_icon_has_dialog (pIcon) && pIcon->cParentDockName != NULL && ! cairo_dock_icon_is_being_removed (pIcon))
1714
pIcon = cairo_dock_get_first_icon_of_type (g_pMainDock->icons, CAIRO_DOCK_SEPARATOR23);
1715
if (pIcon != NULL && ! cairo_dock_icon_has_dialog (pIcon) && pIcon->cParentDockName != NULL && ! cairo_dock_icon_is_being_removed (pIcon))
1718
pIcon = cairo_dock_get_pointed_icon (g_pMainDock->icons);
1719
if (pIcon != NULL && ! CAIRO_DOCK_IS_NORMAL_APPLI (pIcon) && ! CAIRO_DOCK_IS_APPLET (pIcon) && ! cairo_dock_icon_has_dialog (pIcon) && pIcon->cParentDockName != NULL && ! cairo_dock_icon_is_being_removed (pIcon))
1723
for (ic = g_pMainDock->icons; ic != NULL; ic = ic->next)
1726
if (! cairo_dock_icon_has_dialog (pIcon) && ! CAIRO_DOCK_IS_NORMAL_APPLI (pIcon) && ! CAIRO_DOCK_IS_APPLET (pIcon) && pIcon->cParentDockName != NULL && ! cairo_dock_icon_is_being_removed (pIcon))
1730
pIcon = cairo_dock_get_first_icon (g_pMainDock->icons);
1734
CairoDialog *cairo_dock_show_general_message (const gchar *cMessage, double fTimeLength)
1736
Icon *pIcon = cairo_dock_get_dialogless_icon ();
1737
return cairo_dock_show_temporary_dialog (cMessage, pIcon, CAIRO_CONTAINER (g_pMainDock), fTimeLength);
1740
int cairo_dock_ask_general_question_and_wait (const gchar *cQuestion)
1742
Icon *pIcon = cairo_dock_get_dialogless_icon ();
1743
return cairo_dock_ask_question_and_wait (cQuestion, pIcon, CAIRO_CONTAINER (g_pMainDock));
1748
void cairo_dock_hide_dialog (CairoDialog *pDialog)
1750
cd_debug ("%s ()", __func__);
1751
if (GTK_WIDGET_VISIBLE (pDialog->container.pWidget))
1753
pDialog->bAllowMinimize = TRUE;
1754
gtk_widget_hide (pDialog->container.pWidget);
1755
pDialog->container.bInside = FALSE;
1756
cairo_dock_replace_all_dialogs ();
1757
if (pDialog->pIcon && pDialog->pIcon->cParentDockName != NULL)
1758
cairo_dock_dialog_window_destroyed ();
1762
void cairo_dock_unhide_dialog (CairoDialog *pDialog)
1764
g_print ("%s ()\n", __func__);
1765
if (! GTK_WIDGET_VISIBLE (pDialog->container.pWidget))
1767
if (pDialog->pInteractiveWidget != NULL)
1768
gtk_widget_grab_focus (pDialog->pInteractiveWidget);
1769
Icon *pIcon = pDialog->pIcon;
1772
CairoContainer *pContainer = cairo_dock_search_container_from_icon (pIcon);
1773
cairo_dock_place_dialog (pDialog, pContainer);
1774
if (pIcon->cParentDockName != NULL)
1775
cairo_dock_dialog_window_created ();
1778
gtk_window_present (GTK_WINDOW (pDialog->container.pWidget));
1781
void cairo_dock_toggle_dialog_visibility (CairoDialog *pDialog)
1783
if (GTK_WIDGET_VISIBLE (pDialog->container.pWidget))
1784
cairo_dock_hide_dialog (pDialog);
1786
cairo_dock_unhide_dialog (pDialog);
1790
GtkWidget *cairo_dock_steal_widget_from_its_container (GtkWidget *pWidget)
1792
/*static GtkWidget *pWidgetCatcher = NULL;
1793
if (pWidgetCatcher == NULL)
1794
pWidgetCatcher = gtk_hbox_new (0, FALSE);*/
1795
g_return_val_if_fail (pWidget != NULL, NULL);
1796
GtkWidget *pContainer = gtk_widget_get_parent (pWidget);
1797
if (pContainer != NULL)
1799
/*gtk_widget_reparent (pWidget, pWidgetCatcher);
1800
cd_message ("reparent -> ref = %d\n", pWidget->object.parent_instance.ref_count);
1801
gtk_object_ref (GTK_OBJECT (pWidget));
1802
gtk_object_ref (GTK_OBJECT (pWidget));
1803
gtk_widget_unparent (pWidget);
1804
gtk_object_unref (GTK_OBJECT (pWidget));
1805
cd_message ("unparent -> ref = %d\n", pWidget->object.parent_instance.ref_count);*/
1806
cd_debug (" ref : %d", pWidget->object.parent_instance.ref_count);
1807
g_object_ref (G_OBJECT (pWidget));
1808
gtk_container_remove (GTK_CONTAINER (pContainer), pWidget);
1809
cd_debug (" -> %d", pWidget->object.parent_instance.ref_count);
1814
GtkWidget *cairo_dock_steal_interactive_widget_from_dialog (CairoDialog *pDialog)
1816
if (pDialog == NULL)
1819
GtkWidget *pInteractiveWidget = pDialog->pInteractiveWidget;
1820
if (pInteractiveWidget != NULL)
1822
pInteractiveWidget = cairo_dock_steal_widget_from_its_container (pInteractiveWidget);
1823
pDialog->pInteractiveWidget = NULL;
1825
return pInteractiveWidget;
1828
void cairo_dock_set_new_dialog_text_surface (CairoDialog *pDialog, cairo_surface_t *pNewTextSurface, int iNewTextWidth, int iNewTextHeight)
1830
int iPrevMessageWidth = pDialog->iMessageWidth;
1831
int iPrevMessageHeight = pDialog->iMessageHeight;
1833
cairo_surface_destroy (pDialog->pTextBuffer);
1834
pDialog->pTextBuffer = pNewTextSurface;
1835
if (pDialog->iTextTexture != 0)
1836
_cairo_dock_delete_texture (pDialog->iTextTexture);
1837
///pDialog->iTextTexture = cairo_dock_create_texture_from_surface (pNewTextSurface);
1839
pDialog->iTextWidth = iNewTextWidth;
1840
pDialog->iTextHeight = iNewTextHeight;
1841
cairo_dock_compute_dialog_sizes (pDialog);
1843
if (pDialog->iMessageWidth != iPrevMessageWidth || pDialog->iMessageHeight != iPrevMessageHeight)
1845
gtk_widget_set (pDialog->pMessageWidget, "width-request", pDialog->iMessageWidth, "height-request", pDialog->iMessageHeight, NULL);
1846
if (pDialog->pIcon != NULL)
1848
CairoContainer *pContainer = cairo_dock_search_container_from_icon (pDialog->pIcon);
1849
cairo_dock_place_dialog (pDialog, pContainer);
1851
gtk_widget_queue_draw (pDialog->container.pWidget);
1855
cairo_dock_damage_text_dialog (pDialog);
1858
if (pDialog->iMaxTextWidth > 0 && pDialog->iSidAnimateText == 0 && pDialog->pTextBuffer != NULL && pDialog->iTextWidth > pDialog->iMaxTextWidth)
1860
pDialog->iSidAnimateText = g_timeout_add (200, (GSourceFunc) _cairo_dock_animate_dialog_text, (gpointer) pDialog); // multiple du timeout de l'icone animee.
1864
void cairo_dock_set_new_dialog_icon_surface (CairoDialog *pDialog, cairo_surface_t *pNewIconSurface, int iNewIconSize)
1866
int iPrevMessageWidth = pDialog->iMessageWidth;
1867
int iPrevMessageHeight = pDialog->iMessageHeight;
1869
cairo_surface_destroy (pDialog->pIconBuffer);
1871
cairo_t *pSourceContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDialog));
1872
pDialog->pIconBuffer = cairo_dock_duplicate_surface (pNewIconSurface, pSourceContext, iNewIconSize, iNewIconSize, iNewIconSize, iNewIconSize);
1873
if (pDialog->iIconTexture != 0)
1874
_cairo_dock_delete_texture (pDialog->iIconTexture);
1875
/// pDialog->iIconTexture = cairo_dock_create_texture_from_surface (pDialog->pIconBuffer);
1877
pDialog->iIconSize = iNewIconSize;
1878
cairo_dock_compute_dialog_sizes (pDialog);
1880
if (pDialog->iMessageWidth != iPrevMessageWidth || pDialog->iMessageHeight != iPrevMessageHeight)
1882
gtk_widget_set (pDialog->pMessageWidget, "width-request", pDialog->iMessageWidth, "height-request", pDialog->iMessageHeight, NULL);
1883
if (pDialog->pIcon != NULL)
1885
CairoContainer *pContainer = cairo_dock_search_container_from_icon (pDialog->pIcon);
1886
cairo_dock_place_dialog (pDialog, pContainer);
1888
gtk_widget_queue_draw (pDialog->container.pWidget);
1892
cairo_dock_damage_icon_dialog (pDialog);
1897
void cairo_dock_set_dialog_message (CairoDialog *pDialog, const gchar *cMessage)
1899
cairo_t *pSourceContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDialog));
1901
int iNewTextWidth=0, iNewTextHeight=0;
1902
cairo_surface_t *pNewTextSurface = _cairo_dock_create_dialog_text_surface (cMessage, NULL, pSourceContext, &iNewTextWidth, &iNewTextHeight);
1904
cairo_dock_set_new_dialog_text_surface (pDialog, pNewTextSurface, iNewTextWidth, iNewTextHeight);
1906
cairo_destroy (pSourceContext);
1908
void cairo_dock_set_dialog_message_printf (CairoDialog *pDialog, const gchar *cMessageFormat, ...)
1910
g_return_if_fail (cMessageFormat != NULL);
1912
va_start (args, cMessageFormat);
1913
gchar *cMessage = g_strdup_vprintf (cMessageFormat, args);
1914
cairo_dock_set_dialog_message (pDialog, cMessage);
1919
void cairo_dock_set_dialog_icon (CairoDialog *pDialog, const gchar *cImageFilePath)
1921
cairo_t *pSourceContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDialog));
1923
cairo_surface_t *pNewIconSurface = cairo_dock_create_surface_for_square_icon (cImageFilePath, pSourceContext, myDialogs.iDialogIconSize);
1924
int iNewIconSize = (pNewIconSurface != NULL ? myDialogs.iDialogIconSize : 0);
1926
cairo_dock_set_new_dialog_icon_surface (pDialog, pNewIconSurface, iNewIconSize);
1928
cairo_destroy (pSourceContext);
1932
void cairo_dock_damage_icon_dialog (CairoDialog *pDialog)
1934
if (!pDialog->container.bUseReflect)
1935
gtk_widget_queue_draw_area (pDialog->container.pWidget,
1936
pDialog->iLeftMargin,
1937
(pDialog->container.bDirectionUp ?
1938
pDialog->iTopMargin :
1939
pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight)),
1941
pDialog->iIconSize);
1943
gtk_widget_queue_draw (pDialog->container.pWidget);
1946
void cairo_dock_damage_text_dialog (CairoDialog *pDialog)
1948
if (!pDialog->container.bUseReflect)
1949
gtk_widget_queue_draw_area (pDialog->container.pWidget,
1950
pDialog->iLeftMargin + pDialog->iIconSize + CAIRO_DIALOG_TEXT_MARGIN,
1951
(pDialog->container.bDirectionUp ?
1952
pDialog->iTopMargin :
1953
pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight)),
1954
_drawn_text_width (pDialog),
1955
pDialog->iTextHeight);
1957
gtk_widget_queue_draw (pDialog->container.pWidget);
1960
void cairo_dock_damage_interactive_widget_dialog (CairoDialog *pDialog)
1962
if (!pDialog->container.bUseReflect)
1963
gtk_widget_queue_draw_area (pDialog->container.pWidget,
1964
pDialog->iLeftMargin,
1965
(pDialog->container.bDirectionUp ?
1966
pDialog->iTopMargin + pDialog->iMessageHeight :
1967
pDialog->container.iHeight - (pDialog->iTopMargin + pDialog->iBubbleHeight) + pDialog->iMessageHeight),
1968
pDialog->iInteractiveWidth,
1969
pDialog->iInteractiveHeight);
1971
gtk_widget_queue_draw (pDialog->container.pWidget);