Browse Source

Support 'mirror' connection editing. Can be toggled off via checkbox

Marcus Huderle 6 years ago
parent
commit
1a10eac29f
5 changed files with 133 additions and 9 deletions
  1. 89
    4
      editor.cpp
  2. 9
    2
      editor.h
  3. 1
    1
      mainwindow.cpp
  4. 32
    0
      mainwindow.ui
  5. 2
    2
      project.cpp

+ 89
- 4
editor.cpp View File

203
     setConnectionEditControlValues(selected_connection_item->connection);
203
     setConnectionEditControlValues(selected_connection_item->connection);
204
 }
204
 }
205
 
205
 
206
+void Editor::updateCurrentConnectionDirection(QString curDirection) {
207
+    if (!selected_connection_item)
208
+        return;
209
+
210
+    QString originalDirection = selected_connection_item->connection->direction;
211
+    setCurrentConnectionDirection(curDirection);
212
+    updateMirroredConnectionDirection(selected_connection_item->connection, originalDirection);
213
+}
214
+
215
+void Editor::onConnectionMoved(Connection* connection) {
216
+    updateMirroredConnectionOffset(connection);
217
+    onConnectionOffsetChanged(connection->offset.toInt());
218
+}
219
+
206
 void Editor::onConnectionOffsetChanged(int newOffset) {
220
 void Editor::onConnectionOffsetChanged(int newOffset) {
207
     ui->spinBox_ConnectionOffset->blockSignals(true);
221
     ui->spinBox_ConnectionOffset->blockSignals(true);
208
     ui->spinBox_ConnectionOffset->setValue(newOffset);
222
     ui->spinBox_ConnectionOffset->setValue(newOffset);
209
     ui->spinBox_ConnectionOffset->blockSignals(false);
223
     ui->spinBox_ConnectionOffset->blockSignals(false);
224
+
210
 }
225
 }
211
 
226
 
212
 void Editor::setConnectionEditControlValues(Connection* connection) {
227
 void Editor::setConnectionEditControlValues(Connection* connection) {
419
 
434
 
420
 void Editor::displayMapConnections() {
435
 void Editor::displayMapConnections() {
421
     for (QGraphicsPixmapItem* item : map->connection_items) {
436
     for (QGraphicsPixmapItem* item : map->connection_items) {
422
-        scene->removeItem(item);
423
         delete item;
437
         delete item;
424
     }
438
     }
425
     map->connection_items.clear();
439
     map->connection_items.clear();
474
     connection_edit_item->setY(y);
488
     connection_edit_item->setY(y);
475
     connection_edit_item->setZValue(-1);
489
     connection_edit_item->setZValue(-1);
476
     scene->addItem(connection_edit_item);
490
     scene->addItem(connection_edit_item);
477
-    connect(connection_edit_item, SIGNAL(connectionMoved(int)), this, SLOT(onConnectionOffsetChanged(int)));
491
+    connect(connection_edit_item, SIGNAL(connectionMoved(Connection*)), this, SLOT(onConnectionMoved(Connection*)));
478
     connect(connection_edit_item, SIGNAL(connectionItemSelected(ConnectionPixmapItem*)), this, SLOT(onConnectionItemSelected(ConnectionPixmapItem*)));
492
     connect(connection_edit_item, SIGNAL(connectionItemSelected(ConnectionPixmapItem*)), this, SLOT(onConnectionItemSelected(ConnectionPixmapItem*)));
479
     connect(connection_edit_item, SIGNAL(connectionItemDoubleClicked(ConnectionPixmapItem*)), this, SLOT(onConnectionItemDoubleClicked(ConnectionPixmapItem*)));
493
     connect(connection_edit_item, SIGNAL(connectionItemDoubleClicked(ConnectionPixmapItem*)), this, SLOT(onConnectionItemDoubleClicked(ConnectionPixmapItem*)));
480
     connection_edit_items.append(connection_edit_item);
494
     connection_edit_items.append(connection_edit_item);
524
         selected_connection_item->setY(selected_connection_item->initialY + (offset - selected_connection_item->initialOffset) * 16);
538
         selected_connection_item->setY(selected_connection_item->initialY + (offset - selected_connection_item->initialOffset) * 16);
525
     }
539
     }
526
     selected_connection_item->blockSignals(false);
540
     selected_connection_item->blockSignals(false);
541
+    updateMirroredConnectionOffset(selected_connection_item->connection);
527
 }
542
 }
