]> Shamusworld >> Repos - architektonas/blobdiff - src/layerwidget.cpp
Whitespace changes. :-P
[architektonas] / src / layerwidget.cpp
index 4a98037685c786312576396dc1a0cf4e34026308..1ab9d79f22ec815e80de126bc84fffe29d7d9a2f 100644 (file)
@@ -1,3 +1,4 @@
+//
 // layerwidget.cpp: Layer add/remove/use widget
 //
 // Part of the Architektonas Project
 //
 
 #include "layerwidget.h"
+#include "global.h"
 #include "layeritemwidget.h"
 
-
-LayerWidget::LayerWidget(void): QWidget()
+LayerWidget::LayerWidget(void): QWidget(),
+       addLayer(new QToolButton), removeLayer(new QToolButton),
+       editLayer(new QToolButton), layerUp(new QToolButton),
+       layerDown(new QToolButton), list(new QListWidget)
 {
-       LayerItemWidget * liw1 = new LayerItemWidget("Background");
-       LayerItemWidget * liw2 = new LayerItemWidget("Guidelines");
-       LayerItemWidget * liw3 = new LayerItemWidget("Floor #1");
-       LayerItemWidget * liw4 = new LayerItemWidget("Mechanical");
-       LayerItemWidget * liw5 = new LayerItemWidget("List Widget");
+       QListWidgetItem * qlwi = new QListWidgetItem(list);
+       LayerItemWidget * liw = new LayerItemWidget("Background", false, false, qlwi);
+       list->setItemWidget(qlwi, liw);
 
-       QListWidget * qlw = new QListWidget;
-       QListWidgetItem * qli1 = new QListWidgetItem(qlw);
-       QListWidgetItem * qli2 = new QListWidgetItem(qlw);
-       QListWidgetItem * qli3 = new QListWidgetItem(qlw);
-       QListWidgetItem * qli4 = new QListWidgetItem(qlw);
-       QListWidgetItem * qli5 = new QListWidgetItem(qlw);
-       qlw->setItemWidget(qli1, liw1);
-       qlw->setItemWidget(qli2, liw2);
-       qlw->setItemWidget(qli3, liw3);
-       qlw->setItemWidget(qli4, liw4);
-       qlw->setItemWidget(qli5, liw5);
+       addLayer->setIcon(QIcon(":/res/layer-add.png"));
+       removeLayer->setIcon(QIcon(":/res/layer-delete.png"));
+       editLayer->setIcon(QIcon(":/res/layer-edit.png"));
+       layerUp->setIcon(QIcon(":/res/layer-up.png"));
+       layerDown->setIcon(QIcon(":/res/layer-down.png"));
 
-       QPushButton * pb1 = new QPushButton("+");
-       QPushButton * pb2 = new QPushButton("-");
+       addLayer->setToolTip(tr("Add layer"));
+       removeLayer->setToolTip(tr("Remove layer"));
+       editLayer->setToolTip(tr("Edit layer"));
+       layerUp->setToolTip(tr("Move layer up"));
+       layerDown->setToolTip(tr("Move layer down"));
 
        QHBoxLayout * hbox1 = new QHBoxLayout;
-       hbox1->addWidget(pb1);
-       hbox1->addWidget(pb2);
+       hbox1->addWidget(addLayer);
+       hbox1->addWidget(removeLayer);
+       hbox1->addWidget(editLayer);
+       hbox1->addWidget(layerUp);
+       hbox1->addWidget(layerDown);
+       hbox1->addStretch();
 
        QVBoxLayout * mainLayout = new QVBoxLayout;
-       mainLayout->addWidget(qlw);
+       mainLayout->addWidget(list);
        mainLayout->addLayout(hbox1);
 
        setLayout(mainLayout);
-}
 
