X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flayerwidget.cpp;h=1ab9d79f22ec815e80de126bc84fffe29d7d9a2f;hb=92b64dc831492f1d6311a8baece66408f7659f67;hp=adc717e7e1c63860a9cc2dfdd3ca8f8229ef1cc6;hpb=642cf72c11b49a9e00128ab6258a2438c785a5ab;p=architektonas diff --git a/src/layerwidget.cpp b/src/layerwidget.cpp index adc717e..1ab9d79 100644 --- a/src/layerwidget.cpp +++ b/src/layerwidget.cpp @@ -1,3 +1,4 @@ +// // layerwidget.cpp: Layer add/remove/use widget // // Part of the Architektonas Project @@ -12,56 +13,36 @@ // #include "layerwidget.h" +#include "global.h" #include "layeritemwidget.h" - LayerWidget::LayerWidget(void): QWidget(), - list(new QListWidget) + addLayer(new QToolButton), removeLayer(new QToolButton), + editLayer(new QToolButton), layerUp(new QToolButton), + layerDown(new QToolButton), list(new QListWidget) { - LayerItemWidget * liw1 = new LayerItemWidget("Guidelines"); - LayerItemWidget * liw2 = new LayerItemWidget("Floor #1"); - LayerItemWidget * liw3 = new LayerItemWidget("Mechanical"); - LayerItemWidget * liw4 = new LayerItemWidget("List Widget"); - LayerItemWidget * liw5 = new LayerItemWidget("Background"); - -// QListWidget * qlw = new QListWidget; - QListWidgetItem * qli1 = new QListWidgetItem(list); - QListWidgetItem * qli2 = new QListWidgetItem(list); - QListWidgetItem * qli3 = new QListWidgetItem(list); - QListWidgetItem * qli4 = new QListWidgetItem(list); - QListWidgetItem * qli5 = new QListWidgetItem(list); - list->setItemWidget(qli1, liw1); - list->setItemWidget(qli2, liw2); - list->setItemWidget(qli3, liw3); - list->setItemWidget(qli4, liw4); - list->setItemWidget(qli5, liw5); - -#if 0 - QPushButton * pb1 = new QPushButton("+"); - QPushButton * pb2 = new QPushButton("-"); - QPushButton * pb3 = new QPushButton("Edit"); - QPushButton * pb4 = new QPushButton("^"); - QPushButton * pb5 = new QPushButton("v"); -#else - QToolButton * pb1 = new QToolButton; - QToolButton * pb2 = new QToolButton; - QToolButton * pb3 = new QToolButton; - QToolButton * pb4 = new QToolButton; - QToolButton * pb5 = new QToolButton; - - pb1->setIcon(QIcon(":/res/generic-tool.png")); - pb2->setIcon(QIcon(":/res/generic-tool.png")); - pb3->setIcon(QIcon(":/res/generic-tool.png")); - pb4->setIcon(QIcon(":/res/generic-tool.png")); - pb5->setIcon(QIcon(":/res/generic-tool.png")); -#endif + QListWidgetItem * qlwi = new QListWidgetItem(list); + LayerItemWidget * liw = new LayerItemWidget("Background", false, false, qlwi); + list->setItemWidget(qlwi, liw); + + 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")); + + 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(pb3); - hbox1->addWidget(pb4); - hbox1->addWidget(pb5); + hbox1->addWidget(addLayer); + hbox1->addWidget(removeLayer); + hbox1->addWidget(editLayer); + hbox1->addWidget(layerUp); + hbox1->addWidget(layerDown); hbox1->addStretch(); QVBoxLayout * mainLayout = new QVBoxLayout; @@ -71,54 +52,270 @@ LayerWidget::LayerWidget(void): QWidget(), setLayout(mainLayout); connect(list, SIGNAL(currentRowChanged(int)), this, SLOT(HandleLayerSelected(int))); - list->setCurrentRow(4); - connect(pb1, SIGNAL(clicked()), this, SLOT(AddLayer())); - connect(pb2, SIGNAL(clicked()), this, SLOT(DeleteLayer())); - connect(pb3, SIGNAL(clicked()), this, SLOT(EditLayer())); - connect(pb4, SIGNAL(clicked()), this, SLOT(MoveLayerUp())); - connect(pb5, SIGNAL(clicked()), this, SLOT(MoveLayerDown())); -} + 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; iinsertItem(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) { -//printf("LayerWidget::HandleLayerSelected(): currentRow = %i\n", currentRow); - emit(LayerSelected(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::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::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); - LayerItemWidget * liw = new LayerItemWidget(text); 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::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); +}