528
 
543
 
529
 void Editor::setConnectionMap(QString mapName) {
544
 void Editor::setConnectionMap(QString mapName) {
539
         return;
554
         return;
540
     }
555
     }
541
 
556
 
557
+    QString originalMapName = selected_connection_item->connection->map_name;
542
     setConnectionEditControlsEnabled(true);
558
     setConnectionEditControlsEnabled(true);
543
     selected_connection_item->connection->map_name = mapName;
559
     selected_connection_item->connection->map_name = mapName;
544
     setCurrentConnectionDirection(selected_connection_item->connection->direction);
560
     setCurrentConnectionDirection(selected_connection_item->connection->direction);
561
+    updateMirroredConnectionMap(selected_connection_item->connection, originalMapName);
545
 }
562
 }
546
 
563
 
547
 void Editor::addNewConnection() {
564
 void Editor::addNewConnection() {
559
         }
576
         }
560
     }
577
     }
561
 
578
 
579
+    // Don't connect the map to itself.
580
+    QString defaultMapName = project->mapNames->first();
581
+    if (defaultMapName == map->name) {
582
+        defaultMapName = project->mapNames->value(1);
583
+    }
584
+
562
     Connection* newConnection = new Connection;
585
     Connection* newConnection = new Connection;
563
     newConnection->direction = minDirection;
586
     newConnection->direction = minDirection;
564
     newConnection->offset = "0";
587
     newConnection->offset = "0";
565
-    newConnection->map_name = project->mapNames->first();
588
+    newConnection->map_name = defaultMapName;
566
     map->connections.append(newConnection);
589
     map->connections.append(newConnection);
567
     createConnectionItem(newConnection, true);
590
     createConnectionItem(newConnection, true);
568
     onConnectionItemSelected(connection_edit_items.last());
591
     onConnectionItemSelected(connection_edit_items.last());
569
     ui->label_NumConnections->setText(QString::number(map->connections.length()));
592
     ui->label_NumConnections->setText(QString::number(map->connections.length()));
593
+
594
+    updateMirroredConnection(newConnection, newConnection->direction, newConnection->map_name);
595
+}
596
+
597
+void Editor::updateMirroredConnectionOffset(Connection* connection) {
598
+    updateMirroredConnection(connection, connection->direction, connection->map_name);
599
+}
600
+void Editor::updateMirroredConnectionDirection(Connection* connection, QString originalDirection) {
601
+    updateMirroredConnection(connection, originalDirection, connection->map_name);
602
+}
603
+void Editor::updateMirroredConnectionMap(Connection* connection, QString originalMapName) {
604
+    updateMirroredConnection(connection, connection->direction, originalMapName);
605
+}
606
+void Editor::removeMirroredConnection(Connection* connection) {
607
+    updateMirroredConnection(connection, connection->direction, connection->map_name, true);
608
+}
609
+void Editor::updateMirroredConnection(Connection* connection, QString originalDirection, QString originalMapName, bool isDelete) {
610
+    if (!ui->checkBox_MirrorConnections->isChecked())
611
+        return;
612
+
613
+    static QMap<QString, QString> oppositeDirections = QMap<QString, QString>({
614
+        {"up", "down"}, {"right", "left"}, {"down", "up"}, {"left", "right"}});
615
+    QString oppositeDirection = oppositeDirections.value(originalDirection);
616
+
617
+    // Find the matching connection in the connected map.
618
+    QMap<QString, Map*> *mapcache = project->map_cache;
619
+    Connection* mirrorConnection = NULL;
620
+    Map* otherMap = project->getMap(originalMapName);
621
+    for (Connection* conn : otherMap->connections) {
622
+        if (conn->direction == oppositeDirection && conn->map_name == map->name) {
623
+            mirrorConnection = conn;
624
+        }
625
+    }
626
+
627
+    if (isDelete) {
628
+        if (mirrorConnection) {
629
+            otherMap->connections.removeOne(mirrorConnection);
630
+            delete mirrorConnection;
631
+        }
632
+        return;
633
+    }
634
+
635
+    if (connection->direction != originalDirection || connection->map_name != originalMapName) {
636
+        if (mirrorConnection) {
637
+            otherMap->connections.removeOne(mirrorConnection);
638
+            delete mirrorConnection;
639
+            mirrorConnection = NULL;
640
+            otherMap = project->getMap(connection->map_name);
641
+        }
642
+    }
643
+
644
+    // Create a new mirrored connection, if a matching one doesn't already exist.
645
+    if (!mirrorConnection) {
646
+        mirrorConnection = new Connection;
647
+        mirrorConnection->direction = oppositeDirections.value(connection->direction);
648
+        mirrorConnection->map_name = map->name;
649
+        otherMap->connections.append(mirrorConnection);
650
+    }
651
+
652
+    mirrorConnection->offset = QString::number(-connection->offset.toInt());
570
 }
