1 /**************************************************************************\
2  * Copyright (c) Kongsberg Oil & Gas Technologies AS
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32 
33 #include <qmetaobject.h>
34 #include <Inventor/Qt/moc_SoQtMaterialList.icc>
35 
36 #include <stdlib.h>
37 
38 #include <Inventor/SbPList.h>
39 #include <Inventor/errors/SoDebugError.h>
40 #include <Inventor/SoDB.h>
41 #include <Inventor/SoInput.h>
42 #include <Inventor/nodes/SoMaterial.h>
43 
44 #include <soqtdefs.h>
45 #include <Inventor/Qt/SoQt.h>
46 #include <Inventor/Qt/SoAnyMaterialList.h>
47 
48 #include <Inventor/Qt/SoQtMaterialList.h>
49 
50 // *************************************************************************
51 
52 /*!
53   \class SoQtMaterialList Inventor/Qt/SoQtMaterialList.h
54   \brief The SoQtMaterialList class is a component for adding material
55   selection to scene graph editors.
56 */
57 
58 // *************************************************************************
59 
60 SOQT_OBJECT_SOURCE(SoQtMaterialList);
61 
62 // *************************************************************************
63 
64 /*!
65   Public constructor.
66 */
67 
SoQtMaterialList(QWidget * parent,const char * const name,SbBool embed,const char * const dir)68 SoQtMaterialList::SoQtMaterialList(
69   QWidget * parent,
70   const char * const name,
71   SbBool embed,
72   const char * const dir)
73 : inherited(parent, name, embed)
74 {
75   this->constructor(dir, true);
76 } // SoQtMaterialList()
77 
78 /*!
79   Protected constructor.
80 */
81 
SoQtMaterialList(QWidget * parent,const char * const name,SbBool embed,const char * const dir,SbBool build)82 SoQtMaterialList::SoQtMaterialList(// protected
83   QWidget * parent,
84   const char * const name,
85   SbBool embed,
86   const char * const dir,
87   SbBool build)
88 : inherited(parent, name, embed)
89 {
90   this->constructor(dir, build);
91 } // SoQtMaterialList()
92 
93 /*!
94   Common constructor code.
95 */
96 
97 void
constructor(const char * const dir,const SbBool build)98 SoQtMaterialList::constructor(// private
99   const char * const dir,
100   const SbBool build)
101 {
102   this->common = new SoAnyMaterialList(dir);
103   this->setSize(SbVec2s(200, 300));
104 
105   if (build) {
106     this->setClassName("SoQtMaterialList");
107     QWidget * materials = this->buildWidget(this->getParentWidget());
108     this->setBaseWidget(materials);
109   }
110 } // constructor()
111 
112 /*!
113   Destructor.
114 */
115 
~SoQtMaterialList(void)116 SoQtMaterialList::~SoQtMaterialList(
117   void)
118 {
119   delete this->common;
120 } // ~SoQtMaterialList()
121 
122 // *************************************************************************
123 
124 /*!
125   FIXME: write doc
126 */
127 
128 void
addCallback(SoQtMaterialListCB * const callback,void * const closure)129 SoQtMaterialList::addCallback(
130   SoQtMaterialListCB * const callback,
131   void * const closure)
132 {
133   common->addCallback(callback, closure);
134 } // addCallback()
135 
136 /*!
137   FIXME: write doc
138 */
139 
140 void
removeCallback(SoQtMaterialListCB * const callback,void * const closure)141 SoQtMaterialList::removeCallback(
142   SoQtMaterialListCB * const callback,
143   void * const closure)
144 {
145   common->removeCallback(callback, closure);
146 } // removeCallback()
147 
148 // *************************************************************************
149 
150 /*!
151   FIXME: write doc
152 */
153 
154 const char *
getDefaultWidgetName(void) const155 SoQtMaterialList::getDefaultWidgetName(// virtual, protected
156   void) const
157 {
158   static const char defaultWidgetName[] = "SoQtMaterialList";
159   return defaultWidgetName;
160 } // getDefaultWidgetName()
161 
162 /*!
163   FIXME: write doc
164 */
165 
166 const char *
getDefaultTitle(void) const167 SoQtMaterialList::getDefaultTitle(// virtual, protected
168   void) const
169 {
170   static const char defaultTitle[] = "Material List";
171   return defaultTitle;
172 } // getDefaultTitle()
173 
174 /*!
175   FIXME: write doc
176 */
177 
178 const char *
getDefaultIconTitle(void) const179 SoQtMaterialList::getDefaultIconTitle(// virtual, protected
180   void) const
181 {
182   static const char defaultIconTitle[] = "Material List";
183   return defaultIconTitle;
184 } // getDefaultIconTitle()
185 
186 // *************************************************************************
187 
188 /*!
189   FIXME: write doc
190 */
191 
192 QWidget *
buildWidget(QWidget * parent)193 SoQtMaterialList::buildWidget(// protected
194   QWidget * parent)
195 {
196 /*
197   // we're building pulldown menu automatically...
198   QWidget * root = XtVaCreateManagedWidget(this->getClassName(),
199     xmFormWidgetClass, parent,
200     NULL);
201 
202   QWidget * menubar = XtVaCreateManagedWidget("menubar",
203     xmRowColumnWidgetClass, root,
204     XmNleftAttachment, XmATTACH_FORM,
205     XmNtopAttachment, XmATTACH_FORM,
206     XmNrightAttachment, XmATTACH_FORM,
207     XmNrowColumnType, XmMENU_BAR,
208     NULL);
209 
210   QWidget * palettemenu = this->buildPulldownMenu(menubar);
211 
212   SoQtMaterialDirectory * dir = common->getMaterialDirectory();
213 
214   int group, materials;
215   XmStringTable list;
216   if (dir->numGroups > 0) {
217     group = dir->current;
218     materials = dir->groups[group]->numMaterials;
219     list = (XmStringTable) XtMalloc(sizeof(XmString) * materials);
220     for (int i = 0; i < materials; i++)
221       list[i] =
222         SoQt::encodeString(dir->groups[group]->materials[i]->name);
223   } else {
224     materials = 0;
225     list = NULL;
226   }
227 
228   Arg argv[10];
229   int argc = 0;
230   XtSetArg(argv[argc], XmNleftAttachment, XmATTACH_FORM); argc++;
231   XtSetArg(argv[argc], XmNtopAttachment, XmATTACH_WIDGET); argc++;
232   XtSetArg(argv[argc], XmNtopWidget, menubar); argc++;
233   XtSetArg(argv[argc], XmNrightAttachment, XmATTACH_FORM); argc++;
234   XtSetArg(argv[argc], XmNbottomAttachment, XmATTACH_FORM); argc++;
235   XtSetArg(argv[argc], XmNselectionPolicy, XmSINGLE_SELECT); argc++;
236   XtSetArg(argv[argc], XmNscrollBarDisplayPolicy, XmSTATIC); argc++;
237   XtSetArg(argv[argc], XmNitems, list); argc++;
238   XtSetArg(argv[argc], XmNitemCount, materials); argc++;
239 
240   this->listwidget = XmCreateScrolledList(root, "materials", argv, argc);
241   XtManageChild(this->listwidget);
242   XtAddCallback(this->listwidget, XmNdefaultActionCallback,
243     SoQtMaterialList::selection_cb, (void *) this);
244   for (int i = 0; i < materials; i++)
245     XmStringFree(list[i]);
246   XtFree((char *) list);
247   return root;
248 */
249   return NULL;
250 } // buildWidget()
251 
252 // *************************************************************************
253 
254 /*!
255   \internal
256   FIXME: write doc
257 */
258 
259 void
selectionCallback(int materialid)260 SoQtMaterialList::selectionCallback(// private
261   int materialid)
262 {
263   materialid--; // get index
264   SoQtMaterialDirectory * data = common->getMaterialDirectory();
265 
266   assert(materialid >= 0 &&
267           materialid < data->groups[data->current]->numMaterials);
268   const char * materialdata =
269     data->groups[data->current]->materials[materialid]->data;
270 
271   SoInput reader;
272   if (data->flags & SOQT_BUILTIN_MATERIALS) {
273     reader.setBuffer((void *) materialdata, strlen(materialdata));
274   } else {
275     if (! reader.openFile(materialdata, false)) {
276       SoDebugError::postWarning("SoQtMaterialList::selectionCallback",
277         "could not open file: \"%s\"", materialdata);
278       return;
279     }
280   }
281 
282   SoNode * material = NULL;
283   if (! SoDB::read(&reader, material)) {
284     SoDebugError::postWarning("SoQtMaterialList::selectionCallback",
285       "failed to read material");
286     return;
287   }
288   if (! material) {
289     SoDebugError::postWarning("SoQtMaterialList::selectionCallback",
290       "read returned no data");
291     return;
292   }
293   material->ref();
294   if (! material->isOfType(SoMaterial::getClassTypeId())) {
295     SoDebugError::postWarning("SoQtMaterialList::selectionCallback",
296       "not a material node!");
297     material->unref();
298     return;
299   }
300   common->invokeCallbacks((SoMaterial *) material);
301   material->unref();
302 } // selectionCallback()
303 
304 /*!
305   \internal
306   FIXME: write doc
307 */
308 
309 void
selection_cb(QWidget *,void * closure,void * call_data)310 SoQtMaterialList::selection_cb(// static, private
311   QWidget *,
312   void * closure,
313   void * call_data)
314 {
315 /*
316   SoQtMaterialList * component = (SoQtMaterialList *) closure;
317   XmListCallbackStruct * data = (XmListCallbackStruct *) call_data;
318   component->selectionCallback(data->item_position);
319 */
320 } // selection_cb()
321 
322 // *************************************************************************
323 
324 /*!
325   \internal
326   FIXME: write doc
327 */
328 
329 void
paletteMenuCallback(QWidget * menuitem)330 SoQtMaterialList::paletteMenuCallback(// private
331   QWidget * menuitem)
332 {
333 /*
334   SoQtMaterialDirectory * data = common->getMaterialDirectory();
335   int i, j;
336   for (i = 0; i < data->numGroups; i++) {
337     if (data->groups[i]->menuitem == menuitem) {
338       XmStringTable list = (XmStringTable) XtMalloc(sizeof(XmString) *
339         data->groups[i]->numMaterials);
340       for (j = 0; j < data->groups[i]->numMaterials; j++)
341         list[j] = SoQt::encodeString(data->groups[i]->materials[j]->name);
342       XtVaSetValues(this->listwidget,
343         XmNitemCount, data->groups[i]->numMaterials,
344         XmNitems, list,
345         NULL);
346       for (j = 0; j < data->groups[i]->numMaterials; j++)
347         XmStringFree(list[j]);
348       XtFree((char *) list);
349       data->current = i;
350       return;
351     }
352   }
353 */
354 } // paletteMenuCallback()
355 
356 /*!
357   \internal
358   FIXME: write doc
359 */
360 
361 void
palette_menu_cb(QWidget * widget,void * closure,void *)362 SoQtMaterialList::palette_menu_cb(// static, private
363   QWidget * widget,
364   void * closure,
365   void *)
366 {
367   assert(closure != NULL);
368   SoQtMaterialList * component = (SoQtMaterialList *) closure;
369   component->paletteMenuCallback(widget);
370 } /* palette_menu_cb */
371 
372 // *************************************************************************
373 
374 /*!
375   This method builds the pulldown menu.
376   The current implementation demands that the \a parent argument should be
377   the menubar RowColumn widget - only the "Palettes" menubar button and the
378   pulldown menu is built by this method.
379 */
380 
381 QWidget *
buildPulldownMenu(QWidget * parent)382 SoQtMaterialList::buildPulldownMenu(// protected
383   QWidget * parent)
384 {
385 /*
386   QWidget * palettes = XtVaCreateManagedWidget("palettes",
387     xmCascadeButtonGadgetClass, parent,
388     XtVaTypedArg,
389       XmNlabelString, XmRString,
390       "Palettes", sizeof("Palettes") + 1,
391     NULL);
392 
393   QWidget * shell = SoQt::getShellWidget(parent);
394   assert(shell != (Widget) NULL);
395 
396   Visual * visual;
397   Colormap colormap;
398   int depth;
399 
400   XtVaGetValues(shell,
401     XmNvisual, &visual,
402     XmNcolormap, &colormap,
403     XmNdepth, &depth,
404     NULL);
405 
406   QWidget * menu =
407     XmVaCreateSimplePulldownMenu(parent, "materialsmenu", 0, NULL, NULL);
408 
409   SoQtMaterialDirectory * data = common->getMaterialDirectory();
410   for (int i = 0; i < data->numGroups; i++) {
411     QWidget * item;
412     item = XtVaCreateManagedWidget(data->groups[i]->name,
413              xmPushButtonGadgetClass, menu,
414              XtVaTypedArg,
415                XmNlabelString, XmRString,
416                data->groups[i]->name, strlen(data->groups[i]->name) + 1,
417              NULL);
418     data->groups[i]->menuitem = item;
419     XtAddCallback(item, XmNactivateCallback,
420       SoQtMaterialList::palette_menu_cb, (void *) this);
421   }
422 
423   return palettes;
424 */
425   return NULL;
426 } // buildPulldownMenu()
427 
428 // *************************************************************************
429