+       connect(list, SIGNAL(currentRowChanged(int)), this, SLOT(HandleLayerSelected(int)));
+       connect(list, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(HandleDblClick(QListWidgetItem *)));
+       connect(addLayer, SIGNAL(clicked()), this, SLOT(AddLayer()));
+       connect(removeLayer, SIGNAL(clicked()), this, SLOT(DeleteLayer()));
+       connect(editLayer, SIGNAL(clicked()), this, SLOT(EditLayer()));
+       connect(layerUp, SIGNAL(clicked()), this, SLOT(MoveLayerUp()));
+       connect(layerDown, SIGNAL(clicked()), this, SLOT(MoveLayerDown()));
+
+       connect(liw, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+       connect(liw, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+
+       list->setCurrentRow(0);
+
+       // We set global variables here, since we are 'in charge' of them (mostly)
+       Global::activeLayer = 0;
+       Global::numLayers = 1;
+       Global::layerHidden.clear();
+       Global::layerLocked.clear();
+       Global::layerName.clear();
+       Global::layerHidden.push_back(false);
+       Global::layerLocked.push_back(false);
+       Global::layerName.push_back("Background");
+}
 
 LayerWidget::~LayerWidget()
 {
 }
 
+void LayerWidget::Reload(void)
+{
+       list->clear();
+
+       for(int i=0; i<Global::numLayers; i++)
+       {
+               QListWidgetItem * qlwi = new QListWidgetItem();
+               LayerItemWidget * liw = new LayerItemWidget(Global::layerName[i].c_str(), Global::layerHidden[i], Global::layerLocked[i], qlwi);
+               list->insertItem(0, qlwi);
+               list->setItemWidget(qlwi, liw);
+
+               // Set up SIGNAL/SLOTs for this LayerItemWidget
+               connect(liw, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+               connect(liw, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+       }
+
+       int layer = (Global::numLayers - Global::activeLayer) - 1;
+       list->setCurrentRow(layer, QItemSelectionModel::SelectCurrent);
+       SetButtonStates();
+}
+
+void LayerWidget::HandleLayerSelected(int currentRow)
+{
+       // If LayerWidget is empty, bail out
+       if (currentRow == -1)
+               return;
+
+       // This is numbered opposite of how it's presented. In other words, the
+       // bottom of the list is 0, and items above it count upwards. So like this:
+       //
+       // (2) Layer #2
+       // (1) Layer #1
+       // (0) Background
+       //
+       // which is the opposite of the internal numbering.
+       Global::activeLayer = (Global::numLayers - currentRow) - 1;
+
+       // Set button states to sane values
+       SetButtonStates();
+}
+
+//
+// What happens here is that for every QListWidgetItem we make, we connect it
+// to these handlers. But we only have to worry about that when adding and
+// moving a layer. However, when toggling states, we need to toggle the global
+// state variables too.
+//
+void LayerWidget::HandleHideToggle(QListWidgetItem * qlwi, bool state)
+{
+       int currentRow = list->row(qlwi);
+       int layer = (Global::numLayers - currentRow) - 1;
+       std::vector<bool>::iterator i = Global::layerHidden.begin() + layer;
+       (*i) = state;
+//printf("Item #%i, new hide state is %s\n", currentRow, (state ? "ON" : "off"));
+//printf("LayerWidget: New hide state of layer %i is %s.\n", layer, (state ? "ON" : "off"));
+       // We do this last, because otherwise the Document would get the wrong state
+       emit LayerToggled();
+}
+
+void LayerWidget::HandleLockToggle(QListWidgetItem * qlwi, bool state)
+{
+       int currentRow = list->row(qlwi);
+       int layer = (Global::numLayers - currentRow) - 1;
+       std::vector<bool>::iterator i = Global::layerLocked.begin() + layer;
+       (*i) = state;
+//     printf("Item #%i, new lock state is %s\n", list->row(qlwi), (state ? "ON" : "off"));
+}
+
+void LayerWidget::HandleDblClick(QListWidgetItem * /*qlwi*/)
+{
+       EditLayer();
+}
+
+void LayerWidget::AddLayer(void)
+{
+       // We always stick the newest layer at the top of the list (visually, the
+       // top of the list is the end, the bottom is the beginning)...
+       int count = list->count();
+       QString text = QString("Layer #%1").arg(count);
+       QListWidgetItem * qlwi = new QListWidgetItem();
+       LayerItemWidget * liw = new LayerItemWidget(text, false, false, qlwi);
+       list->insertItem(0, qlwi);
+       list->setItemWidget(qlwi, liw);
+
+       // Set up SIGNAL/SLOTs for this LayerItemWidget
+       connect(liw, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+       connect(liw, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+
+       SetButtonStates();
+
+       // Fix up the global state
+       Global::layerHidden.push_back(false);
+       Global::layerLocked.push_back(false);
+       Global::layerName.push_back(text.toUtf8().data());
+       Global::numLayers++;
+}
+
+void LayerWidget::DeleteLayer(void)
+{
+       int numItems = list->count();
+
+       if (numItems == 1)
+               return;
+
+       // N.B.: This *must* go before the item removal because that causes
+       //       HandleLayerSelected() to be fired off which causes the numbers to
+       //       be off. You have been warned!
+       // Tell the DrawingView to delete this layer in its Container:
+       emit LayerDeleted(Global::activeLayer);
+
+       int currentRow = list->currentRow();
+       QListWidgetItem * qlwi = list->currentItem();
+       list->removeItemWidget(qlwi);
+       delete qlwi;
+
+       SetButtonStates();
+
+       // Fix up the global state
+       int layer = (Global::numLayers - currentRow) - 1;
+       Global::layerHidden.erase(Global::layerHidden.begin() + layer);
+       Global::layerLocked.erase(Global::layerLocked.begin() + layer);
+       Global::layerName.erase(Global::layerName.begin() + layer);
+       Global::numLayers--;
+
+       // If we're deleting from the top of the list, we have to decrement the
+       // active layer # by 1 (since we count upward from the bottom of the list).
+       if (currentRow == 0)
+               Global::activeLayer--;
+}
+
+void LayerWidget::EditLayer(void)
+{
+       // Get the LayerItemWidget so we can edit it (its name, anyway)...
+       QListWidgetItem * qlwi = list->currentItem();
+       LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+       QString s = li->name->text();
+
+       bool ok;
+       QString result = QInputDialog::getText(this, tr("Edit Layer Name"), tr("Layer Name:"), QLineEdit::Normal, s, &ok);
+
+       if (ok && !result.isEmpty())
+       {
+               li->name->setText(result);
+
+               // We don't reverse the layer # here, like elsewhere, because we're
+               // using the layer # directly instead of having to translate it from
+               // the widget.
+               std::vector<std::string>::iterator i = Global::layerName.begin() + Global::activeLayer;
+               (*i) = result.toUtf8().data();
+       }
+}
+
+void LayerWidget::MoveLayerUp(void)
+{
+       // Get information out of the LayerItemWidget (& get it from the list!)
+       int currentRow = list->currentRow();
+       QListWidgetItem * qlwi = list->currentItem();
+       LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+       QString s = li->name->text();
+       bool visible = li->invisible->isChecked();
+       bool editible = li->locked->isChecked();
+
+       // We have to make a new LayerItemWidget because it destroys the old one!
+       list->takeItem(currentRow);
+       list->insertItem(currentRow - 1, qlwi);
+       li = new LayerItemWidget(s, visible, editible, qlwi);
+       list->setItemWidget(qlwi, li);
+       list->setCurrentItem(qlwi);
+
+       // Set up SIGNAL/SLOTs for this LayerItemWidget
+       connect(li, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+       connect(li, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+
+       // Fix up the global state...
+       // N.B.: Because we handle the button states correctly, we should never
+       //       have a situation where the reference in the vector is bad.
+       int layer = (Global::numLayers - currentRow) - 1;
+       bool old = Global::layerHidden[layer];
+       Global::layerHidden[layer] = Global::layerHidden[layer + 1];
+       Global::layerHidden[layer + 1] = old;
+       old = Global::layerLocked[layer];
+       Global::layerLocked[layer] = Global::layerLocked[layer + 1];
+       Global::layerLocked[layer + 1] = old;
+       std::string oldStr = Global::layerName[layer];
+       Global::layerName[layer] = Global::layerName[layer + 1];
+       Global::layerName[layer + 1] = oldStr;
+       // We also have to tell the document to shuffle its layers too
+       emit LayersSwapped(layer, layer + 1);
+}
+
+void LayerWidget::MoveLayerDown(void)
+{
+       // Get information out of the LayerItemWidget (& get it from the list!)
+       int currentRow = list->currentRow();
+       QListWidgetItem * qlwi = list->currentItem();
+       LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+       QString s = li->name->text();
+       bool visible = li->invisible->isChecked();
+       bool editible = li->locked->isChecked();
+
+       // We have to make a new LayerItemWidget because it destroys the old one!
+       list->takeItem(currentRow);
+       list->insertItem(currentRow + 1, qlwi);
+       li = new LayerItemWidget(s, visible, editible, qlwi);
+       list->setItemWidget(qlwi, li);
+       list->setCurrentItem(qlwi);
+
+       // Set up SIGNAL/SLOTs for this LayerItemWidget
+       connect(li, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+       connect(li, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+
+       // Fix up the global state...
+       // N.B.: Because we handle the button states correctly, we should never
+       //       have a situation where the reference in the vector is bad.
+       int layer = (Global::numLayers - currentRow) - 1;
+       bool old = Global::layerHidden[layer];
+       Global::layerHidden[layer] = Global::layerHidden[layer - 1];
+       Global::layerHidden[layer - 1] = old;
+       old = Global::layerLocked[layer];
+       Global::layerLocked[layer] = Global::layerLocked[layer - 1];
+       Global::layerLocked[layer - 1] = old;
+       std::string oldStr = Global::layerName[layer];
+       Global::layerName[layer] = Global::layerName[layer - 1];
+       Global::layerName[layer - 1] = oldStr;
+       // We also have to tell the document to shuffle its layers too
+       emit LayersSwapped(layer, layer - 1);
+}
+
+//
+// Set button states in this widget to sane values
+//
+void LayerWidget::SetButtonStates(void)
+{
+       int numItems = list->count();
+       int currentRow = list->currentRow();
+
+       layerDown->setEnabled(currentRow == (numItems - 1) ? false : true);
+       layerUp->setEnabled(currentRow == 0 ? false : true);
+       removeLayer->setEnabled(numItems == 1 ? false : true);
+}