653
 }
571
 
654
 
572
 void Editor::removeCurrentConnection() {
655
 void Editor::removeCurrentConnection() {
575
 
658
 
576
     map->connections.removeOne(selected_connection_item->connection);
659
     map->connections.removeOne(selected_connection_item->connection);
577
     connection_edit_items.removeOne(selected_connection_item);
660
     connection_edit_items.removeOne(selected_connection_item);
661
+    removeMirroredConnection(selected_connection_item->connection);
662
+
578
     scene->removeItem(selected_connection_item);
663
     scene->removeItem(selected_connection_item);
579
     delete selected_connection_item;
664
     delete selected_connection_item;
580
     selected_connection_item = NULL;
665
     selected_connection_item = NULL;
751
             y = initialY;
836
             y = initialY;
752
         }
837
         }
753
 
838
 
754
-        emit connectionMoved(newOffset);
755
         connection->offset = QString::number(newOffset);
839
         connection->offset = QString::number(newOffset);
840
+        emit connectionMoved(connection);
756
         return QPointF(x, y);
841
         return QPointF(x, y);
757
     }
842
     }
758
     else {
843
     else {

+ 9
- 2
editor.h View File

48
     void setEditingObjects();
48
     void setEditingObjects();
49
     void setEditingConnections();
49
     void setEditingConnections();
50
     void setCurrentConnectionDirection(QString curDirection);
50
     void setCurrentConnectionDirection(QString curDirection);
51
+    void updateCurrentConnectionDirection(QString curDirection);
51
     void setConnectionsVisibility(bool visible);
52
     void setConnectionsVisibility(bool visible);
52
     void updateConnectionOffset(int offset);
53
     void updateConnectionOffset(int offset);
53
     void setConnectionMap(QString mapName);
54
     void setConnectionMap(QString mapName);
101
     void populateConnectionMapPickers();
102
     void populateConnectionMapPickers();
102
     void setDiveEmergeControls();
103
     void setDiveEmergeControls();
103
     void updateDiveEmergeMap(QString mapName, QString direction);
104
     void updateDiveEmergeMap(QString mapName, QString direction);
105
+    void onConnectionOffsetChanged(int newOffset);
106
+    void removeMirroredConnection(Connection*);
107
+    void updateMirroredConnectionOffset(Connection*);
108
+    void updateMirroredConnectionDirection(Connection*, QString);
109
+    void updateMirroredConnectionMap(Connection*, QString);
110
+    void updateMirroredConnection(Connection*, QString, QString, bool isDelete = false);
104
 
111
 
105
 private slots:
112
 private slots:
106
     void mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
113
     void mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
107
     void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item);
114
     void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item);
108
-    void onConnectionOffsetChanged(int newOffset);
115
+    void onConnectionMoved(Connection*);
109
     void onConnectionItemSelected(ConnectionPixmapItem* connectionItem);
116
     void onConnectionItemSelected(ConnectionPixmapItem* connectionItem);
110
     void onConnectionItemDoubleClicked(ConnectionPixmapItem* connectionItem);
