Merge pull request #3046 from Nordsoft91/editor-improvements-1.4
Add map editor zoom and objects lock functionality
@ -1067,8 +1067,7 @@ std::string CGHeroInstance::getBiographyTextID() const
|
||||
if (type)
|
||||
return type->getBiographyTextID();
|
||||
|
||||
assert(0);
|
||||
return "";
|
||||
return ""; //for random hero
|
||||
}
|
||||
|
||||
CGHeroInstance::ArtPlacementMap CGHeroInstance::putArtifact(ArtifactPosition pos, CArtifactInstance * art)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "Animation.h"
|
||||
|
||||
#include "BitmapHandler.h"
|
||||
#include "graphics.h"
|
||||
|
||||
#include "../lib/vcmi_endian.h"
|
||||
#include "../lib/filesystem/Filesystem.h"
|
||||
@ -585,8 +586,8 @@ void Animation::init()
|
||||
|
||||
JsonPath resID = JsonPath::builtin("SPRITES/" + name);
|
||||
|
||||
//if(vstd::contains(graphics->imageLists, resID.getName()))
|
||||
//initFromJson(graphics->imageLists[resID.getName()]);
|
||||
if(vstd::contains(graphics->imageLists, resID.getName()))
|
||||
initFromJson(graphics->imageLists[resID.getName()]);
|
||||
|
||||
auto configList = CResourceHandler::get()->getResourcesWithName(resID);
|
||||
|
||||
|
@ -35,6 +35,7 @@ set(editor_SRCS
|
||||
inspector/questwidget.cpp
|
||||
inspector/heroskillswidget.cpp
|
||||
inspector/PickObjectDelegate.cpp
|
||||
inspector/portraitwidget.cpp
|
||||
resourceExtractor/ResourceConverter.cpp
|
||||
)
|
||||
|
||||
@ -74,6 +75,7 @@ set(editor_HEADERS
|
||||
inspector/questwidget.h
|
||||
inspector/heroskillswidget.h
|
||||
inspector/PickObjectDelegate.h
|
||||
inspector/portraitwidget.h
|
||||
resourceExtractor/ResourceConverter.h
|
||||
)
|
||||
|
||||
@ -99,6 +101,7 @@ set(editor_FORMS
|
||||
inspector/rewardswidget.ui
|
||||
inspector/questwidget.ui
|
||||
inspector/heroskillswidget.ui
|
||||
inspector/portraitwidget.ui
|
||||
)
|
||||
|
||||
set(editor_TS
|
||||
|
@ -11,6 +11,7 @@
|
||||
//code is copied from vcmiclient/Graphics.h with minimal changes
|
||||
|
||||
#include "../lib/GameConstants.h"
|
||||
#include "../lib/filesystem/ResourcePath.h"
|
||||
#include <QImage>
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
BIN
mapeditor/icons/brush-0.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mapeditor/icons/brush-6.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mapeditor/icons/brush-7.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
mapeditor/icons/zoom_base.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
mapeditor/icons/zoom_minus.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
mapeditor/icons/zoom_plus.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
mapeditor/icons/zoom_zero.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
@ -26,6 +26,7 @@
|
||||
#include "rewardswidget.h"
|
||||
#include "questwidget.h"
|
||||
#include "heroskillswidget.h"
|
||||
#include "portraitwidget.h"
|
||||
#include "PickObjectDelegate.h"
|
||||
#include "../mapcontroller.h"
|
||||
|
||||
@ -272,7 +273,7 @@ void Inspector::updateProperties(CGHeroInstance * o)
|
||||
}
|
||||
addProperty("Name", o->getNameTranslated(), false);
|
||||
addProperty("Biography", o->getBiographyTranslated(), new MessageDelegate, false);
|
||||
addProperty("Portrait", o->customPortraitSource, false);
|
||||
addProperty("Portrait", PropertyEditorPlaceholder(), new PortraitDelegate(*o), false);
|
||||
|
||||
auto * delegate = new HeroSkillsDelegate(*o);
|
||||
addProperty("Skills", PropertyEditorPlaceholder(), delegate, false);
|
||||
|
135
mapeditor/inspector/portraitwidget.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* portraitwidget.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "portraitwidget.h"
|
||||
#include "ui_portraitwidget.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../Animation.h"
|
||||
|
||||
PortraitWidget::PortraitWidget(CGHeroInstance & h, QWidget *parent):
|
||||
QDialog(parent),
|
||||
ui(new Ui::PortraitWidget),
|
||||
hero(h),
|
||||
portraitIndex(0)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->portraitView->setScene(&scene);
|
||||
ui->portraitView->fitInView(scene.itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
PortraitWidget::~PortraitWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void PortraitWidget::obtainData()
|
||||
{
|
||||
portraitIndex = VLC->heroh->getById(hero.getPortraitSource())->getIndex();
|
||||
if(hero.customPortraitSource.isValid())
|
||||
{
|
||||
ui->isDefault->setChecked(true);
|
||||
}
|
||||
|
||||
drawPortrait();
|
||||
}
|
||||
|
||||
void PortraitWidget::commitChanges()
|
||||
{
|
||||
if(portraitIndex == VLC->heroh->getById(HeroTypeID(hero.subID))->getIndex())
|
||||
hero.customPortraitSource = HeroTypeID::NONE;
|
||||
else
|
||||
hero.customPortraitSource = VLC->heroh->getByIndex(portraitIndex)->getId();
|
||||
}
|
||||
|
||||
void PortraitWidget::drawPortrait()
|
||||
{
|
||||
static Animation portraitAnimation(AnimationPath::builtin("PortraitsLarge").getOriginalName());
|
||||
portraitAnimation.preload();
|
||||
auto icon = VLC->heroTypes()->getByIndex(portraitIndex)->getIconIndex();
|
||||
pixmap = QPixmap::fromImage(*portraitAnimation.getImage(icon));
|
||||
scene.addPixmap(pixmap);
|
||||
ui->portraitView->fitInView(scene.itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
void PortraitWidget::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
ui->portraitView->fitInView(scene.itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
void PortraitWidget::on_isDefault_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->buttonNext->setEnabled(false);
|
||||
ui->buttonPrev->setEnabled(false);
|
||||
portraitIndex = VLC->heroh->getById(HeroTypeID(hero.subID))->getIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->buttonNext->setEnabled(true);
|
||||
ui->buttonPrev->setEnabled(true);
|
||||
}
|
||||
drawPortrait();
|
||||
}
|
||||
|
||||
|
||||
void PortraitWidget::on_buttonNext_clicked()
|
||||
{
|
||||
if(portraitIndex < VLC->heroh->size() - 1)
|
||||
++portraitIndex;
|
||||
else
|
||||
portraitIndex = 0;
|
||||
|
||||
drawPortrait();
|
||||
}
|
||||
|
||||
|
||||
void PortraitWidget::on_buttonPrev_clicked()
|
||||
{
|
||||
if(portraitIndex > 0)
|
||||
--portraitIndex;
|
||||
else
|
||||
portraitIndex = VLC->heroh->size() - 1;
|
||||
|
||||
drawPortrait();
|
||||
}
|
||||
|
||||
PortraitDelegate::PortraitDelegate(CGHeroInstance & h): hero(h), QStyledItemDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
QWidget * PortraitDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
return new PortraitWidget(hero, parent);
|
||||
}
|
||||
|
||||
void PortraitDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||
{
|
||||
if(auto * ed = qobject_cast<PortraitWidget *>(editor))
|
||||
{
|
||||
ed->obtainData();
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyledItemDelegate::setEditorData(editor, index);
|
||||
}
|
||||
}
|
||||
|
||||
void PortraitDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
if(auto * ed = qobject_cast<PortraitWidget *>(editor))
|
||||
{
|
||||
ed->commitChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
}
|
64
mapeditor/inspector/portraitwidget.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* portraitwidget.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
namespace Ui {
|
||||
class PortraitWidget;
|
||||
}
|
||||
|
||||
class PortraitWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PortraitWidget(CGHeroInstance &, QWidget *parent = nullptr);
|
||||
~PortraitWidget();
|
||||
|
||||
void obtainData();
|
||||
void commitChanges();
|
||||
|
||||
void resizeEvent(QResizeEvent *) override;
|
||||
|
||||
private slots:
|
||||
void on_isDefault_toggled(bool checked);
|
||||
|
||||
void on_buttonNext_clicked();
|
||||
|
||||
void on_buttonPrev_clicked();
|
||||
|
||||
private:
|
||||
void drawPortrait();
|
||||
|
||||
Ui::PortraitWidget *ui;
|
||||
QGraphicsScene scene;
|
||||
QPixmap pixmap;
|
||||
|
||||
CGHeroInstance & hero;
|
||||
int portraitIndex;
|
||||
};
|
||||
|
||||
class PortraitDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QStyledItemDelegate::QStyledItemDelegate;
|
||||
|
||||
PortraitDelegate(CGHeroInstance &);
|
||||
|
||||
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
CGHeroInstance & hero;
|
||||
};
|
96
mapeditor/inspector/portraitwidget.ui
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PortraitWidget</class>
|
||||
<widget class="QDialog" name="PortraitWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>286</width>
|
||||
<height>305</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Portrait</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="portraitView">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>116</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonNext">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="arrowType">
|
||||
<enum>Qt::UpArrow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonPrev">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="arrowType">
|
||||
<enum>Qt::DownArrow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="isDefault">
|
||||
<property name="text">
|
||||
<string>Default</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -222,6 +222,8 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
scenePreview = new QGraphicsScene(this);
|
||||
ui->objectPreview->setScene(scenePreview);
|
||||
|
||||
initialScale = ui->mapView->viewport()->geometry();
|
||||
|
||||
//loading objects
|
||||
loadObjectsTree();
|
||||
|
||||
@ -296,6 +298,7 @@ void MainWindow::initializeMap(bool isNew)
|
||||
ui->mapView->setScene(controller.scene(mapLevel));
|
||||
ui->minimapView->setScene(controller.miniScene(mapLevel));
|
||||
ui->minimapView->dimensions();
|
||||
initialScale = ui->mapView->mapToScene(ui->mapView->viewport()->geometry()).boundingRect();
|
||||
|
||||
//enable settings
|
||||
ui->actionMapSettings->setEnabled(true);
|
||||
@ -537,18 +540,20 @@ void MainWindow::addGroupIntoCatalog(const std::string & groupName, bool useCust
|
||||
painter.drawImage(QPoint(0, 0), *picture);
|
||||
}
|
||||
|
||||
//create object to extract name
|
||||
std::unique_ptr<CGObjectInstance> temporaryObj(factory->create(templ));
|
||||
QString translated = useCustomName ? QString::fromStdString(temporaryObj->getObjectName().c_str()) : subGroupName;
|
||||
itemType->setText(translated);
|
||||
|
||||
//add parameters
|
||||
QJsonObject data{{"id", QJsonValue(ID)},
|
||||
{"subid", QJsonValue(secondaryID)},
|
||||
{"template", QJsonValue(templateId)},
|
||||
{"animationEditor", QString::fromStdString(templ->editorAnimationFile.getOriginalName())},
|
||||
{"animation", QString::fromStdString(templ->animationFile.getOriginalName())},
|
||||
{"preview", jsonFromPixmap(preview)}};
|
||||
|
||||
//create object to extract name
|
||||
std::unique_ptr<CGObjectInstance> temporaryObj(factory->create(templ));
|
||||
QString translated = useCustomName ? tr(temporaryObj->getObjectName().c_str()) : subGroupName;
|
||||
itemType->setText(translated);
|
||||
{"preview", jsonFromPixmap(preview)},
|
||||
{"typeName", QString::fromStdString(factory->getJsonKey())}
|
||||
};
|
||||
|
||||
//do not have extra level
|
||||
if(singleTemplate)
|
||||
@ -830,99 +835,12 @@ void MainWindow::changeBrushState(int idx)
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_toolBrush_clicked(bool checked)
|
||||
{
|
||||
//ui->toolBrush->setChecked(false);
|
||||
ui->toolBrush2->setChecked(false);
|
||||
ui->toolBrush4->setChecked(false);
|
||||
ui->toolArea->setChecked(false);
|
||||
ui->toolLasso->setChecked(false);
|
||||
|
||||
if(checked)
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Brush;
|
||||
else
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::None;
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void MainWindow::on_toolBrush2_clicked(bool checked)
|
||||
{
|
||||
ui->toolBrush->setChecked(false);
|
||||
//ui->toolBrush2->setChecked(false);
|
||||
ui->toolBrush4->setChecked(false);
|
||||
ui->toolArea->setChecked(false);
|
||||
ui->toolLasso->setChecked(false);
|
||||
|
||||
if(checked)
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Brush2;
|
||||
else
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::None;
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolBrush4_clicked(bool checked)
|
||||
{
|
||||
ui->toolBrush->setChecked(false);
|
||||
ui->toolBrush2->setChecked(false);
|
||||
//ui->toolBrush4->setChecked(false);
|
||||
ui->toolArea->setChecked(false);
|
||||
ui->toolLasso->setChecked(false);
|
||||
|
||||
if(checked)
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Brush4;
|
||||
else
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::None;
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void MainWindow::on_toolArea_clicked(bool checked)
|
||||
{
|
||||
ui->toolBrush->setChecked(false);
|
||||
ui->toolBrush2->setChecked(false);
|
||||
ui->toolBrush4->setChecked(false);
|
||||
//ui->toolArea->setChecked(false);
|
||||
ui->toolLasso->setChecked(false);
|
||||
|
||||
if(checked)
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Area;
|
||||
else
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::None;
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void MainWindow::on_toolLasso_clicked(bool checked)
|
||||
{
|
||||
ui->toolBrush->setChecked(false);
|
||||
ui->toolBrush2->setChecked(false);
|
||||
ui->toolBrush4->setChecked(false);
|
||||
ui->toolArea->setChecked(false);
|
||||
//ui->toolLasso->setChecked(false);
|
||||
|
||||
if(checked)
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Lasso;
|
||||
else
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::None;
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionErase_triggered()
|
||||
{
|
||||
on_toolErase_clicked();
|
||||
}
|
||||
|
||||
void MainWindow::on_toolErase_clicked()
|
||||
{
|
||||
if(controller.map())
|
||||
{
|
||||
controller.commitObjectErase(mapLevel);
|
||||
}
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void MainWindow::preparePreview(const QModelIndex &index)
|
||||
@ -939,16 +857,14 @@ void MainWindow::preparePreview(const QModelIndex &index)
|
||||
scenePreview->addPixmap(objPreview);
|
||||
}
|
||||
}
|
||||
|
||||
ui->objectPreview->fitInView(scenePreview->itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::treeViewSelected(const QModelIndex & index, const QModelIndex & deselected)
|
||||
{
|
||||
ui->toolBrush->setChecked(false);
|
||||
ui->toolBrush2->setChecked(false);
|
||||
ui->toolBrush4->setChecked(false);
|
||||
ui->toolArea->setChecked(false);
|
||||
ui->toolLasso->setChecked(false);
|
||||
ui->toolSelect->setChecked(true);
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::None;
|
||||
|
||||
preparePreview(index);
|
||||
@ -1109,7 +1025,6 @@ void MainWindow::onSelectionMade(int level, bool anythingSelected)
|
||||
if (level == mapLevel)
|
||||
{
|
||||
ui->actionErase->setEnabled(anythingSelected);
|
||||
ui->toolErase->setEnabled(anythingSelected);
|
||||
}
|
||||
}
|
||||
void MainWindow::displayStatus(const QString& message, int timeout /* = 2000 */)
|
||||
@ -1279,3 +1194,145 @@ void MainWindow::on_actionh3m_converter_triggered()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionLock_triggered()
|
||||
{
|
||||
if(controller.map())
|
||||
{
|
||||
if(controller.scene(mapLevel)->selectionObjectsView.getSelection().empty())
|
||||
{
|
||||
for(auto obj : controller.map()->objects)
|
||||
{
|
||||
controller.scene(mapLevel)->selectionObjectsView.setLockObject(obj, true);
|
||||
controller.scene(mapLevel)->objectsView.setLockObject(obj, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto * obj : controller.scene(mapLevel)->selectionObjectsView.getSelection())
|
||||
{
|
||||
controller.scene(mapLevel)->selectionObjectsView.setLockObject(obj, true);
|
||||
controller.scene(mapLevel)->objectsView.setLockObject(obj, true);
|
||||
}
|
||||
controller.scene(mapLevel)->selectionObjectsView.clear();
|
||||
}
|
||||
controller.scene(mapLevel)->objectsView.update();
|
||||
controller.scene(mapLevel)->selectionObjectsView.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionUnlock_triggered()
|
||||
{
|
||||
if(controller.map())
|
||||
{
|
||||
controller.scene(mapLevel)->selectionObjectsView.unlockAll();
|
||||
controller.scene(mapLevel)->objectsView.unlockAll();
|
||||
}
|
||||
controller.scene(mapLevel)->objectsView.update();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionZoom_in_triggered()
|
||||
{
|
||||
auto rect = ui->mapView->mapToScene(ui->mapView->viewport()->geometry()).boundingRect();
|
||||
rect -= QMargins{32 + 1, 32 + 1, 32 + 2, 32 + 2}; //compensate bounding box
|
||||
ui->mapView->fitInView(rect, Qt::KeepAspectRatioByExpanding);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionZoom_out_triggered()
|
||||
{
|
||||
auto rect = ui->mapView->mapToScene(ui->mapView->viewport()->geometry()).boundingRect();
|
||||
rect += QMargins{32 - 1, 32 - 1, 32 - 2, 32 - 2}; //compensate bounding box
|
||||
ui->mapView->fitInView(rect, Qt::KeepAspectRatioByExpanding);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionZoom_reset_triggered()
|
||||
{
|
||||
auto center = ui->mapView->mapToScene(ui->mapView->viewport()->geometry().center());
|
||||
ui->mapView->fitInView(initialScale, Qt::KeepAspectRatioByExpanding);
|
||||
ui->mapView->centerOn(center);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolLine_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Line;
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolBrush2_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Brush2;
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolBrush_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Brush;
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolBrush4_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Brush4;
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolLasso_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Lasso;
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolArea_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Area;
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolFill_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::Fill;
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_toolSelect_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::None;
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,28 +76,16 @@ private slots:
|
||||
|
||||
void on_actionGrid_triggered(bool checked);
|
||||
|
||||
void on_toolBrush_clicked(bool checked);
|
||||
|
||||
void on_toolArea_clicked(bool checked);
|
||||
|
||||
void terrainButtonClicked(TerrainId terrain);
|
||||
void roadOrRiverButtonClicked(ui8 type, bool isRoad);
|
||||
void currentCoordinatesChanged(int x, int y);
|
||||
|
||||
void on_toolErase_clicked();
|
||||
|
||||
void on_terrainFilterCombo_currentIndexChanged(int index);
|
||||
|
||||
void on_filter_textChanged(const QString &arg1);
|
||||
|
||||
void on_actionFill_triggered();
|
||||
|
||||
void on_toolBrush2_clicked(bool checked);
|
||||
|
||||
void on_toolBrush4_clicked(bool checked);
|
||||
|
||||
void on_toolLasso_clicked(bool checked);
|
||||
|
||||
void on_inspectorWidget_itemChanged(QTableWidgetItem *item);
|
||||
|
||||
void on_actionMapSettings_triggered();
|
||||
@ -124,6 +112,32 @@ private slots:
|
||||
|
||||
void on_actionh3m_converter_triggered();
|
||||
|
||||
void on_actionLock_triggered();
|
||||
|
||||
void on_actionUnlock_triggered();
|
||||
|
||||
void on_actionZoom_in_triggered();
|
||||
|
||||
void on_actionZoom_out_triggered();
|
||||
|
||||
void on_actionZoom_reset_triggered();
|
||||
|
||||
void on_toolLine_toggled(bool checked);
|
||||
|
||||
void on_toolBrush2_toggled(bool checked);
|
||||
|
||||
void on_toolBrush_toggled(bool checked);
|
||||
|
||||
void on_toolBrush4_toggled(bool checked);
|
||||
|
||||
void on_toolLasso_toggled(bool checked);
|
||||
|
||||
void on_toolArea_toggled(bool checked);
|
||||
|
||||
void on_toolFill_toggled(bool checked);
|
||||
|
||||
void on_toolSelect_toggled(bool checked);
|
||||
|
||||
public slots:
|
||||
|
||||
void treeViewSelected(const QModelIndex &selected, const QModelIndex &deselected);
|
||||
@ -166,6 +180,7 @@ private:
|
||||
QStandardItemModel objectsModel;
|
||||
|
||||
int mapLevel = 0;
|
||||
QRectF initialScale;
|
||||
|
||||
std::set<int> catalog;
|
||||
|
||||
|
@ -86,6 +86,8 @@
|
||||
<addaction name="actionCopy"/>
|
||||
<addaction name="actionPaste"/>
|
||||
<addaction name="actionErase"/>
|
||||
<addaction name="actionLock"/>
|
||||
<addaction name="actionUnlock"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
@ -94,6 +96,10 @@
|
||||
<addaction name="actionLevel"/>
|
||||
<addaction name="actionGrid"/>
|
||||
<addaction name="actionPass"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionZoom_in"/>
|
||||
<addaction name="actionZoom_out"/>
|
||||
<addaction name="actionZoom_reset"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuPlayer">
|
||||
<property name="title">
|
||||
@ -143,6 +149,13 @@
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionFill"/>
|
||||
<addaction name="actionTranslations"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionLock"/>
|
||||
<addaction name="actionUnlock"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionZoom_in"/>
|
||||
<addaction name="actionZoom_out"/>
|
||||
<addaction name="actionZoom_reset"/>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dockWidget_2">
|
||||
<property name="sizePolicy">
|
||||
@ -163,6 +176,9 @@
|
||||
<height>214</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Minimap</string>
|
||||
</property>
|
||||
@ -203,12 +219,6 @@
|
||||
<height>192</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>192</width>
|
||||
<height>192</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
@ -239,6 +249,9 @@
|
||||
<height>524287</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Map Objects View</string>
|
||||
</property>
|
||||
@ -429,17 +442,8 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>128</width>
|
||||
<height>192</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>524287</width>
|
||||
<height>192</height>
|
||||
</size>
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Tools</string>
|
||||
@ -468,48 +472,23 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Brush</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="toolBrush">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
@ -545,12 +524,15 @@
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolBrush2">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
@ -589,12 +571,15 @@
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolBrush4">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
@ -633,39 +618,7 @@
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="toolArea">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:brush-5.png</normaloff>icons:brush-5.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
@ -673,7 +626,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolLasso">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
@ -706,16 +659,134 @@
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="toolErase">
|
||||
<property name="enabled">
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolLine">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:brush-7.png</normaloff>icons:brush-7.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolArea">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:brush-5.png</normaloff>icons:brush-5.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolFill">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:brush-6.png</normaloff>icons:brush-6.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolSelect">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@ -739,10 +810,16 @@
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:edit-clear.png</normaloff>icons:edit-clear.png</iconset>
|
||||
<normaloff>icons:brush-0.png</normaloff>icons:brush-0.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoExclusive">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
@ -750,7 +827,6 @@
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -762,6 +838,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Painting</string>
|
||||
</property>
|
||||
@ -804,8 +883,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>128</width>
|
||||
<height>192</height>
|
||||
<width>256</width>
|
||||
<height>120</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -847,8 +926,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>128</width>
|
||||
<height>192</height>
|
||||
<width>256</width>
|
||||
<height>120</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -883,8 +962,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>128</width>
|
||||
<height>192</height>
|
||||
<width>256</width>
|
||||
<height>120</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -920,11 +999,8 @@
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dockWidget_5">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>524287</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Preview</string>
|
||||
@ -954,12 +1030,6 @@
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>128</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -1341,6 +1411,72 @@
|
||||
<string>h3m converter</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLock">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:lock-closed.png</normaloff>icons:lock-closed.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lock</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Lock objects on map to avoid unnecessary changes</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+L</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUnlock">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:lock-open.png</normaloff>icons:lock-open.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unlock</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Unlock all objects on the map</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+L</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionZoom_in">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:zoom_plus.png</normaloff>icons:zoom_plus.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Zoom in</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+=</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionZoom_out">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:zoom_minus.png</normaloff>icons:zoom_minus.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Zoom out</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+-</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionZoom_reset">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:zoom_zero.png</normaloff>icons:zoom_zero.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Zoom reset</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+=</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
@ -322,8 +322,11 @@ std::vector<TileObject> & MapHandler::getObjects(int x, int y, int z)
|
||||
return ttiles[index(x, y, z)];
|
||||
}
|
||||
|
||||
void MapHandler::drawObjects(QPainter & painter, int x, int y, int z)
|
||||
void MapHandler::drawObjects(QPainter & painter, int x, int y, int z, const std::set<const CGObjectInstance *> & locked)
|
||||
{
|
||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||
|
||||
for(auto & object : getObjects(x, y, z))
|
||||
{
|
||||
const CGObjectInstance * obj = object.obj;
|
||||
@ -343,7 +346,14 @@ void MapHandler::drawObjects(QPainter & painter, int x, int y, int z)
|
||||
{
|
||||
auto pos = obj->getPosition();
|
||||
|
||||
painter.drawImage(QPoint(x * tileSize, y * tileSize), *objData.objBitmap, object.rect);
|
||||
painter.drawImage(QPoint(x * tileSize, y * tileSize), *objData.objBitmap, object.rect, Qt::AutoColor | Qt::NoOpaqueDetection);
|
||||
|
||||
if(locked.count(obj))
|
||||
{
|
||||
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
painter.fillRect(x * tileSize, y * tileSize, object.rect.width(), object.rect.height(), Qt::Dense4Pattern);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
}
|
||||
|
||||
if(objData.flagBitmap)
|
||||
{
|
||||
|
@ -89,6 +89,8 @@ private:
|
||||
void initTerrainGraphics();
|
||||
QRgb getTileColor(int x, int y, int z);
|
||||
|
||||
QPolygon lockBitMask;
|
||||
|
||||
public:
|
||||
MapHandler();
|
||||
~MapHandler() = default;
|
||||
@ -110,7 +112,7 @@ public:
|
||||
std::vector<int3> getTilesUnderObject(CGObjectInstance *) const;
|
||||
|
||||
/// draws all objects on current tile (higher-level logic, unlike other draw*** methods)
|
||||
void drawObjects(QPainter & painter, int x, int y, int z);
|
||||
void drawObjects(QPainter & painter, int x, int y, int z, const std::set<const CGObjectInstance *> & locked);
|
||||
void drawObject(QPainter & painter, const TileObject & object);
|
||||
void drawObjectAt(QPainter & painter, const CGObjectInstance * object, int x, int y);
|
||||
std::vector<TileObject> & getObjects(int x, int y, int z);
|
||||
|
@ -44,15 +44,9 @@ void MinimapView::mouseMoveEvent(QMouseEvent *mouseEvent)
|
||||
if(!sc)
|
||||
return;
|
||||
|
||||
int w = sc->viewport.viewportWidth();
|
||||
int h = sc->viewport.viewportHeight();
|
||||
auto pos = mapToScene(mouseEvent->pos());
|
||||
pos.setX(pos.x() - w / 2);
|
||||
pos.setY(pos.y() - h / 2);
|
||||
|
||||
QPointF point = pos * 32;
|
||||
|
||||
emit cameraPositionChanged(point);
|
||||
pos *= 32;
|
||||
emit cameraPositionChanged(pos);
|
||||
}
|
||||
|
||||
void MinimapView::mousePressEvent(QMouseEvent* event)
|
||||
@ -68,8 +62,7 @@ MapView::MapView(QWidget * parent):
|
||||
|
||||
void MapView::cameraChanged(const QPointF & pos)
|
||||
{
|
||||
horizontalScrollBar()->setValue(pos.x());
|
||||
verticalScrollBar()->setValue(pos.y());
|
||||
centerOn(pos);
|
||||
}
|
||||
|
||||
void MapView::setController(MapController * ctrl)
|
||||
@ -158,6 +151,60 @@ void MapView::mouseMoveEvent(QMouseEvent *mouseEvent)
|
||||
sc->selectionTerrainView.draw();
|
||||
break;
|
||||
|
||||
case MapView::SelectionTool::Line:
|
||||
{
|
||||
assert(tile.z == tileStart.z);
|
||||
const auto diff = tile - tileStart;
|
||||
if(diff == int3{})
|
||||
break;
|
||||
|
||||
const int edge = std::max(abs(diff.x), abs(diff.y));
|
||||
int distMin = std::numeric_limits<int>::max();
|
||||
int3 dir;
|
||||
|
||||
for(auto & d : int3::getDirs())
|
||||
{
|
||||
if(tile.dist2d(d * edge + tileStart) < distMin)
|
||||
{
|
||||
distMin = tile.dist2d(d * edge + tileStart);
|
||||
dir = d;
|
||||
}
|
||||
}
|
||||
|
||||
assert(dir != int3{});
|
||||
|
||||
if(mouseEvent->buttons() == Qt::LeftButton)
|
||||
{
|
||||
for(auto & ts : temporaryTiles)
|
||||
sc->selectionTerrainView.erase(ts);
|
||||
|
||||
for(auto ts = tileStart; ts.dist2d(tileStart) < edge; ts += dir)
|
||||
{
|
||||
if(!controller->map()->isInTheMap(ts))
|
||||
break;
|
||||
if(!sc->selectionTerrainView.selection().count(ts))
|
||||
temporaryTiles.insert(ts);
|
||||
sc->selectionTerrainView.select(ts);
|
||||
}
|
||||
}
|
||||
if(mouseEvent->buttons() == Qt::RightButton)
|
||||
{
|
||||
for(auto & ts : temporaryTiles)
|
||||
sc->selectionTerrainView.select(ts);
|
||||
|
||||
for(auto ts = tileStart; ts.dist2d(tileStart) < edge; ts += dir)
|
||||
{
|
||||
if(!controller->map()->isInTheMap(ts))
|
||||
break;
|
||||
if(sc->selectionTerrainView.selection().count(ts))
|
||||
temporaryTiles.insert(ts);
|
||||
sc->selectionTerrainView.erase(ts);
|
||||
}
|
||||
}
|
||||
sc->selectionTerrainView.draw();
|
||||
break;
|
||||
}
|
||||
|
||||
case MapView::SelectionTool::Lasso:
|
||||
if(mouseEvent->buttons() == Qt::LeftButton)
|
||||
{
|
||||
@ -212,6 +259,7 @@ void MapView::mousePressEvent(QMouseEvent *event)
|
||||
switch(selectionTool)
|
||||
{
|
||||
case MapView::SelectionTool::Brush:
|
||||
case MapView::SelectionTool::Line:
|
||||
sc->selectionObjectsView.clear();
|
||||
sc->selectionObjectsView.draw();
|
||||
|
||||
@ -270,6 +318,55 @@ void MapView::mousePressEvent(QMouseEvent *event)
|
||||
sc->selectionObjectsView.draw();
|
||||
break;
|
||||
|
||||
case MapView::SelectionTool::Fill:
|
||||
{
|
||||
if(event->button() != Qt::RightButton && event->button() != Qt::LeftButton)
|
||||
break;
|
||||
|
||||
std::vector<int3> queue;
|
||||
queue.push_back(tileStart);
|
||||
|
||||
const std::array<int3, 4> dirs{ int3{1, 0, 0}, int3{-1, 0, 0}, int3{0, 1, 0}, int3{0, -1, 0} };
|
||||
|
||||
while(!queue.empty())
|
||||
{
|
||||
auto tile = queue.back();
|
||||
queue.pop_back();
|
||||
if(event->button() == Qt::LeftButton)
|
||||
sc->selectionTerrainView.select(tile);
|
||||
else
|
||||
sc->selectionTerrainView.erase(tile);
|
||||
for(auto & d : dirs)
|
||||
{
|
||||
auto tilen = tile + d;
|
||||
if(!controller->map()->isInTheMap(tilen))
|
||||
continue;
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
if(controller->map()->getTile(tile).roadType
|
||||
&& controller->map()->getTile(tile).roadType != controller->map()->getTile(tilen).roadType)
|
||||
continue;
|
||||
else if(controller->map()->getTile(tile).riverType
|
||||
&& controller->map()->getTile(tile).riverType != controller->map()->getTile(tilen).riverType)
|
||||
continue;
|
||||
else if(controller->map()->getTile(tile).terType != controller->map()->getTile(tilen).terType)
|
||||
continue;
|
||||
}
|
||||
if(event->button() == Qt::LeftButton && sc->selectionTerrainView.selection().count(tilen))
|
||||
continue;
|
||||
if(event->button() == Qt::RightButton && !sc->selectionTerrainView.selection().count(tilen))
|
||||
continue;
|
||||
queue.push_back(tilen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sc->selectionTerrainView.draw();
|
||||
sc->selectionObjectsView.clear();
|
||||
sc->selectionObjectsView.draw();
|
||||
break;
|
||||
}
|
||||
|
||||
case MapView::SelectionTool::None:
|
||||
sc->selectionTerrainView.clear();
|
||||
sc->selectionTerrainView.draw();
|
||||
@ -408,6 +505,10 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
|
||||
break;
|
||||
}
|
||||
|
||||
case MapView::SelectionTool::Line:
|
||||
temporaryTiles.clear();
|
||||
break;
|
||||
|
||||
case MapView::SelectionTool::None:
|
||||
if(event->button() == Qt::RightButton)
|
||||
break;
|
||||
|
@ -89,7 +89,7 @@ class MapView : public QGraphicsView
|
||||
public:
|
||||
enum class SelectionTool
|
||||
{
|
||||
None, Brush, Brush2, Brush4, Area, Lasso
|
||||
None, Brush, Brush2, Brush4, Area, Lasso, Line, Fill
|
||||
};
|
||||
|
||||
public:
|
||||
@ -124,6 +124,8 @@ private:
|
||||
int3 tileStart;
|
||||
int3 tilePrev;
|
||||
bool pressedOnSelected;
|
||||
|
||||
std::set<int3> temporaryTiles;
|
||||
};
|
||||
|
||||
class MinimapView : public QGraphicsView
|
||||
|
@ -77,7 +77,11 @@ bool ObjectBrowserProxyModel::filterAcceptsRowText(int source_row, const QModelI
|
||||
if(!item)
|
||||
return false;
|
||||
|
||||
return (filter.isNull() || filter.isEmpty() || item->text().contains(filter, Qt::CaseInsensitive));
|
||||
auto data = item->data().toJsonObject();
|
||||
|
||||
return (filter.isNull() || filter.isEmpty()
|
||||
|| item->text().contains(filter, Qt::CaseInsensitive)
|
||||
|| data["typeName"].toString().contains(filter, Qt::CaseInsensitive));
|
||||
}
|
||||
|
||||
Qt::ItemFlags ObjectBrowserProxyModel::flags(const QModelIndex & index) const
|
||||
|
@ -377,7 +377,6 @@ void ObjectsLayer::draw(bool onlyDirty)
|
||||
return;
|
||||
|
||||
QPainter painter(pixmap.get());
|
||||
std::set<const CGObjectInstance *> drawen;
|
||||
|
||||
if(onlyDirty)
|
||||
{
|
||||
@ -392,7 +391,7 @@ void ObjectsLayer::draw(bool onlyDirty)
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
|
||||
for(auto & p : dirty)
|
||||
handler->drawObjects(painter, p.x, p.y, p.z);
|
||||
handler->drawObjects(painter, p.x, p.y, p.z, lockedObjects);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -401,7 +400,7 @@ void ObjectsLayer::draw(bool onlyDirty)
|
||||
{
|
||||
for(int i = 0; i < map->width; ++i)
|
||||
{
|
||||
handler->drawObjects(painter, i, j, scene->level);
|
||||
handler->drawObjects(painter, i, j, scene->level, lockedObjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -430,6 +429,19 @@ void ObjectsLayer::setDirty(const CGObjectInstance * object)
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectsLayer::setLockObject(const CGObjectInstance * object, bool lock)
|
||||
{
|
||||
if(lock)
|
||||
lockedObjects.insert(object);
|
||||
else
|
||||
lockedObjects.erase(object);
|
||||
}
|
||||
|
||||
void ObjectsLayer::unlockAll()
|
||||
{
|
||||
lockedObjects.clear();
|
||||
}
|
||||
|
||||
SelectionObjectsLayer::SelectionObjectsLayer(MapSceneBase * s): AbstractLayer(s), newObject(nullptr)
|
||||
{
|
||||
}
|
||||
@ -501,7 +513,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y, const CGO
|
||||
//visitable is most important
|
||||
for(auto & object : objects)
|
||||
{
|
||||
if(!object.obj || object.obj == ignore)
|
||||
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||
continue;
|
||||
|
||||
if(object.obj->visitableAt(x, y))
|
||||
@ -513,7 +525,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y, const CGO
|
||||
//if not visitable tile - try to get blocked
|
||||
for(auto & object : objects)
|
||||
{
|
||||
if(!object.obj || object.obj == ignore)
|
||||
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||
continue;
|
||||
|
||||
if(object.obj->blockingAt(x, y))
|
||||
@ -525,7 +537,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y, const CGO
|
||||
//finally, we can take any object
|
||||
for(auto & object : objects)
|
||||
{
|
||||
if(!object.obj || object.obj == ignore)
|
||||
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||
continue;
|
||||
|
||||
if(object.obj->coveringAt(x, y))
|
||||
@ -555,6 +567,7 @@ void SelectionObjectsLayer::selectObjects(int x1, int y1, int x2, int y2)
|
||||
if(map->isInTheMap(int3(i, j, scene->level)))
|
||||
{
|
||||
for(auto & o : handler->getObjects(i, j, scene->level))
|
||||
if(!lockedObjects.count(o.obj))
|
||||
selectObject(o.obj, false); //do not inform about each object added
|
||||
}
|
||||
}
|
||||
@ -599,6 +612,19 @@ void SelectionObjectsLayer::onSelection()
|
||||
emit selectionMade(!selectedObjects.empty());
|
||||
}
|
||||
|
||||
void SelectionObjectsLayer::setLockObject(const CGObjectInstance * object, bool lock)
|
||||
{
|
||||
if(lock)
|
||||
lockedObjects.insert(object);
|
||||
else
|
||||
lockedObjects.erase(object);
|
||||
}
|
||||
|
||||
void SelectionObjectsLayer::unlockAll()
|
||||
{
|
||||
lockedObjects.clear();
|
||||
}
|
||||
|
||||
MinimapLayer::MinimapLayer(MapSceneBase * s): AbstractLayer(s)
|
||||
{
|
||||
|
||||
|
@ -121,8 +121,12 @@ public:
|
||||
void setDirty(int x, int y);
|
||||
void setDirty(const CGObjectInstance * object);
|
||||
|
||||
void setLockObject(const CGObjectInstance * object, bool lock);
|
||||
void unlockAll();
|
||||
|
||||
private:
|
||||
std::set<const CGObjectInstance *> objDirty;
|
||||
std::set<const CGObjectInstance *> lockedObjects;
|
||||
std::set<int3> dirty;
|
||||
};
|
||||
|
||||
@ -181,6 +185,9 @@ public:
|
||||
std::set<CGObjectInstance*> getSelection() const;
|
||||
void clear();
|
||||
|
||||
void setLockObject(const CGObjectInstance * object, bool lock);
|
||||
void unlockAll();
|
||||
|
||||
QPoint shift;
|
||||
CGObjectInstance * newObject;
|
||||
//FIXME: magic number
|
||||
@ -191,6 +198,7 @@ signals:
|
||||
|
||||
private:
|
||||
std::set<CGObjectInstance *> selectedObjects;
|
||||
std::set<const CGObjectInstance *> lockedObjects;
|
||||
|
||||
void onSelection();
|
||||
};
|
||||
|