# HG changeset patch # User Santeri Piippo # Date 1366844065 -10800 # Node ID 13db97be14cbc72b44694b34f412eeedf0ca33c6 # Parent c243df39913e622f0ac1f9db9a5f26b9fc308a4c Converted combo boxes in add object and new part dialogs to radio buttons. Added a convenience widget which makes it easier for me to add groups of radio buttons. My first widget.. :') diff -r c243df39913e -r 13db97be14cb buttonbox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/buttonbox.h Thu Apr 25 01:54:25 2013 +0300 @@ -0,0 +1,161 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 Santeri Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BUTTONBOX_H +#define BUTTONBOX_H + +#include "common.h" +#include +#include +#include +#include + +// ============================================================================= +// ButtonBox +// +// Convenience widget - is a groupbox of buttons. Mainly useful for quick creation +// of radio button groups. +// ============================================================================= +template class ButtonBox : public QGroupBox { +private: + std::vector objects; + std::vector layouts; + QBoxLayout* coreLayout; + QBoxLayout* currentLayout; + QBoxLayout::Direction dir; + int currentId; + int defaultId; + +public: + QButtonGroup* buttonGroup; + + QBoxLayout::Direction makeDirection (Qt::Orientation orient, bool invert = false) { + return (orient == (invert ? Qt::Vertical : Qt::Horizontal)) ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom; + } + + void init (Qt::Orientation orient) { + dir = makeDirection (orient); + + buttonGroup = new QButtonGroup; + currentId = 0; + coreLayout = null; + + // Ensure we have buttons and not lists or timers or cows or + // anything like that. + R* test = new R; + assert (test->inherits ("QAbstractButton")); + delete test; + + coreLayout = new QBoxLayout (makeDirection (orient, true)); + setLayout (coreLayout); + + // Init the first row with a break + rowBreak (); + } + + explicit ButtonBox (QWidget* parent = null) : QGroupBox (parent) { + init (Qt::Vertical); + } + + explicit ButtonBox (const QString& title, QWidget* parent = null) : QGroupBox (title, parent) { + init (Qt::Vertical); + } + + explicit ButtonBox (const QGroupBox& box) : QGroupBox (box) { + init (Qt::Vertical); + } + + explicit ButtonBox (const QString& title, initlist entries, int const defaultId, + const Qt::Orientation orient = Qt::Vertical, QWidget* parent = null) : + QGroupBox (title, parent), defaultId (defaultId) + { + init (orient); + + for (char const* entry : entries) { + addButton (entry); + } + } + + void rowBreak () { + QBoxLayout* newLayout = new QBoxLayout (dir); + currentLayout = newLayout; + layouts.push_back (newLayout); + + coreLayout->addLayout (newLayout); + } + + void setCurrentRow (uint row) { + currentLayout = layouts[row]; + } + + void addButton (const char* entry) { + R* button = new R (entry); + addButton (button); + } + + void addButton (R* button) { + bool const selectThis = (currentId == defaultId); + + objects.push_back (button); + buttonGroup->addButton (button, currentId++); + currentLayout->addWidget (button); + + if (selectThis) + button->setChecked (true); + } + + ButtonBox& operator<< (R* button) { + addButton (button); + return *this; + } + + ButtonBox& operator<< (const char* entry) { + addButton (entry); + return *this; + } + + int value () { + return buttonGroup->checkedId (); + } + + R* const& begin () { + return objects.begin (); + } + + R* const& end () { + return objects.end (); + } + + R* operator[] (uint n) const { + return objects[n]; + } + + bool exclusive () const { + return buttonGroup->exclusive (); + } + + void setExclusive (bool val) { + buttonGroup->setExclusive (val); + } + + bool isChecked (uint n) { + return objects[n]->checked (); + } +}; + +#endif // BUTTONBOX_H \ No newline at end of file diff -r c243df39913e -r 13db97be14cb gui.h --- a/gui.h Wed Apr 24 23:27:36 2013 +0300 +++ b/gui.h Thu Apr 25 01:54:25 2013 +0300 @@ -27,6 +27,7 @@ #include #include #include +#include #include "gldraw.h" #include "config.h" diff -r c243df39913e -r 13db97be14cb ldforge.pro --- a/ldforge.pro Wed Apr 24 23:27:36 2013 +0300 +++ b/ldforge.pro Thu Apr 25 01:54:25 2013 +0300 @@ -11,6 +11,7 @@ # Input HEADERS += bbox.h \ + buttonbox.h \ colors.h \ common.h \ config.h \ diff -r c243df39913e -r 13db97be14cb zz_addObjectDialog.cpp --- a/zz_addObjectDialog.cpp Wed Apr 24 23:27:36 2013 +0300 +++ b/zz_addObjectDialog.cpp Thu Apr 25 01:54:25 2013 +0300 @@ -17,6 +17,8 @@ */ #include +#include +#include #include "gui.h" #include "zz_addObjectDialog.h" #include "file.h" @@ -72,15 +74,18 @@ lb_radSegments = new QLabel ("Segments:"); lb_radRingNum = new QLabel ("Ring number:"); - qRadialType = new QComboBox; - - for (int i = 0; i < LDRadial::NumTypes; ++i) - qRadialType->addItem (LDRadial::radialTypeName ((LDRadial::Type) i)); + bb_radType = new ButtonBox ("Type", {}, 0, Qt::Vertical); - connect (qRadialType, SIGNAL (currentIndexChanged (int)), this, SLOT (slot_radialTypeChanged (int))); + for (int i = 0; i < LDRadial::NumTypes; ++i) { + bb_radType->addButton (new QRadioButton (LDRadial::radialTypeName ((LDRadial::Type) i))); + + if (i % (LDRadial::NumTypes / 2) == ((LDRadial::NumTypes / 2) - 1)) + bb_radType->rowBreak (); + } - qRadialResolution = new QComboBox; - qRadialResolution->addItems ({"Normal (16)", "Hi-Res (48)"}); + connect (bb_radType->buttonGroup, SIGNAL (buttonPressed (int)), this, SLOT (slot_radialTypeChanged (int))); + + cb_radHiRes = new QCheckBox ("Hi-Res"); sb_radSegments = new QSpinBox; sb_radSegments->setMinimum (1); @@ -135,14 +140,12 @@ break; case OBJ_Radial: - qLayout->addWidget (lb_radType, 1, 1); - qLayout->addWidget (qRadialType, 1, 2); - qLayout->addWidget (lb_radResolution, 2, 1); - qLayout->addWidget (qRadialResolution, 2, 2); - qLayout->addWidget (lb_radSegments, 3, 1); - qLayout->addWidget (sb_radSegments, 3, 2); - qLayout->addWidget (lb_radRingNum, 4, 1); - qLayout->addWidget (sb_radRingNum, 4, 2); + qLayout->addWidget (bb_radType, 1, 1, 3, 1); + qLayout->addWidget (cb_radHiRes, 1, 2); + qLayout->addWidget (lb_radSegments, 2, 2); + qLayout->addWidget (sb_radSegments, 2, 3); + qLayout->addWidget (lb_radRingNum, 3, 2); + qLayout->addWidget (sb_radRingNum, 3, 3); break; default: @@ -158,10 +161,10 @@ for (short i = 0; i < dCoordCount; ++i) qCoordLayout->addWidget (qaCoordinates[i], (i / 3), (i % 3)); - qLayout->addLayout (qCoordLayout, 0, 1, 2, 2); + qLayout->addLayout (qCoordLayout, 0, 1, (dCoordCount / 3), 3); } - qLayout->addWidget (bbx_buttons, 5, 1); + qLayout->addWidget (bbx_buttons, 5, 0, 1, 4); setLayout (qLayout); setWindowTitle (format (APPNAME_DISPLAY " - new %s", g_saObjTypeNames[type]).chars()); @@ -263,9 +266,9 @@ pRad->vPosition.x = dlg.qaCoordinates[0]->value (); pRad->vPosition.y = dlg.qaCoordinates[1]->value (); pRad->vPosition.z = dlg.qaCoordinates[2]->value (); - pRad->dDivisions = (dlg.qRadialResolution->currentIndex () == 0) ? 16 : 48; + pRad->dDivisions = (dlg.cb_radHiRes->checkState () != Qt::Checked) ? 16 : 48; pRad->dSegments = min (dlg.sb_radSegments->value (), pRad->dDivisions); - pRad->eRadialType = (LDRadial::Type) dlg.qRadialType->currentIndex (); + pRad->eRadialType = (LDRadial::Type) dlg.bb_radType->value (); pRad->dRingNum = dlg.sb_radRingNum->value (); pRad->mMatrix = g_mIdentity; diff -r c243df39913e -r 13db97be14cb zz_addObjectDialog.h --- a/zz_addObjectDialog.h Wed Apr 24 23:27:36 2013 +0300 +++ b/zz_addObjectDialog.h Thu Apr 25 01:54:25 2013 +0300 @@ -20,13 +20,14 @@ #define ZZ_ADDOBJECTDIALOG_H #include "gui.h" +#include "buttonbox.h" #include #include #include -#include +#include #include -#include -#include +#include +#include class AddObjectDialog : public QDialog { Q_OBJECT @@ -47,7 +48,8 @@ QPushButton* qColorButton; // Radial stuff - QComboBox* qRadialType, *qRadialResolution; + QCheckBox* cb_radHiRes; + ButtonBox* bb_radType; QSpinBox* sb_radSegments, *sb_radRingNum; QLabel* lb_radType, *lb_radResolution, *lb_radSegments, *lb_radRingNum; diff -r c243df39913e -r 13db97be14cb zz_newPartDialog.cpp --- a/zz_newPartDialog.cpp Wed Apr 24 23:27:36 2013 +0300 +++ b/zz_newPartDialog.cpp Thu Apr 25 01:54:25 2013 +0300 @@ -48,21 +48,21 @@ lb_author = new QLabel ("Author:"); le_author = new QLineEdit; - lb_license = new QLabel ("License:"); - qCB_LicenseBox = new QComboBox; - qCB_LicenseBox->addItems ({ + bb_license = new ButtonBox ("License", { "CCAL Redistributable", "Non-redistributable", - "[none]", - }); + "Don't append a license", + }, LICENSE_CCAL); - lb_BFC = new QLabel ("BFC:"); - qCB_BFCBox = new QComboBox; - qCB_BFCBox->addItems ({ + bb_BFC = new ButtonBox ("BFC Winding", { "CCW", "CW", "No winding" - }); + }, BFCBOX_CCW); + + QHBoxLayout* boxes = new QHBoxLayout; + boxes->addWidget (bb_license); + boxes->addWidget (bb_BFC); IMPLEMENT_DIALOG_BUTTONS @@ -72,11 +72,8 @@ layout->addWidget (le_name, 0, 2); layout->addWidget (lb_author, 1, 1); layout->addWidget (le_author, 1, 2); - layout->addWidget (lb_license, 2, 1); - layout->addWidget (qCB_LicenseBox, 2, 2); - layout->addWidget (lb_BFC, 3, 1); - layout->addWidget (qCB_BFCBox, 3, 2); - layout->addWidget (bbx_buttons, 4, 2); + layout->addLayout (boxes, 2, 1, 1, 2); + layout->addWidget (bbx_buttons, 3, 2); setLayout (layout); setWindowIcon (QIcon ("icons/brick.png")); @@ -95,13 +92,13 @@ str zAuthor = dlg.le_author->text (); vector& objs = g_CurrentFile->objects; - idx = dlg.qCB_BFCBox->currentIndex (); + idx = dlg.bb_BFC->value (); const LDBFC::Type eBFCType = (idx == BFCBOX_CCW) ? LDBFC::CertifyCCW : (idx == BFCBOX_CW) ? LDBFC::CertifyCW : LDBFC::NoCertify; - idx = dlg.qCB_LicenseBox->currentIndex (); + idx = dlg.bb_license->value (); const char* sLicense = (idx == LICENSE_CCAL) ? "Redistributable under CCAL version 2.0 : see CAreadme.txt" : (idx == LICENSE_NonCA) ? "Not redistributable : see NonCAreadme.txt" : diff -r c243df39913e -r 13db97be14cb zz_newPartDialog.h --- a/zz_newPartDialog.h Wed Apr 24 23:27:36 2013 +0300 +++ b/zz_newPartDialog.h Thu Apr 25 01:54:25 2013 +0300 @@ -19,12 +19,15 @@ #ifndef NEWPARTDIALOG_H #define NEWPARTDIALOG_H -#include "gui.h" #include #include #include #include #include +#include +#include +#include "gui.h" +#include "buttonbox.h" class NewPartDialog : public QDialog { public: @@ -33,7 +36,8 @@ QLabel* lb_brickIcon, *lb_name, *lb_author, *lb_license, *lb_BFC; QLineEdit* le_name, *le_author; - QComboBox* qCB_LicenseBox, *qCB_BFCBox; + + ButtonBox* bb_license, *bb_BFC; QDialogButtonBox* bbx_buttons; };