117
     void onConnectionItemDoubleClicked(ConnectionPixmapItem* connectionItem);
111
     void onConnectionDirectionChanged(QString newDirection);
118
     void onConnectionDirectionChanged(QString newDirection);
310
 signals:
317
 signals:
311
     void connectionItemSelected(ConnectionPixmapItem* connectionItem);
318
     void connectionItemSelected(ConnectionPixmapItem* connectionItem);
312
     void connectionItemDoubleClicked(ConnectionPixmapItem* connectionItem);
319
     void connectionItemDoubleClicked(ConnectionPixmapItem* connectionItem);
313
-    void connectionMoved(int offset);
320
+    void connectionMoved(Connection*);
314
 };
321
 };
315
 
322
 
316
 class MetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
323
 class MetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {

+ 1
- 1
mainwindow.cpp View File

775
 
775
 
776
 void MainWindow::on_comboBox_ConnectionDirection_currentIndexChanged(const QString &direction)
776
 void MainWindow::on_comboBox_ConnectionDirection_currentIndexChanged(const QString &direction)
777
 {
777
 {
778
-    editor->setCurrentConnectionDirection(direction);
778
+    editor->updateCurrentConnectionDirection(direction);
779
 }
779
 }
780
 
780
 
781
 void MainWindow::on_spinBox_ConnectionOffset_valueChanged(int offset)
781
 void MainWindow::on_spinBox_ConnectionOffset_valueChanged(int offset)

+ 32
- 0
mainwindow.ui View File

1327
                 </widget>
1327
                 </widget>
1328
                </item>
1328
                </item>
1329
                <item>
1329
                <item>
1330
+                <spacer name="horizontalSpacer_11">
1331
+                 <property name="orientation">
1332
+                  <enum>Qt::Horizontal</enum>
1333
+                 </property>
1334
+                 <property name="sizeType">
1335
+                  <enum>QSizePolicy::Maximum</enum>
1336
+                 </property>
1337
+                 <property name="sizeHint" stdset="0">
1338
+                  <size>
1339
+                   <width>40</width>
1340
+                   <height>20</height>
1341
+                  </size>
1342
+                 </property>
1343
+                </spacer>
1344
+               </item>
1345
+               <item>
1346
+                <widget class="QCheckBox" name="checkBox_MirrorConnections">
1347
+                 <property name="sizePolicy">
1348
+                  <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
1349
+                   <horstretch>0</horstretch>
1350
+                   <verstretch>0</verstretch>
1351
+                  </sizepolicy>
1352
+                 </property>
1353
+                 <property name="text">
1354
+                  <string>Mirror</string>
1355
+                 </property>
1356
+                 <property name="checked">
1357
+                  <bool>true</bool>
1358
+                 </property>
1359
+                </widget>
1360
+               </item>
1361
+               <item>
1330
                 <spacer name="horizontalSpacer_9">
1362
                 <spacer name="horizontalSpacer_9">
1331
                  <property name="orientation">
1363
                  <property name="orientation">
1332
                   <enum>Qt::Horizontal</enum>
1364
                   <enum>Qt::Horizontal</enum>

+ 2
- 2
project.cpp View File

39
     Map *map;
39
     Map *map;
40
     if (map_cache->contains(map_name)) {
40
     if (map_cache->contains(map_name)) {
41
         map = map_cache->value(map_name);
41
         map = map_cache->value(map_name);
42
-        if (map->hasUnsavedChanges()) {
42
+        // TODO: uncomment when undo/redo history is fully implemented for all actions.
43
+        if (true/*map->hasUnsavedChanges()*/) {
43
             return map;
44
             return map;
44
         }
45
         }
45
     } else {
46
     } else {
1260
         }
1261
         }
1261
 
1262
 
1262
         if (event_type == "object") {
1263
         if (event_type == "object") {
1263
-
1264
             int sprite_id = constants.value(object->get("sprite"));
1264
             int sprite_id = constants.value(object->get("sprite"));
1265
 
1265
 
1266
             QString info_label = pointers.value(sprite_id).replace("&", "");
1266
             QString info_label = pointers.value(sprite_id).replace("&", "");