More Motif stuff incl. beginnings of wxToolBar
[wxWidgets.git] / src / motif / toolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: toolbar.cpp
3 // Purpose: wxToolBar
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "toolbar.h"
14 #endif
15
16 #include "wx/wx.h"
17 #include "wx/motif/toolbar.h"
18
19 #include <Xm/Xm.h>
20 #include <Xm/PushBG.h>
21 #include <Xm/PushB.h>
22 #include <Xm/ToggleB.h>
23 #include <Xm/ToggleBG.h>
24 #include <Xm/Form.h>
25
26 #include "wx/motif/private.h"
27
28 #if !USE_SHARED_LIBRARY
29 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
30
31 BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
32 END_EVENT_TABLE()
33 #endif
34
35 wxToolBar::wxToolBar():
36 m_widgets(wxKEY_INTEGER)
37 {
38 m_maxWidth = -1;
39 m_maxHeight = -1;
40 m_defaultWidth = 24;
41 m_defaultHeight = 22;
42 // TODO
43 }
44
45 bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
46 long style, const wxString& name)
47 {
48 m_maxWidth = -1;
49 m_maxHeight = -1;
50
51 m_defaultWidth = 24;
52 m_defaultHeight = 22;
53 SetName(name);
54 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
55 m_foregroundColour = parent->GetForegroundColour();
56 m_windowStyle = style;
57
58 SetParent(parent);
59
60 if (parent) parent->AddChild(this);
61
62 Widget parentWidget = (Widget) parent->GetClientWidget();
63
64 Widget toolbar = XtVaCreateManagedWidget("toolbar",
65 xmFormWidgetClass, parentWidget,
66 XmNtraversalOn, False,
67 XmNhorizontalSpacing, 0,
68 XmNverticalSpacing, 0,
69 NULL);
70
71 m_mainWidget = (WXWidget) toolbar;
72
73 SetCanAddEventHandler(TRUE);
74 AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y);
75
76 SetFont(* parent->GetFont());
77 ChangeBackgroundColour();
78
79 return TRUE;
80 }
81
82 wxToolBar::~wxToolBar()
83 {
84 // TODO
85 }
86
87 bool wxToolBar::CreateTools()
88 {
89 if (m_tools.Number() == 0)
90 return FALSE;
91
92 m_widgets.Clear();
93 Widget prevButton = (Widget) 0;
94 wxNode* node = m_tools.First();
95 while (node)
96 {
97 wxToolBarTool *tool = (wxToolBarTool *)node->Data();
98 if ((tool->m_toolStyle != wxTOOL_STYLE_SEPARATOR) && tool->m_bitmap1.Ok())
99 {
100 Widget button = (Widget) 0;
101
102 if (tool->m_isToggle)
103 {
104 button = XtVaCreateManagedWidget("toggleButton",
105 xmToggleButtonWidgetClass, (Widget) m_mainWidget,
106 XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET,
107 XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton,
108 XmNleftOffset, 0,
109 XmNtopAttachment, XmATTACH_FORM,
110 // XmNpushButtonEnabled, True,
111 XmNmultiClick, XmMULTICLICK_KEEP,
112 XmNlabelType, XmPIXMAP,
113 NULL);
114 }
115 else
116 {
117 button = XtVaCreateManagedWidget("button",
118 xmPushButtonWidgetClass, (Widget) m_mainWidget,
119 XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET,
120 XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton,
121 XmNleftOffset, 0,
122 XmNtopAttachment, XmATTACH_FORM,
123 XmNpushButtonEnabled, True,
124 XmNmultiClick, XmMULTICLICK_KEEP,
125 XmNlabelType, XmPIXMAP,
126 NULL);
127 }
128
129 // For each button, if there is a mask, we must create
130 // a new wxBitmap that has the correct background colour
131 // for the button. Otherwise the background will just be
132 // e.g. black if a transparent XPM has been loaded.
133 if (tool->m_bitmap1.GetMask())
134 {
135 wxBitmap newBitmap(tool->m_bitmap1.GetWidth(),
136 tool->m_bitmap1.GetHeight(),
137 tool->m_bitmap1.GetDepth());
138 int backgroundPixel;
139 XtVaGetValues(button, XmNbackground, &backgroundPixel,
140 NULL);
141
142
143 wxColour col;
144 col.SetPixel(backgroundPixel);
145
146 wxMemoryDC destDC;
147 wxMemoryDC srcDC;
148 srcDC.SelectObject(tool->m_bitmap1);
149 destDC.SelectObject(newBitmap);
150
151 wxBrush brush(col, wxSOLID);
152 destDC.SetOptimization(FALSE);
153 destDC.SetBackground(brush);
154 destDC.Clear();
155 destDC.Blit(0, 0, tool->m_bitmap1.GetWidth(), tool->m_bitmap1.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE);
156
157 tool->m_bitmap1 = newBitmap;
158 }
159 if (tool->m_bitmap2.Ok() && tool->m_bitmap2.GetMask())
160 {
161 wxBitmap newBitmap(tool->m_bitmap2.GetWidth(),
162 tool->m_bitmap2.GetHeight(),
163 tool->m_bitmap2.GetDepth());
164 int backgroundPixel;
165 XtVaGetValues(button, XmNbackground, &backgroundPixel,
166 NULL);
167
168
169 wxColour col;
170 col.SetPixel(backgroundPixel);
171
172 wxMemoryDC destDC;
173 wxMemoryDC srcDC;
174 srcDC.SelectObject(tool->m_bitmap2);
175 destDC.SelectObject(newBitmap);
176
177 wxBrush brush(col, wxSOLID);
178 destDC.SetOptimization(FALSE);
179 destDC.SetBackground(brush);
180 destDC.Clear();
181 destDC.Blit(0, 0, tool->m_bitmap2.GetWidth(), tool->m_bitmap2.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE);
182
183 tool->m_bitmap2 = newBitmap;
184 }
185 Pixmap pixmap = (Pixmap) tool->m_bitmap1.GetPixmap();
186 Pixmap insensPixmap = (Pixmap) tool->m_bitmap1.GetInsensPixmap();
187
188 if (tool->m_isToggle)
189 {
190 Pixmap pixmap2 = (Pixmap) 0;
191 Pixmap insensPixmap2 = (Pixmap) 0;
192
193 // If there's a bitmap for the toggled state, use it,
194 // otherwise generate one.
195 if (tool->m_bitmap2.Ok())
196 {
197 pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap();
198 insensPixmap2 = (Pixmap) tool->m_bitmap2.GetInsensPixmap();
199 }
200 else
201 {
202 pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button);
203 // This has to be both toggled and insensitive, but
204 // wxBitmap doesn't yet have a member to store & destroy
205 // it, so make it the same as pixmap2. Actually it's not
206 // used!
207 insensPixmap2 = pixmap2;
208 }
209 XtVaSetValues (button,
210 XmNlabelPixmap, pixmap,
211 XmNselectPixmap, pixmap,
212 XmNlabelInsensitivePixmap, insensPixmap,
213 XmNselectInsensitivePixmap, insensPixmap,
214 XmNarmPixmap, pixmap2,
215 XmNlabelType, XmPIXMAP,
216 NULL);
217
218 }
219 else
220 {
221 XtVaSetValues(button,
222 XmNlabelPixmap, pixmap,
223 XmNlabelInsensitivePixmap, insensPixmap,
224 NULL);
225 }
226
227 m_widgets.Append(tool->m_index, (wxObject*) button);
228
229 prevButton = button;
230
231 }
232 node = node->Next();
233 }
234
235 return TRUE;
236 }
237
238 void wxToolBar::SetToolBitmapSize(const wxSize& size)
239 {
240 m_defaultWidth = size.x; m_defaultHeight = size.y;
241 // TODO
242 }
243
244 wxSize wxToolBar::GetMaxSize() const
245 {
246 // TODO
247 return wxSize(0, 0);
248 }
249
250 // The button size is bigger than the bitmap size
251 wxSize wxToolBar::GetToolSize() const
252 {
253 // TODO
254 return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
255 }
256
257 void wxToolBar::EnableTool(int toolIndex, bool enable)
258 {
259 wxNode *node = m_tools.Find((long)toolIndex);
260 if (node)
261 {
262 wxToolBarTool *tool = (wxToolBarTool *)node->Data();
263 tool->m_enabled = enable;
264 // TODO enable button
265 }
266 }
267
268 void wxToolBar::ToggleTool(int toolIndex, bool toggle)
269 {
270 wxNode *node = m_tools.Find((long)toolIndex);
271 if (node)
272 {
273 wxToolBarTool *tool = (wxToolBarTool *)node->Data();
274 if (tool->m_isToggle)
275 {
276 tool->m_toggleState = toggle;
277 // TODO: set toggle state
278 }
279 }
280 }
281
282 void wxToolBar::ClearTools()
283 {
284 wxNode* node = m_widgets.First();
285 while (node)
286 {
287 Widget button = (Widget) node->Data();
288 XtDestroyWidget(button);
289 node = node->Next();
290 }
291 m_widgets.Clear();
292
293 wxToolBarBase::ClearTools();
294 }
295
296 // If pushedBitmap is NULL, a reversed version of bitmap is
297 // created and used as the pushed/toggled image.
298 // If toggle is TRUE, the button toggles between the two states.
299
300 wxToolBarTool *wxToolBar::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap,
301 bool toggle, long xPos, long yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2)
302 {
303 wxToolBarTool *tool = new wxToolBarTool(index, bitmap, (wxBitmap *)NULL, toggle, xPos, yPos, helpString1, helpString2);
304 tool->m_clientData = clientData;
305
306 if (xPos > -1)
307 tool->m_x = xPos;
308 else
309 tool->m_x = m_xMargin;
310
311 if (yPos > -1)
312 tool->m_y = yPos;
313 else
314 tool->m_y = m_yMargin;
315
316 tool->SetSize(GetDefaultButtonWidth(), GetDefaultButtonHeight());
317
318 m_tools.Append((long)index, tool);
319 return tool;
320 }
321