]> git.cworth.org Git - vogl/blob - src/vogleditor/vogleditor_statetreeitem.cpp
Initial vogl checkin
[vogl] / src / vogleditor / vogleditor_statetreeitem.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #include "vogleditor_statetreeitem.h"
27 #include "vogleditor_qstatetreemodel.h"
28
29 //=============================================================================
30
31 vogleditor_stateTreeItem::vogleditor_stateTreeItem(QList<QVariant> columnTitles, vogleditor_QStateTreeModel* pModel)
32  : m_columnData(columnTitles),
33    m_parentItem(NULL),
34    m_pModel(pModel),
35    m_bWasEdited(false)
36 {
37 }
38
39 vogleditor_stateTreeItem::vogleditor_stateTreeItem(QString name, QString value, vogleditor_stateTreeItem* parent)
40  : m_parentItem(parent),
41    m_pModel(NULL)
42 {
43    m_columnData << name;
44    m_columnData << value;
45
46    if (m_parentItem != NULL)
47    {
48       m_pModel = m_parentItem->m_pModel;
49    }
50 }
51
52 vogleditor_stateTreeItem::~vogleditor_stateTreeItem()
53 {
54    for (int i = 0; i < m_childItems.size(); i++)
55    {
56       delete m_childItems[i];
57       m_childItems[i] = NULL;
58    }
59
60    m_childItems.clear();
61 }
62
63 vogleditor_stateTreeItem* vogleditor_stateTreeItem::parent() const
64 {
65    return m_parentItem;
66 }
67
68 void vogleditor_stateTreeItem::setValue(QString value)
69 {
70     if (m_columnData.size() >= 2)
71     {
72         m_columnData.removeAt(1);
73         m_columnData.insert(1, value);
74     }
75 }
76
77 QString vogleditor_stateTreeItem::getValueFromBools(const bool* values, uint count) const
78 {
79     if (count == 0 || values == NULL)
80     {
81         return "";
82     }
83     else if (count == 1)
84     {
85         return (values[0]) ? "GL_TRUE" : "GL_FALSE";
86     }
87
88     QString tmp;
89     tmp = tmp.sprintf("%s, %s", getValueFromBools(values, 1).toStdString().c_str(), getValueFromBools(&(values[1]), count-1).toStdString().c_str());
90     return tmp;
91 }
92
93 QString vogleditor_stateTreeItem::getValueFromInts(const int* values, uint count) const
94 {
95     QString tmp;
96     if (count == 0 || values == NULL)
97     {
98         return "";
99     }
100     else if (count == 1)
101     {
102         tmp = tmp.sprintf("%d", *values);
103     }
104     else
105     {
106         tmp = tmp.sprintf("%s, %s", getValueFromInts(values, 1).toStdString().c_str(), getValueFromInts(&(values[1]), count-1).toStdString().c_str());
107     }
108
109     return tmp;
110 }
111
112 QString vogleditor_stateTreeItem::getValueFromUints(const uint* values, uint count) const
113 {
114     QString tmp;
115     if (count == 0 || values == NULL)
116     {
117         return "";
118     }
119     else if (count == 1)
120     {
121         tmp = tmp.sprintf("%d", *values);
122     }
123     else
124     {
125         tmp = tmp.sprintf("%s, %s", getValueFromUints(values, 1).toStdString().c_str(), getValueFromUints(&(values[1]), count-1).toStdString().c_str());
126     }
127
128     return tmp;
129 }
130
131 QString vogleditor_stateTreeItem::getValueFromFloats(const float* values, uint count) const
132 {
133     QString tmp;
134     if (count == 0 || values == NULL)
135     {
136         return "";
137     }
138     else if (count == 1)
139     {
140         tmp = tmp.sprintf("%f", *values);
141     }
142     else
143     {
144         tmp = tmp.sprintf("%s, %s", getValueFromFloats(values, 1).toStdString().c_str(), getValueFromFloats(&(values[1]), count-1).toStdString().c_str());
145     }
146
147     return tmp;
148 }
149
150 QString vogleditor_stateTreeItem::getValueFromDoubles(const double* values, uint count) const
151 {
152     QString tmp;
153     if (count == 0 || values == NULL)
154     {
155         return "";
156     }
157     else if (count == 1)
158     {
159         tmp = tmp.sprintf("%f", *values);
160     }
161     else
162     {
163         tmp = tmp.sprintf("%s, %s", getValueFromDoubles(values, 1).toStdString().c_str(), getValueFromDoubles(&(values[1]), count-1).toStdString().c_str());
164     }
165
166     return tmp;
167 }
168
169 QString vogleditor_stateTreeItem::getValueFromEnums(const int* values, uint count) const
170 {
171     QString tmp;
172     if (count == 0 || values == NULL)
173     {
174         return "";
175     }
176     else if (count == 1)
177     {
178         tmp = enum_to_string(*values);
179     }
180     else
181     {
182         tmp = tmp.sprintf("%s, %s", getValueFromEnums(values, 1).toStdString().c_str(), getValueFromEnums(&(values[1]), count-1).toStdString().c_str());
183     }
184
185     return tmp;
186 }
187
188 QString vogleditor_stateTreeItem::getValueFromPtrs(const int* values, uint count) const
189 {
190     QString tmp;
191     if (count == 0 || values == NULL)
192     {
193         return "";
194     }
195     else if (count == 1)
196     {
197         tmp = tmp.sprintf("%p", (void*)(*values));
198     }
199     else
200     {
201         tmp = tmp.sprintf("%s, %s", getValueFromPtrs(values, 1).toStdString().c_str(), getValueFromPtrs(&(values[1]), count-1).toStdString().c_str());
202     }
203
204     return tmp;
205 }
206
207 void vogleditor_stateTreeItem::appendChild(vogleditor_stateTreeItem* pChild)
208 {
209    m_childItems.append(pChild);
210 }
211
212 int vogleditor_stateTreeItem::childCount() const
213 {
214    return m_childItems.size();
215 }
216
217 vogleditor_stateTreeItem* vogleditor_stateTreeItem::child(int index) const
218 {
219    if (index < 0 || index >= childCount())
220    {
221       return NULL;
222    }
223
224    return m_childItems[index];
225 }
226
227 int vogleditor_stateTreeItem::columnCount() const
228 {
229    int count = 0;
230    if (m_parentItem == NULL)
231    {
232       // this must be the root node
233       count = m_columnData.size();
234    }
235    else
236    {
237       m_pModel->columnCount();
238    }
239
240    return count;
241 }
242
243 QVariant vogleditor_stateTreeItem::columnData(int column, int role) const
244 {
245    if (column >= m_columnData.size())
246    {
247       return QVariant();
248    }
249
250    if (role == Qt::ForegroundRole && parent() != NULL && hasChanged())
251    {
252        return QVariant(Qt::red);
253    }
254
255    if (role == Qt::ToolTipRole)
256    {
257        if (hasChanged())
258        {
259            QString prevValue = getDiffedValue();
260            if (prevValue.isEmpty())
261                return "";
262            else
263                return "Previous value was: " + prevValue;
264        }
265    }
266
267    // catch any other roles that we don't specifically handle
268    if (role != Qt::DisplayRole)
269    {
270        return QVariant();
271    }
272
273    // return the data since the only role left is the DisplayRole
274    return m_columnData[column];
275 }
276
277 int vogleditor_stateTreeItem::row() const
278 {
279    // note, this is just the row within the current level of the hierarchy
280    if (m_parentItem)
281       return m_parentItem->m_childItems.indexOf(const_cast<vogleditor_stateTreeItem*>(this));
282
283    return 0;
284 }
285
286 bool vogleditor_stateTreeItem::hasChanged() const
287 {
288     for (int i = 0; i < m_childItems.size(); i++)
289     {
290         if (m_childItems[i]->hasChanged())
291         {
292             return true;
293         }
294     }
295
296     return false;
297 }
298
299 //=============================================================================
300
301 template <typename T> vogleditor_stateTreeDatatypeItem<T>::vogleditor_stateTreeDatatypeItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, unsigned int numComponents, bool isIndexed, vogleditor_stateTreeItem* parent)
302     : vogleditor_stateTreeStateVecDiffableItem(glenumName, "", parent),
303       m_name(name),
304       m_index(index),
305       m_numComponents(numComponents),
306       m_isIndexed(isIndexed),
307       m_pStateVec(&stateVec)
308 {
309 }
310
311 template <typename T> bool vogleditor_stateTreeDatatypeItem<T>::hasChanged() const
312 {
313    if (m_pDiffBaseState == NULL)
314        return false;
315
316    static T baseValues[4];
317    static T curValues[4];
318    VOGL_ASSERT(m_numComponents <= 4);
319
320    bool bFoundInBase = m_pDiffBaseState->get<T>(m_name, m_index, baseValues, m_numComponents, m_isIndexed);
321    bool bFoundInCurrent = m_pStateVec->get<T>(m_name, m_index, curValues, m_numComponents, m_isIndexed);
322
323    if (bFoundInBase && bFoundInCurrent)
324    {
325        for (unsigned int i = 0; i < m_numComponents; i++)
326        {
327            if (baseValues[i] != curValues[i])
328            {
329                // one of the values has changed, so return early
330                return true;
331            }
332        }
333    }
334
335    if (bFoundInCurrent && !bFoundInBase)
336    {
337        // the enum must have been added, so it is different
338        return true;
339    }
340
341    return false;
342 }
343
344 template <typename T> QString vogleditor_stateTreeDatatypeItem<T>::getDiffedValue() const
345 {
346     static T baseValues[4];
347     VOGL_ASSERT(m_numComponents <= 4);
348
349     bool bFoundInBase = m_pDiffBaseState->get<T>(m_name, m_index, baseValues, m_numComponents, m_isIndexed);
350
351     QString result = "";
352     if (bFoundInBase)
353     {
354         result = "TODO: An actual diff'ed value";
355     }
356
357     return result;
358 }
359
360
361 //=============================================================================
362 vogleditor_stateTreeStateVecBoolItem::vogleditor_stateTreeStateVecBoolItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, bool* values, unsigned int numComponents, bool isIndexed, vogleditor_stateTreeItem* parent)
363    : vogleditor_stateTreeDatatypeItem<bool>(glenumName, name, index, stateVec, numComponents, isIndexed, parent)
364 {
365     setValue(getValueFromBools(values, numComponents));
366 }
367
368 vogleditor_stateTreeStateVecBoolItem::vogleditor_stateTreeStateVecBoolItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, int* values, unsigned int numComponents, bool isIndexed, vogleditor_stateTreeItem* parent)
369    : vogleditor_stateTreeDatatypeItem<bool>(glenumName, name, index, stateVec, numComponents, isIndexed, parent)
370 {
371     bool bVals[4] = {values[0] != 0, values[1] != 0, values[2] != 0, values[3] != 0 };
372     setValue(getValueFromBools(bVals, numComponents));
373 }
374
375 QString vogleditor_stateTreeStateVecBoolItem::getDiffedValue() const
376 {
377     static bool baseValues[4];
378     VOGL_ASSERT(m_numComponents <= 4);
379
380     QString result = "";
381     if (m_pDiffBaseState->get<bool>(m_name, m_index, baseValues, m_numComponents, m_isIndexed))
382     {
383         result = getValueFromBools(baseValues, m_numComponents);
384     }
385
386     return result;
387 }
388
389 //=============================================================================
390
391 vogleditor_stateTreeStateVecIntItem::vogleditor_stateTreeStateVecIntItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, int* values, unsigned int numComponents, bool isIndexed, vogleditor_stateTreeItem* parent)
392    : vogleditor_stateTreeDatatypeItem<int>(glenumName, name, index, stateVec, numComponents, isIndexed, parent)
393 {
394     setValue(getValueFromInts(values, numComponents));
395 }
396
397 QString vogleditor_stateTreeStateVecIntItem::getDiffedValue() const
398 {
399     static int baseValues[4];
400     VOGL_ASSERT(m_numComponents <= 4);
401
402     QString result = "";
403     if (m_pDiffBaseState->get<int>(m_name, m_index, baseValues, m_numComponents, m_isIndexed))
404     {
405         result = getValueFromInts(baseValues, m_numComponents);
406     }
407
408     return result;
409 }
410
411 //=============================================================================
412
413 vogleditor_stateTreeStateVecPtrItem::vogleditor_stateTreeStateVecPtrItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, int* values, unsigned int numComponents, bool isIndexed, vogleditor_stateTreeItem* parent)
414    : vogleditor_stateTreeDatatypeItem<int>(glenumName, name, index, stateVec, numComponents, isIndexed, parent)
415 {
416     setValue(getValueFromPtrs(values, numComponents));
417 }
418
419 QString vogleditor_stateTreeStateVecPtrItem::getDiffedValue() const
420 {
421     static int baseValues[4];
422     VOGL_ASSERT(m_numComponents <= 4);
423
424     QString result = "";
425     if (m_pDiffBaseState->get<int>(m_name, m_index, baseValues, m_numComponents, m_isIndexed))
426     {
427         result = getValueFromPtrs(baseValues, m_numComponents);
428     }
429
430     return result;
431 }
432
433 //=============================================================================
434
435 vogleditor_stateTreeStateVecFloatItem::vogleditor_stateTreeStateVecFloatItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, float* values, unsigned int numComponents, bool isIndexed, vogleditor_stateTreeItem* parent)
436    : vogleditor_stateTreeDatatypeItem<float>(glenumName, name, index, stateVec, numComponents, isIndexed, parent)
437 {
438     setValue(getValueFromFloats(values, numComponents));
439 }
440
441 QString vogleditor_stateTreeStateVecFloatItem::getDiffedValue() const
442 {
443     static float baseValues[4];
444     VOGL_ASSERT(m_numComponents <= 4);
445
446     QString result = "";
447     if (m_pDiffBaseState->get<float>(m_name, m_index, baseValues, m_numComponents, m_isIndexed))
448     {
449         result = getValueFromFloats(baseValues, m_numComponents);
450     }
451
452     return result;
453 }
454
455 //=============================================================================
456
457 vogleditor_stateTreeStateVecEnumItem::vogleditor_stateTreeStateVecEnumItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, int* values, unsigned int numComponents, bool isIndexed, vogleditor_stateTreeItem* parent)
458    : vogleditor_stateTreeDatatypeItem<int>(glenumName, name, index, stateVec, numComponents, isIndexed, parent)
459 {
460     setValue(getValueFromEnums(values, numComponents));
461 }
462
463 QString vogleditor_stateTreeStateVecEnumItem::getDiffedValue() const
464 {
465     static int baseValues[4];
466     VOGL_ASSERT(m_numComponents <= 4);
467
468     QString result = "";
469     if (m_pDiffBaseState->get<int>(m_name, m_index, baseValues, m_numComponents, m_isIndexed))
470     {
471         result = getValueFromEnums(baseValues, m_numComponents);
472     }
473
474     return result;
475 }
476
477 //=============================================================================
478
479 vogleditor_stateTreeStateVecMatrixRowItem::vogleditor_stateTreeStateVecMatrixRowItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, float* values, unsigned int numComponents, unsigned int rowIndex, bool isIndexed, vogleditor_stateTreeItem* parent)
480     : vogleditor_stateTreeStateVecDiffableItem(glenumName, "", parent),
481       m_name(name),
482       m_index(index),
483       m_numComponents(numComponents),
484       m_isIndexed(isIndexed),
485       m_pState(&stateVec),
486       m_rowIndex(rowIndex)
487 {
488     setValue(getValueFromFloats(values, 4));
489 }
490
491 bool vogleditor_stateTreeStateVecMatrixRowItem::hasChanged() const
492 {
493     if (m_pDiffBaseState == NULL)
494     {
495         return false;
496     }
497
498     static float baseValues[16];
499     static float curValues[16];
500     VOGL_ASSERT(m_numComponents <= 16);
501
502     if (m_pDiffBaseState->get<float>(m_name, m_index, baseValues, m_numComponents, m_isIndexed) &&
503         m_pState->get<float>(m_name, m_index, curValues, m_numComponents, m_isIndexed))
504     {
505         for(unsigned int i = 0; i < 4; i++)
506         {
507             if (baseValues[i + (m_rowIndex*4)] != curValues[i + (m_rowIndex*4)])
508             {
509                 // one of the values has changed, so return early
510                 return true;
511             }
512         }
513     }
514     else
515     {
516         // the enum must have been added, so it is different
517         return true;
518     }
519     return false;
520 }
521
522 QString vogleditor_stateTreeStateVecMatrixRowItem::getDiffedValue() const
523 {
524     static float baseValues[16];
525     VOGL_ASSERT(m_numComponents <= 16);
526
527     QString result = "";
528     if (m_pDiffBaseState->get<float>(m_name, m_index, baseValues, m_numComponents, m_isIndexed))
529     {
530         result = getValueFromFloats(&(baseValues[m_rowIndex*4]), 4);
531     }
532
533     return result;
534 }
535
536 vogleditor_stateTreeStateVecMatrixItem::vogleditor_stateTreeStateVecMatrixItem(QString glenumName, GLenum name, unsigned int index, const vogl_state_vector& stateVec, float* values, unsigned int numComponents, bool isIndexed, vogleditor_stateTreeItem* parent)
537     : vogleditor_stateTreeStateVecDiffableItem(glenumName, "", parent),
538       m_pState(&stateVec)
539 {
540     vogleditor_stateTreeStateVecMatrixRowItem* pRow1 = new vogleditor_stateTreeStateVecMatrixRowItem("row 0", name, index, stateVec, &(values[0]), numComponents, 0, isIndexed, this); m_rowItems.push_back(pRow1); this->appendChild(pRow1);
541     vogleditor_stateTreeStateVecMatrixRowItem* pRow2 = new vogleditor_stateTreeStateVecMatrixRowItem("row 1", name, index, stateVec, &(values[4]), numComponents, 1, isIndexed, this); m_rowItems.push_back(pRow2); this->appendChild(pRow2);
542     vogleditor_stateTreeStateVecMatrixRowItem* pRow3 = new vogleditor_stateTreeStateVecMatrixRowItem("row 2", name, index, stateVec, &(values[8]), numComponents, 2, isIndexed, this); m_rowItems.push_back(pRow3); this->appendChild(pRow3);
543     vogleditor_stateTreeStateVecMatrixRowItem* pRow4 = new vogleditor_stateTreeStateVecMatrixRowItem("row 3", name, index, stateVec, &(values[12]), numComponents, 3, isIndexed, this); m_rowItems.push_back(pRow4); this->appendChild(pRow4);
544 }