1 /* GuiDialog.cpp
2  *
3  * Copyright (C) 1993-2018,2020,2021 Paul Boersma, 2013 Tom Naughton
4  *
5  * This code is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at
8  * your option) any later version.
9  *
10  * This code is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this work. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "GuiP.h"
20 
21 Thing_implement (GuiDialog, GuiShell, 0);
22 
23 #if gtk
_GuiGtkDialog_destroyCallback(GuiObject widget,gpointer void_me)24 	static void _GuiGtkDialog_destroyCallback (GuiObject widget, gpointer void_me) {
25 		(void) widget;
26 		iam (GuiDialog);
27 		forget (me);
28 	}
_GuiGtkDialog_goAwayCallback(GuiObject widget,GdkEvent * event,gpointer void_me)29 	static gboolean _GuiGtkDialog_goAwayCallback (GuiObject widget, GdkEvent *event, gpointer void_me) {
30 		(void) widget;
31 		(void) event;
32 		iam (GuiDialog);
33 		if (my d_goAwayCallback)
34 			my d_goAwayCallback (my d_goAwayBoss);
35 		return true;   // signal handled (don't destroy dialog)
36 	}
37 #elif motif
_GuiMotifDialog_destroyCallback(GuiObject widget,XtPointer void_me,XtPointer call)38 	static void _GuiMotifDialog_destroyCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
39 		(void) widget; (void) call;
40 		iam (GuiDialog);
41 		forget (me);
42 	}
_GuiMotifDialog_goAwayCallback(GuiObject widget,XtPointer void_me,XtPointer call)43 	static void _GuiMotifDialog_goAwayCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
44 		(void) widget; (void) call;
45 		iam (GuiDialog);
46 		if (my d_goAwayCallback)
47 			my d_goAwayCallback (my d_goAwayBoss);
48 	}
49 #endif
50 
GuiDialog_create(GuiWindow parent,int x,int y,int width,int height,conststring32 title,GuiShell_GoAwayCallback goAwayCallback,Thing goAwayBoss,uint32 flags)51 GuiDialog GuiDialog_create (GuiWindow parent, int x, int y, int width, int height,
52 	conststring32 title, GuiShell_GoAwayCallback goAwayCallback, Thing goAwayBoss, uint32 flags)
53 {
54 	autoGuiDialog me = Thing_new (GuiDialog);
55 	my d_parent = parent;
56 	my d_goAwayCallback = goAwayCallback;
57 	my d_goAwayBoss = goAwayBoss;
58 	#if gtk
59 		my d_gtkWindow = (GtkWindow *) gtk_dialog_new ();
60 		if (parent) {
61 			Melder_assert (parent -> d_widget);
62 			GuiObject toplevel = gtk_widget_get_ancestor (GTK_WIDGET (parent -> d_widget), GTK_TYPE_WINDOW);
63 			if (toplevel) {
64 				gtk_window_set_transient_for (GTK_WINDOW (my d_gtkWindow), GTK_WINDOW (toplevel));
65 				gtk_window_set_destroy_with_parent (GTK_WINDOW (my d_gtkWindow), true);
66 			}
67 		}
68 		g_signal_connect (G_OBJECT (my d_gtkWindow), "delete-event",
69 				goAwayCallback ? G_CALLBACK (_GuiGtkDialog_goAwayCallback) : G_CALLBACK (gtk_widget_hide_on_delete), me.get());
70 		gtk_window_set_default_size (GTK_WINDOW (my d_gtkWindow), width, height);
71 		gtk_window_set_modal (GTK_WINDOW (my d_gtkWindow), flags & GuiDialog_MODAL);
72 		gtk_window_set_resizable (GTK_WINDOW (my d_gtkWindow), false);
73 		//GuiObject vbox = GTK_DIALOG (my d_gtkWindow) -> vbox;
74 		GuiObject vbox = gtk_dialog_get_content_area (GTK_DIALOG (my d_gtkWindow));
75 		my d_widget = gtk_fixed_new ();
76 		_GuiObject_setUserData (my d_widget, me.get());
77 		gtk_widget_set_size_request (GTK_WIDGET (my d_widget), width, height);
78 		gtk_container_add (GTK_CONTAINER (vbox /*my d_gtkWindow*/), GTK_WIDGET (my d_widget));
79 		gtk_widget_show (GTK_WIDGET (my d_widget));
80 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkDialog_destroyCallback), me.get());
81 		#if defined (chrome)
82 			my chrome_surrogateShellTitleLabelWidget = gtk_label_new (Melder_peek32to8 (title));
83 			gtk_label_set_use_markup (GTK_LABEL (my chrome_surrogateShellTitleLabelWidget), true);
84 			gtk_widget_set_size_request (GTK_WIDGET (my chrome_surrogateShellTitleLabelWidget), width, 31 /*Machine_getTextHeight()*/);
85 			gtk_misc_set_alignment (GTK_MISC (my chrome_surrogateShellTitleLabelWidget), 0.5, 0.0);
86 			//gtk_widget_set_xalign (GTK_WIDGET (my chrome_surrogateShellTitleLabelWidget), 0.5);
87 			gtk_fixed_put (GTK_FIXED (my d_widget), GTK_WIDGET (my chrome_surrogateShellTitleLabelWidget), 0 /*8*/, 0);
88 			gtk_widget_show (GTK_WIDGET (my chrome_surrogateShellTitleLabelWidget));
89 		#endif
90 		GuiShell_setTitle (me.get(), title);
91 	#elif motif
92 		my d_xmShell = XmCreateDialogShell (parent -> d_widget, "dialogShell", nullptr, 0);
93 		XtVaSetValues (my d_xmShell, XmNdeleteResponse, goAwayCallback ? XmDO_NOTHING : XmUNMAP, XmNx, x, XmNy, y, nullptr);
94 		if (goAwayCallback)
95 			XmAddWMProtocolCallback (my d_xmShell, 'delw', _GuiMotifDialog_goAwayCallback, (char *) me.get());
96 		GuiShell_setTitle (me.get(), title);
97 		my d_widget = XmCreateForm (my d_xmShell, "dialog", nullptr, 0);
98 		XtVaSetValues (my d_widget, XmNwidth, (Dimension) width, XmNheight, (Dimension) height, nullptr);
99 		_GuiObject_setUserData (my d_widget, me.get());
100 		XtAddCallback (my d_widget, XmNdestroyCallback, _GuiMotifDialog_destroyCallback, me.get());
101 		XtVaSetValues (my d_widget, XmNdialogStyle,
102 			(flags & GuiDialog_MODAL) ? XmDIALOG_FULL_APPLICATION_MODAL : XmDIALOG_MODELESS,
103 			XmNautoUnmanage, False, nullptr
104 		);
105 	#elif cocoa
106 		(void) parent;
107 		NSRect rect = { { (CGFloat) x, (CGFloat) y }, { (CGFloat) width, (CGFloat) height } };
108 		my d_cocoaShell = [[GuiCocoaShell alloc]
109 			initWithContentRect: rect
110 			styleMask: NSTitledWindowMask | NSClosableWindowMask
111 			backing: NSBackingStoreBuffered
112 			defer: false
113 		];
114         [my d_cocoaShell   setMinSize: NSMakeSize (500.0, 500.0)];   // BUG: should not be needed
115 		[my d_cocoaShell   setTitle: (NSString *) Melder_peek32toCfstring (title)];
116 		//[my d_cocoaShell   makeKeyAndOrderFront: nil];
117 		my d_widget = (GuiObject) [my d_cocoaShell   contentView];
118 		[my d_cocoaShell   setUserData: me.get()];
119 		[my d_cocoaShell   setReleasedWhenClosed: NO];
120 	#endif
121 	my d_shell = me.get();
122 	return me.releaseToAmbiguousOwner();
123 }
124 
GuiDialog_setDefaultCallback(GuiDialog me,GuiDialog_DefaultCallback callback,Thing boss)125 void GuiDialog_setDefaultCallback (GuiDialog me, GuiDialog_DefaultCallback callback, Thing boss) {
126 	my d_defaultCallback = callback;
127 	my d_defaultBoss = boss;
128 }
129 
130 /* End of file GuiDialog.cpp */
131