Merge branch 'master' of https://github.com/huderlem/porymap into commit-version
2
.gitignore
vendored
@@ -8,9 +8,11 @@ porymap.app*
|
||||
porymap
|
||||
porymap.cfg
|
||||
porymap.log
|
||||
build/
|
||||
|
||||
# Qt generated files
|
||||
ui_*.h
|
||||
moc_*.h
|
||||
moc_*.cpp
|
||||
qrc_*.cpp
|
||||
.qtc_clangd
|
||||
|
||||
16
CHANGELOG.md
@@ -9,10 +9,14 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Redesigned the Connections tab, adding a number of new features including the option to open or display diving maps and a list UI for easier edit access.
|
||||
- Add the ability to edit layouts with no corresponding map.
|
||||
- Add a `Close Project` option
|
||||
- Add charts to the `Wild Pokémon` tab that show species and level distributions.
|
||||
- Add options for customizing the map grid under `View -> Grid Settings`.
|
||||
- An alert will be displayed when attempting to open a seemingly invalid project.
|
||||
- Add support for defining project values with `enum` where `#define` was expected.
|
||||
- Add button to enable editing map groups including renaming groups and rearranging the maps within them.
|
||||
- Add buttons to hide and show empty folders in each map tree view.
|
||||
|
||||
### Changed
|
||||
- Edits to map connections now have Undo/Redo and can be viewed in exported timelapses.
|
||||
@@ -22,6 +26,8 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
|
||||
- The max encounter rate is now read from the project, rather than assuming the default value from RSE.
|
||||
- It's now possible to cancel quitting if there are unsaved changes in sub-windows.
|
||||
- The triple-layer metatiles setting can now be set automatically using a project constant.
|
||||
- `Export Map Stitch Image` now shows a preview of the full image, not just the current map.
|
||||
- Maps and layouts were internally separated.
|
||||
|
||||
### Fixed
|
||||
- Fix `Add Region Map...` not updating the region map settings file.
|
||||
@@ -45,6 +51,16 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
|
||||
- Fix the map list filter retaining text between project open/close.
|
||||
- Fix the map list mishandling value gaps when sorting by Area.
|
||||
- Fix a freeze on startup if project values are defined with mismatched parentheses.
|
||||
- Fix stitched map images sometimes rendering garbage
|
||||
- Fix the `Reset` button on `Export Map Timelapse Image` not resetting the Timelapse settings.
|
||||
- Stop sliders in the Palette Editor from creating a bunch of edit history when used.
|
||||
- Fix scrolling on some containers locking up when the mouse stops over a spin box or combo box.
|
||||
- Fix some file dialogs returning to an incorrect window when closed.
|
||||
- Fix bug where reloading a layout would overwrite all unsaved changes.
|
||||
- Fix bug where layout json and blockdata could be saved separately leading to inconsistent data.
|
||||
- Fix crash when saving tilesets with fewer palettes than the maximum.
|
||||
- Fix projects not opening on Windows if the project filepath contains certain characters.
|
||||
- Fix exported tile images containing garbage pixels after the end of the tiles.
|
||||
|
||||
## [5.4.1] - 2024-03-21
|
||||
### Fixed
|
||||
|
||||
11
INSTALL.md
@@ -39,3 +39,14 @@ qmake
|
||||
make
|
||||
./porymap
|
||||
```
|
||||
|
||||
## Arch Linux
|
||||
|
||||
You need to install Qt. You can check the version of your Qt packages with `qtdiag` or `qmake --version`.
|
||||
|
||||
```bash
|
||||
sudo pacman -S qt6-declarative qt6-charts
|
||||
qmake
|
||||
make
|
||||
./porymap
|
||||
```
|
||||
|
||||
@@ -59,7 +59,6 @@ The filepath that Porymap expects for each file can be overridden on the ``Files
|
||||
include/constants/event_object_movement.h, yes, no, ``constants_obj_event_movement``,
|
||||
include/constants/event_objects.h, yes, no, ``constants_obj_events``,
|
||||
include/constants/event_bg.h, yes, no, ``constants_event_bg``,
|
||||
include/constants/region_map_sections.h, yes, no, ``constants_region_map_sections``,
|
||||
include/constants/metatile_labels.h, yes, yes, ``constants_metatile_labels``,
|
||||
include/constants/metatile_behaviors.h, yes, no, ``constants_metatile_behaviors``,
|
||||
include/constants/species.h, yes, no, ``constants_metatile_behaviors``, for the Wild Pokémon tab
|
||||
@@ -122,7 +121,6 @@ In addition to these files, there are some specific symbol and macro names that
|
||||
``define_map_empty``, ``UNDEFINED``, macro name after prefix for empty maps
|
||||
``define_map_section_prefix``, ``MAPSEC_``, expected prefix for location macro names
|
||||
``define_map_section_empty``, ``NONE``, macro name after prefix for empty region map sections
|
||||
``define_map_section_count``, ``COUNT``, macro name after prefix for total number of region map sections
|
||||
``define_species_prefix``, ``SPECIES_``, expected prefix for species macro names
|
||||
``regex_behaviors``, ``\bMB_``, regex to find metatile behavior macro names
|
||||
``regex_obj_event_gfx``, ``\bOBJ_EVENT_GFX_``, regex to find Object Event graphics ID macro names
|
||||
|
||||
310
forms/colorinputwidget.ui
Normal file
@@ -0,0 +1,310 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ColorInputWidget</class>
|
||||
<widget class="QGroupBox" name="ColorInputWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>221</width>
|
||||
<height>212</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QFrame" name="frame_InputMain">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<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>
|
||||
<widget class="QFrame" name="frame_Labels">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<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>
|
||||
<widget class="QLabel" name="label_Red">
|
||||
<property name="text">
|
||||
<string>Red</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_Green">
|
||||
<property name="text">
|
||||
<string>Green</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_Blue">
|
||||
<property name="text">
|
||||
<string>Blue</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_Sliders">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<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>
|
||||
<widget class="QSlider" name="slider_Red">
|
||||
<property name="maximum">
|
||||
<number>31</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="slider_Green">
|
||||
<property name="maximum">
|
||||
<number>31</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="slider_Blue">
|
||||
<property name="maximum">
|
||||
<number>31</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_SpinBoxes">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<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>
|
||||
<widget class="QSpinBox" name="spinBox_Red">
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>8</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_Green">
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>8</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_Blue">
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>8</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QFrame" name="frame_ColorDisplay">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QFrame" name="frame_InputTop">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<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="QFrame" name="frame_Hex">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<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="QLabel" name="label_Hex">
|
||||
<property name="text">
|
||||
<string>#</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Hex"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QToolButton" name="button_Eyedrop">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/pipette.ico</normaloff>:/icons/pipette.ico</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>540</width>
|
||||
<width>582</width>
|
||||
<height>355</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -33,21 +33,30 @@
|
||||
<item>
|
||||
<widget class="QFrame" name="window">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QFrame" name="header">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="button_CreateNewScript">
|
||||
<property name="toolTip">
|
||||
@@ -91,9 +100,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_header">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -103,35 +112,33 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_header">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="button_Help">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/help.ico</normaloff>:/icons/help.ico</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_Manual">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://huderlem.github.io/porymap/manual/scripting-capabilities.html"><span style=" text-decoration: underline; color:#0069d9;">Help</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_ListHeader">
|
||||
<property name="text">
|
||||
@@ -142,32 +149,32 @@
|
||||
<item>
|
||||
<widget class="QListWidget" name="list">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragOnly</enum>
|
||||
<enum>QAbstractItemView::DragDropMode::DragOnly</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::IgnoreAction</enum>
|
||||
<enum>Qt::DropAction::IgnoreAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
<enum>QAbstractItemView::SelectionMode::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="textElideMode">
|
||||
<enum>Qt::ElideLeft</enum>
|
||||
<enum>Qt::TextElideMode::ElideLeft</enum>
|
||||
</property>
|
||||
<property name="movement">
|
||||
<enum>QListView::Free</enum>
|
||||
<enum>QListView::Movement::Free</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
275
forms/gridsettingsdialog.ui
Normal file
@@ -0,0 +1,275 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GridSettingsDialog</class>
|
||||
<widget class="QDialog" name="GridSettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>331</width>
|
||||
<height>467</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Grid Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>305</width>
|
||||
<height>401</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="4" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_Color">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_Style">
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::SizeAdjustPolicy::AdjustToContentsOnFirstShow</enum>
|
||||
</property>
|
||||
<property name="minimumContentsLength">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_Style">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Style</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_Dimensions">
|
||||
<property name="title">
|
||||
<string>Dimensions (in pixels)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,1,5">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QToolButton" name="button_LinkDimensions">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/link_broken.ico</normaloff>
|
||||
<normalon>:/icons/link.ico</normalon>:/icons/link_broken.ico</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::ToolButtonPopupMode::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="NoScrollSpinBox" name="spinBox_Height">
|
||||
<property name="minimum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_Height">
|
||||
<property name="text">
|
||||
<string>Height</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_Width">
|
||||
<property name="text">
|
||||
<string>Width</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="NoScrollSpinBox" name="spinBox_Width">
|
||||
<property name="minimum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_Offset">
|
||||
<property name="title">
|
||||
<string>Offset (in pixels)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,1,5">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_Y">
|
||||
<property name="text">
|
||||
<string>Y</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_X">
|
||||
<property name="text">
|
||||
<string>X</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="NoScrollSpinBox" name="spinBox_Y">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="NoScrollSpinBox" name="spinBox_X">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QToolButton" name="button_LinkOffsets">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/link_broken.ico</normaloff>
|
||||
<normalon>:/icons/link.ico</normalon>:/icons/link_broken.ico</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::ToolButtonPopupMode::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="ColorInputWidget" name="colorInput">
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok|QDialogButtonBox::StandardButton::RestoreDefaults</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>NoScrollSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>noscrollspinbox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>NoScrollComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>noscrollcombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ColorInputWidget</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header>colorinputwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources/images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>696</width>
|
||||
<height>396</height>
|
||||
<width>817</width>
|
||||
<height>535</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -16,15 +16,313 @@
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<layout class="QGridLayout" name="gridLayout_4" columnstretch="2,1">
|
||||
<item row="1" column="1">
|
||||
<widget class="QFrame" name="frame_Options">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Options">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Map</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_MapSelection">
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::SizeAdjustPolicy::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_Events">
|
||||
<property name="title">
|
||||
<string>Events</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_Event_Options">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_Triggers">
|
||||
<property name="text">
|
||||
<string>Triggers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_Objects">
|
||||
<property name="text">
|
||||
<string>Objects</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="checkBox_HealLocations">
|
||||
<property name="text">
|
||||
<string>Heal Locations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="checkBox_Warps">
|
||||
<property name="text">
|
||||
<string>Warps</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_AllEvents">
|
||||
<property name="text">
|
||||
<string>All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_BGs">
|
||||
<property name="text">
|
||||
<string>BGs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_Connections">
|
||||
<property name="title">
|
||||
<string>Connections</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_Connection_Options">
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="checkBox_ConnectionLeft">
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_ConnectionUp">
|
||||
<property name="text">
|
||||
<string>Up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QCheckBox" name="checkBox_ConnectionRight">
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_ConnectionDown">
|
||||
<property name="text">
|
||||
<string>Down</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_AllConnections">
|
||||
<property name="text">
|
||||
<string>All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_Misc">
|
||||
<property name="title">
|
||||
<string>Miscellaneous</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_Misc_Options">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_Grid">
|
||||
<property name="text">
|
||||
<string>Grid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_Elevation">
|
||||
<property name="text">
|
||||
<string>Collision</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_Border">
|
||||
<property name="text">
|
||||
<string>Border</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_Timelapse">
|
||||
<property name="title">
|
||||
<string>Timelapse</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_TimelapseDelay">
|
||||
<property name="specialValueText">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string>ms</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>200</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Frame Delay</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_FrameSkip">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Edit Frame Skip</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_ActualSize">
|
||||
<property name="text">
|
||||
<string>Preview actual size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Reset">
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Cancel">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Save">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_Preview">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Preview</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<widget class="QScrollArea" name="scrollArea_Preview">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@@ -33,12 +331,24 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>403</width>
|
||||
<height>343</height>
|
||||
<width>469</width>
|
||||
<height>464</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="4">
|
||||
<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="2" column="3">
|
||||
<widget class="QGraphicsView" name="graphicsView_Preview">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
@@ -53,65 +363,13 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
||||
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored</enum>
|
||||
</property>
|
||||
<property name="dragMode">
|
||||
<enum>QGraphicsView::NoDrag</enum>
|
||||
<enum>QGraphicsView::DragMode::NoDrag</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4">
|
||||
<spacer name="verticalSpacer_South">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<spacer name="verticalSpacer_North">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="5">
|
||||
<spacer name="horizontalSpacer_West">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="horizontalSpacer_East">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
@@ -119,256 +377,18 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Options">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Map</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_MapSelection">
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_Events">
|
||||
<property name="title">
|
||||
<string>Events</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_Event_Options">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_Warps">
|
||||
<property name="text">
|
||||
<string>Warps</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_Objects">
|
||||
<property name="text">
|
||||
<string>Objects</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="checkBox_BGs">
|
||||
<property name="text">
|
||||
<string>BGs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_Triggers">
|
||||
<property name="text">
|
||||
<string>Triggers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_HealSpots">
|
||||
<property name="text">
|
||||
<string>Heal Spots</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_Connections">
|
||||
<property name="title">
|
||||
<string>Connections</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_Connection_Options">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_ConnectionUp">
|
||||
<property name="text">
|
||||
<string>Up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_ConnectionDown">
|
||||
<property name="text">
|
||||
<string>Down</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="checkBox_ConnectionLeft">
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QCheckBox" name="checkBox_ConnectionRight">
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_Misc">
|
||||
<property name="title">
|
||||
<string>Miscellaneous</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_Misc_Options">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_Grid">
|
||||
<property name="text">
|
||||
<string>Grid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_Elevation">
|
||||
<property name="text">
|
||||
<string>Collision</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_Border">
|
||||
<property name="text">
|
||||
<string>Border</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_Timelapse">
|
||||
<property name="title">
|
||||
<string>Timelapse</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_TimelapseDelay">
|
||||
<property name="specialValueText">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string>ms</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>200</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Frame Delay</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_FrameSkip">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Edit Frame Skip</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Reset">
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Cancel">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Save">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_Description">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
175
forms/maplisttoolbar.ui
Normal file
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MapListToolBar</class>
|
||||
<widget class="QFrame" name="MapListToolBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>274</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="button_AddFolder">
|
||||
<property name="toolTip">
|
||||
<string>Add a new folder to the list.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/folder_add.ico</normaloff>:/icons/folder_add.ico</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::ToolButtonPopupMode::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="button_ToggleEmptyFolders">
|
||||
<property name="text">
|
||||
<string>Hide empty folders in the list.</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/folder_eye_open.ico</normaloff>
|
||||
<normalon>:/icons/folder_eye_closed.ico</normalon>:/icons/folder_eye_open.ico</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::ToolButtonPopupMode::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="button_ExpandAll">
|
||||
<property name="toolTip">
|
||||
<string>Expand all folders in the list.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/expand_all.ico</normaloff>:/icons/expand_all.ico</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::ToolButtonPopupMode::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="button_CollapseAll">
|
||||
<property name="toolTip">
|
||||
<string>Collapse all folders in the list.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/collapse_all.ico</normaloff>:/icons/collapse_all.ico</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::ToolButtonPopupMode::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="button_ToggleEdit">
|
||||
<property name="toolTip">
|
||||
<string>If enabled, folders may be renamed and items in the list may be rearranged.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/lock_edit.ico</normaloff>
|
||||
<normalon>:/icons/unlock_edit.ico</normalon>:/icons/lock_edit.ico</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::ToolButtonPopupMode::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>12</width>
|
||||
<height>19</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_filterBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Filter...</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>410</width>
|
||||
<height>621</height>
|
||||
<height>687</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -73,14 +73,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Width">
|
||||
<property name="text">
|
||||
<string>Map Width</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_NewMap_Width">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Width (in blocks) of the new map.</p></body></html></string>
|
||||
@@ -90,14 +90,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Height">
|
||||
<property name="text">
|
||||
<string>Map Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_NewMap_Height">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Height (in blocks) of the new map.</p></body></html></string>
|
||||
@@ -107,14 +107,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_BorderWidth">
|
||||
<property name="text">
|
||||
<string>Border Width</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_NewMap_BorderWidth">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Width (in blocks) of the new map's border.</p></body></html></string>
|
||||
@@ -124,14 +124,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_BorderHeight">
|
||||
<property name="text">
|
||||
<string>Border Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_NewMap_BorderHeight">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Height (in blocks) of the new map's border.</p></body></html></string>
|
||||
@@ -141,14 +141,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Primary_Tileset">
|
||||
<property name="text">
|
||||
<string>Primary Tileset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_NewMap_Primary_Tileset">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The primary tileset for the new map.</p></body></html></string>
|
||||
@@ -158,14 +158,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Secondary_Tileset">
|
||||
<property name="text">
|
||||
<string>Secondary Tileset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_NewMap_Secondary_Tileset">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The secondary tileset for the new map.</p></body></html></string>
|
||||
@@ -175,14 +175,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Type">
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_NewMap_Type">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The map type is a general attribute, which is used for many different things. For example. it determines whether biking or running is allowed.</p></body></html></string>
|
||||
@@ -192,14 +192,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Location">
|
||||
<property name="text">
|
||||
<string>Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="11" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_NewMap_Location">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The section of the region map which the map is grouped under. This also determines the name of the map that is displayed when the player enters it.</p></body></html></string>
|
||||
@@ -209,14 +209,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_Song">
|
||||
<property name="text">
|
||||
<string>Song</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<item row="12" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_NewMap_Song">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The default background music for this map.</p></body></html></string>
|
||||
@@ -226,14 +226,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Flyable">
|
||||
<property name="text">
|
||||
<string>Can Fly To</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="13" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_NewMap_Flyable">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Whether to add a heal location to the new map.</p></body></html></string>
|
||||
@@ -243,14 +243,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<item row="14" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Show_Location">
|
||||
<property name="text">
|
||||
<string>Show Location Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<item row="14" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_NewMap_Show_Location">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Whether or not to display the location name when the player enters the map.</p></body></html></string>
|
||||
@@ -260,14 +260,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<item row="15" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Allow_Running">
|
||||
<property name="text">
|
||||
<string>Allow Running</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<item row="15" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_NewMap_Allow_Running">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Allows the player to use Running Shoes</p></body></html></string>
|
||||
@@ -277,14 +277,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<item row="16" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Allow_Biking">
|
||||
<property name="text">
|
||||
<string>Allow Biking</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<item row="16" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_NewMap_Allow_Biking">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Allows the player to use a Bike</p></body></html></string>
|
||||
@@ -294,14 +294,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<item row="17" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Allow_Escape_Rope">
|
||||
<property name="text">
|
||||
<string>Allow Dig & Escape Rope</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<item row="17" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_NewMap_Allow_Escape_Rope">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Allows the player to use Dig or Escape Rope</p></body></html></string>
|
||||
@@ -311,14 +311,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<item row="18" column="0">
|
||||
<widget class="QLabel" name="label_NewMap_Floor_Number">
|
||||
<property name="text">
|
||||
<string>Floor Number</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<item row="18" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_NewMap_Floor_Number">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Floor number to be used for maps with elevators.</p></body></html></string>
|
||||
@@ -328,6 +328,96 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_Layout">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Layout</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Use Existing Layout</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_UseExistingLayout">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -396,7 +486,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>410</width>
|
||||
<height>21</height>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
<item row="1" column="6">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -194,10 +194,10 @@
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
<enum>QSizePolicy::Policy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -276,10 +276,10 @@
|
||||
<string notr="true">.QFrame { border: 1px solid red; }</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
@@ -287,7 +287,6 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
@@ -319,7 +318,7 @@
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -338,7 +337,7 @@
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -567,10 +566,10 @@
|
||||
<string notr="true">.QFrame { border: 1px solid red; }</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_18">
|
||||
<item>
|
||||
@@ -578,7 +577,6 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
@@ -693,7 +691,7 @@
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -712,7 +710,7 @@
|
||||
<item>
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -783,10 +781,10 @@
|
||||
<string notr="true">.QFrame { border: 1px solid red; }</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
<item>
|
||||
@@ -794,7 +792,6 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
@@ -839,10 +836,10 @@
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
<enum>QSizePolicy::Policy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -924,10 +921,10 @@
|
||||
<item row="9" column="0">
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
<enum>QSizePolicy::Policy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -975,7 +972,7 @@
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -1212,7 +1209,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
<set>Qt::TextInteractionFlag::NoTextInteraction</set>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Use the dropbown and buttons to add behaviors to the list...</string>
|
||||
@@ -1242,10 +1239,10 @@
|
||||
<string notr="true">.QFrame { border: 1px solid red; }</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_15">
|
||||
<item>
|
||||
@@ -1253,7 +1250,6 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
@@ -1316,7 +1312,7 @@
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -1335,7 +1331,7 @@
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -1372,18 +1368,13 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_ProjectFilesHelp">
|
||||
<widget class="QToolButton" name="button_HelpFiles">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://huderlem.github.io/porymap/manual/project-files.html#files"><span style=" text-decoration: underline; color:#0069d9;">Help</span></a></p></body></html></string>
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/help.ico</normaloff>:/icons/help.ico</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1419,7 +1410,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>533</width>
|
||||
<height>440</height>
|
||||
<height>428</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="layout_ProjectPaths">
|
||||
@@ -1466,18 +1457,13 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_IdentifiersHelp">
|
||||
<widget class="QToolButton" name="button_HelpIdentifiers">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://huderlem.github.io/porymap/manual/project-files.html#identifiers"><span style=" text-decoration: underline; color:#0069d9;">Help</span></a></p></body></html></string>
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/images.qrc">
|
||||
<normaloff>:/icons/help.ico</normaloff>:/icons/help.ico</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1513,7 +1499,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>533</width>
|
||||
<height>440</height>
|
||||
<height>428</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="layout_Identifiers">
|
||||
@@ -1544,7 +1530,7 @@
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok|QDialogButtonBox::StandardButton::RestoreDefaults</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -22,12 +22,6 @@ static const QVersionNumber porymapVersion = QVersionNumber::fromString(PORYMAP_
|
||||
|
||||
#define CONFIG_BACKWARDS_COMPATABILITY
|
||||
|
||||
enum MapSortOrder {
|
||||
Group = 0,
|
||||
Area = 1,
|
||||
Layout = 2,
|
||||
};
|
||||
|
||||
class KeyValueConfigBase
|
||||
{
|
||||
public:
|
||||
@@ -56,7 +50,7 @@ public:
|
||||
this->recentProjects.clear();
|
||||
this->projectManuallyClosed = false;
|
||||
this->reopenOnLaunch = true;
|
||||
this->mapSortOrder = MapSortOrder::Group;
|
||||
this->mapListTab = 0;
|
||||
this->prettyCursors = true;
|
||||
this->mirrorConnectingMaps = true;
|
||||
this->showDiveEmergeMaps = false;
|
||||
@@ -107,7 +101,7 @@ public:
|
||||
|
||||
bool reopenOnLaunch;
|
||||
bool projectManuallyClosed;
|
||||
MapSortOrder mapSortOrder;
|
||||
int mapListTab;
|
||||
bool prettyCursors;
|
||||
bool mirrorConnectingMaps;
|
||||
bool showDiveEmergeMaps;
|
||||
@@ -219,7 +213,6 @@ enum ProjectIdentifier {
|
||||
define_map_empty,
|
||||
define_map_section_prefix,
|
||||
define_map_section_empty,
|
||||
define_map_section_count,
|
||||
define_species_prefix,
|
||||
regex_behaviors,
|
||||
regex_obj_event_gfx,
|
||||
@@ -275,7 +268,6 @@ enum ProjectFilePath {
|
||||
constants_obj_event_movement,
|
||||
constants_obj_events,
|
||||
constants_event_bg,
|
||||
constants_region_map_sections,
|
||||
constants_metatile_labels,
|
||||
constants_metatile_behaviors,
|
||||
constants_species,
|
||||
@@ -406,7 +398,7 @@ public:
|
||||
reset();
|
||||
}
|
||||
virtual void reset() override {
|
||||
this->recentMap = QString();
|
||||
this->recentMapOrLayout = QString();
|
||||
this->useEncounterJson = true;
|
||||
this->customScripts.clear();
|
||||
this->readKeys.clear();
|
||||
@@ -418,7 +410,7 @@ public:
|
||||
QList<bool> getCustomScriptsEnabled();
|
||||
|
||||
QString projectDir;
|
||||
QString recentMap;
|
||||
QString recentMapOrLayout;
|
||||
bool useEncounterJson;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
|
||||
class MapPixmapItem;
|
||||
class Map;
|
||||
class Layout;
|
||||
class Blockdata;
|
||||
class Event;
|
||||
class DraggablePixmapItem;
|
||||
@@ -24,9 +24,9 @@ enum CommandId {
|
||||
ID_PaintCollision,
|
||||
ID_BucketFillCollision,
|
||||
ID_MagicFillCollision,
|
||||
ID_ResizeMap,
|
||||
ID_ResizeLayout,
|
||||
ID_PaintBorder,
|
||||
ID_ScriptEditMap,
|
||||
ID_ScriptEditLayout,
|
||||
ID_EventMove,
|
||||
ID_EventShift,
|
||||
ID_EventCreate,
|
||||
@@ -50,7 +50,7 @@ enum CommandId {
|
||||
/// onto the map using the pencil tool.
|
||||
class PaintMetatile : public QUndoCommand {
|
||||
public:
|
||||
PaintMetatile(Map *map,
|
||||
PaintMetatile(Layout *layout,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
unsigned actionId, QUndoCommand *parent = nullptr);
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
int id() const override { return CommandId::ID_PaintMetatile; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
Layout *layout;
|
||||
|
||||
Blockdata newMetatiles;
|
||||
Blockdata oldMetatiles;
|
||||
@@ -75,10 +75,10 @@ private:
|
||||
/// on the metatile collision and elevation.
|
||||
class PaintCollision : public PaintMetatile {
|
||||
public:
|
||||
PaintCollision(Map *map,
|
||||
PaintCollision(Layout *layout,
|
||||
const Blockdata &oldCollision, const Blockdata &newCollision,
|
||||
unsigned actionId, QUndoCommand *parent = nullptr)
|
||||
: PaintMetatile(map, oldCollision, newCollision, actionId, parent) {
|
||||
: PaintMetatile(layout, oldCollision, newCollision, actionId, parent) {
|
||||
setText("Paint Collision");
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
/// Implements a command to commit paint actions on the map border.
|
||||
class PaintBorder : public QUndoCommand {
|
||||
public:
|
||||
PaintBorder(Map *map,
|
||||
PaintBorder(Layout *layout,
|
||||
const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||
unsigned actionId, QUndoCommand *parent = nullptr);
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
int id() const override { return CommandId::ID_PaintBorder; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
Layout *layout;
|
||||
|
||||
Blockdata newBorder;
|
||||
Blockdata oldBorder;
|
||||
@@ -115,10 +115,10 @@ private:
|
||||
/// with the bucket tool onto the map.
|
||||
class BucketFillMetatile : public PaintMetatile {
|
||||
public:
|
||||
BucketFillMetatile(Map *map,
|
||||
BucketFillMetatile(Layout *layout,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
unsigned actionId, QUndoCommand *parent = nullptr)
|
||||
: PaintMetatile(map, oldMetatiles, newMetatiles, actionId, parent) {
|
||||
: PaintMetatile(layout, oldMetatiles, newMetatiles, actionId, parent) {
|
||||
setText("Bucket Fill Metatiles");
|
||||
}
|
||||
|
||||
@@ -131,10 +131,10 @@ public:
|
||||
/// on the metatile collision and elevation.
|
||||
class BucketFillCollision : public PaintCollision {
|
||||
public:
|
||||
BucketFillCollision(Map *map,
|
||||
BucketFillCollision(Layout *layout,
|
||||
const Blockdata &oldCollision, const Blockdata &newCollision,
|
||||
QUndoCommand *parent = nullptr)
|
||||
: PaintCollision(map, oldCollision, newCollision, -1, parent) {
|
||||
: PaintCollision(layout, oldCollision, newCollision, -1, parent) {
|
||||
setText("Flood Fill Collision");
|
||||
}
|
||||
|
||||
@@ -148,10 +148,10 @@ public:
|
||||
/// with the bucket or paint tool onto the map.
|
||||
class MagicFillMetatile : public PaintMetatile {
|
||||
public:
|
||||
MagicFillMetatile(Map *map,
|
||||
MagicFillMetatile(Layout *layout,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
unsigned actionId, QUndoCommand *parent = nullptr)
|
||||
: PaintMetatile(map, oldMetatiles, newMetatiles, actionId, parent) {
|
||||
: PaintMetatile(layout, oldMetatiles, newMetatiles, actionId, parent) {
|
||||
setText("Magic Fill Metatiles");
|
||||
}
|
||||
|
||||
@@ -163,10 +163,10 @@ public:
|
||||
/// Implements a command to commit magic fill collision actions.
|
||||
class MagicFillCollision : public PaintCollision {
|
||||
public:
|
||||
MagicFillCollision(Map *map,
|
||||
MagicFillCollision(Layout *layout,
|
||||
const Blockdata &oldCollision, const Blockdata &newCollision,
|
||||
QUndoCommand *parent = nullptr)
|
||||
: PaintCollision(map, oldCollision, newCollision, -1, parent) {
|
||||
: PaintCollision(layout, oldCollision, newCollision, -1, parent) {
|
||||
setText("Magic Fill Collision");
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ public:
|
||||
/// Implements a command to commit metatile shift actions.
|
||||
class ShiftMetatiles : public QUndoCommand {
|
||||
public:
|
||||
ShiftMetatiles(Map *map,
|
||||
ShiftMetatiles(Layout *layout,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
unsigned actionId, QUndoCommand *parent = nullptr);
|
||||
|
||||
@@ -190,7 +190,7 @@ public:
|
||||
int id() const override { return CommandId::ID_ShiftMetatiles; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
Layout *layout= nullptr;
|
||||
|
||||
Blockdata newMetatiles;
|
||||
Blockdata oldMetatiles;
|
||||
@@ -201,9 +201,9 @@ private:
|
||||
|
||||
|
||||
/// Implements a command to commit a map or border resize action.
|
||||
class ResizeMap : public QUndoCommand {
|
||||
class ResizeLayout : public QUndoCommand {
|
||||
public:
|
||||
ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
|
||||
ResizeLayout(Layout *layout, QSize oldLayoutDimensions, QSize newLayoutDimensions,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||
const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||
@@ -213,15 +213,15 @@ public:
|
||||
void redo() override;
|
||||
|
||||
bool mergeWith(const QUndoCommand *) override { return false; }
|
||||
int id() const override { return CommandId::ID_ResizeMap; }
|
||||
int id() const override { return CommandId::ID_ResizeLayout; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
Layout *layout = nullptr;
|
||||
|
||||
int oldMapWidth;
|
||||
int oldMapHeight;
|
||||
int newMapWidth;
|
||||
int newMapHeight;
|
||||
int oldLayoutWidth;
|
||||
int oldLayoutHeight;
|
||||
int newLayoutWidth;
|
||||
int newLayoutHeight;
|
||||
|
||||
int oldBorderWidth;
|
||||
int oldBorderHeight;
|
||||
@@ -351,10 +351,10 @@ public:
|
||||
|
||||
/// Implements a command to commit map edits from the scripting API.
|
||||
/// The scripting api can edit map/border blocks and dimensions.
|
||||
class ScriptEditMap : public QUndoCommand {
|
||||
class ScriptEditLayout : public QUndoCommand {
|
||||
public:
|
||||
ScriptEditMap(Map *map,
|
||||
QSize oldMapDimensions, QSize newMapDimensions,
|
||||
ScriptEditLayout(Layout *layout,
|
||||
QSize oldLayoutDimensions, QSize newLayoutDimensions,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||
const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||
@@ -364,10 +364,10 @@ public:
|
||||
void redo() override;
|
||||
|
||||
bool mergeWith(const QUndoCommand *) override { return false; }
|
||||
int id() const override { return CommandId::ID_ScriptEditMap; }
|
||||
int id() const override { return CommandId::ID_ScriptEditLayout; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
Layout *layout = nullptr;
|
||||
|
||||
Blockdata newMetatiles;
|
||||
Blockdata oldMetatiles;
|
||||
@@ -375,10 +375,10 @@ private:
|
||||
Blockdata newBorder;
|
||||
Blockdata oldBorder;
|
||||
|
||||
int oldMapWidth;
|
||||
int oldMapHeight;
|
||||
int newMapWidth;
|
||||
int newMapHeight;
|
||||
int oldLayoutWidth;
|
||||
int oldLayoutHeight;
|
||||
int newLayoutWidth;
|
||||
int newLayoutHeight;
|
||||
|
||||
int oldBorderWidth;
|
||||
int oldBorderHeight;
|
||||
|
||||
@@ -187,6 +187,7 @@ public:
|
||||
static QString eventGroupToString(Event::Group group);
|
||||
static QString eventTypeToString(Event::Type type);
|
||||
static Event::Type eventTypeFromString(QString type);
|
||||
static void clearIcons();
|
||||
static void setIcons();
|
||||
|
||||
// protected attributes
|
||||
|
||||
65
include/core/filedialog.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef FILEDIALOG_H
|
||||
#define FILEDIALOG_H
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
/*
|
||||
Static QFileDialog functions will (unless otherwise specified) use native file dialogs.
|
||||
In general this is good (we want our file dialogs to be visually seamless) but unfortunately
|
||||
the native file dialogs ignore the parent widget, so in some cases they'll return focus to
|
||||
the main window rather than the window that opened the file dialog.
|
||||
|
||||
To make working around this a little easier we use this class, which will use the native
|
||||
file dialog and manually return focus to the parent widget.
|
||||
|
||||
It will also save the directory of the previous file selected in a file dialog, and if
|
||||
no 'dir' argument is specified it will open new dialogs at that directory.
|
||||
|
||||
*/
|
||||
|
||||
class FileDialog : public QFileDialog
|
||||
{
|
||||
public:
|
||||
FileDialog(QWidget *parent, Qt::WindowFlags flags) : QFileDialog(parent, flags) {};
|
||||
FileDialog(QWidget *parent = nullptr,
|
||||
const QString &caption = QString(),
|
||||
const QString &directory = QString(),
|
||||
const QString &filter = QString()) : QFileDialog(parent, caption, directory, filter) {};
|
||||
|
||||
static void setDirectory(const QString &dir) { FileDialog::prevDirectory = dir; }
|
||||
static QString getDirectory() { return FileDialog::prevDirectory; }
|
||||
|
||||
static QString getOpenFileName(QWidget *parent = nullptr,
|
||||
const QString &caption = QString(),
|
||||
const QString &dir = QString(),
|
||||
const QString &filter = QString(),
|
||||
QString *selectedFilter = nullptr,
|
||||
QFileDialog::Options options = Options());
|
||||
|
||||
static QStringList getOpenFileNames(QWidget *parent = nullptr,
|
||||
const QString &caption = QString(),
|
||||
const QString &dir = QString(),
|
||||
const QString &filter = QString(),
|
||||
QString *selectedFilter = nullptr,
|
||||
QFileDialog::Options options = Options());
|
||||
|
||||
static QString getExistingDirectory(QWidget *parent = nullptr,
|
||||
const QString &caption = QString(),
|
||||
const QString &dir = QString(),
|
||||
QFileDialog::Options options = ShowDirsOnly);
|
||||
|
||||
static QString getSaveFileName(QWidget *parent = nullptr,
|
||||
const QString &caption = QString(),
|
||||
const QString &dir = QString(),
|
||||
const QString &filter = QString(),
|
||||
QString *selectedFilter = nullptr,
|
||||
QFileDialog::Options options = Options());
|
||||
|
||||
private:
|
||||
static QString prevDirectory;
|
||||
static QString getDirectoryFromInput(const QString &dir);
|
||||
static void setDirectoryFromFile(const QString &fileName);
|
||||
static void restoreFocus(QWidget *parent);
|
||||
};
|
||||
|
||||
#endif // FILEDIALOG_H
|
||||
@@ -25,7 +25,7 @@
|
||||
// porymap will reflect changes to it, but the value is hard-coded in the projects at the moment
|
||||
#define BORDER_DISTANCE 7
|
||||
|
||||
class MapPixmapItem;
|
||||
class LayoutPixmapItem;
|
||||
class CollisionPixmapItem;
|
||||
class BorderMetatilesPixmapItem;
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
public:
|
||||
QString name;
|
||||
QString constantName;
|
||||
|
||||
QString song;
|
||||
QString layoutId;
|
||||
QString location;
|
||||
@@ -51,20 +52,22 @@ public:
|
||||
bool allowEscaping;
|
||||
int floorNumber = 0;
|
||||
QString battle_scene;
|
||||
|
||||
QString sharedEventsMap = "";
|
||||
QString sharedScriptsMap = "";
|
||||
|
||||
QStringList scriptsFileLabels;
|
||||
QMap<QString, QJsonValue> customHeaders;
|
||||
MapLayout *layout;
|
||||
|
||||
Layout *layout = nullptr;
|
||||
void setLayout(Layout *layout);
|
||||
|
||||
bool isPersistedToFile = true;
|
||||
bool hasUnsavedDataChanges = false;
|
||||
|
||||
bool needsLayoutDir = true;
|
||||
bool needsHealLocation = false;
|
||||
bool scriptsLoaded = false;
|
||||
QImage collision_image;
|
||||
QPixmap collision_pixmap;
|
||||
QImage image;
|
||||
QPixmap pixmap;
|
||||
|
||||
QMap<Event::Group, QList<Event *>> events;
|
||||
QList<Event *> ownedEvents; // for memory management
|
||||
@@ -74,64 +77,34 @@ public:
|
||||
|
||||
void setName(QString mapName);
|
||||
static QString mapConstantFromName(QString mapName, bool includePrefix = true);
|
||||
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
int getBorderWidth();
|
||||
int getBorderHeight();
|
||||
QPixmap render(bool ignoreCache = false, MapLayout *fromLayout = nullptr, QRect bounds = QRect(0, 0, -1, -1));
|
||||
QPixmap renderCollision(bool ignoreCache);
|
||||
bool mapBlockChanged(int i, const Blockdata &cache);
|
||||
bool borderBlockChanged(int i, const Blockdata &cache);
|
||||
void cacheBlockdata();
|
||||
void cacheCollision();
|
||||
bool getBlock(int x, int y, Block *out);
|
||||
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
|
||||
void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false);
|
||||
uint16_t getBorderMetatileId(int x, int y);
|
||||
void setBorderMetatileId(int x, int y, uint16_t metatileId, bool enableScriptCallback = false);
|
||||
void setBorderBlockData(Blockdata blockdata, bool enableScriptCallback = false);
|
||||
void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
|
||||
void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
|
||||
void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
|
||||
|
||||
QList<Event *> getAllEvents() const;
|
||||
QStringList getScriptLabels(Event::Group group = Event::Group::None);
|
||||
QString getScriptsFilePath() const;
|
||||
void openScript(QString label);
|
||||
void removeEvent(Event *);
|
||||
void addEvent(Event *);
|
||||
|
||||
void deleteConnections();
|
||||
QList<MapConnection*> getConnections() const;
|
||||
void removeConnection(MapConnection *);
|
||||
void addConnection(MapConnection *);
|
||||
void loadConnection(MapConnection *);
|
||||
QRect getConnectionRect(const QString &direction, MapLayout *fromLayout = nullptr);
|
||||
QPixmap renderConnection(const QString &direction, MapLayout *fromLayout = nullptr);
|
||||
QPixmap renderBorder(bool ignoreCache = false);
|
||||
void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||
void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||
void clearBorderCache();
|
||||
void cacheBorder();
|
||||
bool hasUnsavedChanges();
|
||||
bool isWithinBounds(int x, int y);
|
||||
bool isWithinBorderBounds(int x, int y);
|
||||
void openScript(QString label);
|
||||
QString getScriptsFilePath() const;
|
||||
|
||||
MapPixmapItem *mapItem = nullptr;
|
||||
void setMapItem(MapPixmapItem *item) { mapItem = item; }
|
||||
|
||||
CollisionPixmapItem *collisionItem = nullptr;
|
||||
void setCollisionItem(CollisionPixmapItem *item) { collisionItem = item; }
|
||||
|
||||
BorderMetatilesPixmapItem *borderItem = nullptr;
|
||||
void setBorderItem(BorderMetatilesPixmapItem *item) { borderItem = item; }
|
||||
QRect getConnectionRect(const QString &direction, Layout *fromLayout = nullptr);
|
||||
QPixmap renderConnection(const QString &direction, Layout *fromLayout = nullptr);
|
||||
|
||||
QUndoStack editHistory;
|
||||
void modify();
|
||||
void clean();
|
||||
bool hasUnsavedChanges() const;
|
||||
void pruneEditHistory();
|
||||
|
||||
private:
|
||||
void setNewDimensionsBlockdata(int newWidth, int newHeight);
|
||||
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);
|
||||
void trackConnection(MapConnection*);
|
||||
|
||||
// MapConnections in 'ownedConnections' but not 'connections' persist in the edit history.
|
||||
@@ -141,7 +114,6 @@ private:
|
||||
signals:
|
||||
void modified();
|
||||
void mapDimensionsChanged(const QSize &size);
|
||||
void mapNeedsRedrawing();
|
||||
void openScriptRequested(QString label);
|
||||
void connectionAdded(MapConnection*);
|
||||
void connectionRemoved(MapConnection*);
|
||||
|
||||
@@ -7,41 +7,135 @@
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
#include <QString>
|
||||
#include <QUndoStack>
|
||||
|
||||
class MapLayout {
|
||||
class Map;
|
||||
class LayoutPixmapItem;
|
||||
class CollisionPixmapItem;
|
||||
class BorderMetatilesPixmapItem;
|
||||
|
||||
class Layout : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MapLayout() {}
|
||||
Layout() {}
|
||||
|
||||
static QString layoutConstantFromName(QString mapName);
|
||||
|
||||
bool loaded = false;
|
||||
|
||||
QString id;
|
||||
QString name;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int border_width;
|
||||
int border_height;
|
||||
|
||||
QString border_path;
|
||||
QString blockdata_path;
|
||||
|
||||
QString tileset_primary_label;
|
||||
QString tileset_secondary_label;
|
||||
|
||||
Tileset *tileset_primary = nullptr;
|
||||
Tileset *tileset_secondary = nullptr;
|
||||
|
||||
Blockdata blockdata;
|
||||
|
||||
QImage image;
|
||||
QPixmap pixmap;
|
||||
QImage border_image;
|
||||
QPixmap border_pixmap;
|
||||
QImage collision_image;
|
||||
QPixmap collision_pixmap;
|
||||
|
||||
Blockdata border;
|
||||
Blockdata cached_blockdata;
|
||||
Blockdata cached_collision;
|
||||
Blockdata cached_border;
|
||||
struct {
|
||||
Blockdata blocks;
|
||||
QSize mapDimensions;
|
||||
QSize layoutDimensions;
|
||||
Blockdata border;
|
||||
QSize borderDimensions;
|
||||
} lastCommitBlocks; // to track map changes
|
||||
|
||||
QList<int> metatileLayerOrder;
|
||||
QList<float> metatileLayerOpacity;
|
||||
|
||||
LayoutPixmapItem *layoutItem = nullptr;
|
||||
CollisionPixmapItem *collisionItem = nullptr;
|
||||
BorderMetatilesPixmapItem *borderItem = nullptr;
|
||||
|
||||
QUndoStack editHistory;
|
||||
|
||||
// to simplify new layout settings transfer between functions
|
||||
struct SimpleSettings {
|
||||
QString id;
|
||||
QString name;
|
||||
int width;
|
||||
int height;
|
||||
QString tileset_primary_label;
|
||||
QString tileset_secondary_label;
|
||||
QString from_id = QString();
|
||||
};
|
||||
|
||||
public:
|
||||
Layout *copy();
|
||||
void copyFrom(Layout *other);
|
||||
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
int getBorderWidth();
|
||||
int getBorderHeight();
|
||||
|
||||
bool isWithinBounds(int x, int y);
|
||||
bool isWithinBorderBounds(int x, int y);
|
||||
|
||||
bool getBlock(int x, int y, Block *out);
|
||||
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
|
||||
void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false);
|
||||
|
||||
void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||
void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||
|
||||
void cacheBlockdata();
|
||||
void cacheCollision();
|
||||
void clearBorderCache();
|
||||
void cacheBorder();
|
||||
|
||||
bool hasUnsavedChanges() const;
|
||||
|
||||
bool layoutBlockChanged(int i, const Blockdata &cache);
|
||||
|
||||
uint16_t getBorderMetatileId(int x, int y);
|
||||
void setBorderMetatileId(int x, int y, uint16_t metatileId, bool enableScriptCallback = false);
|
||||
void setBorderBlockData(Blockdata blockdata, bool enableScriptCallback = false);
|
||||
|
||||
void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
|
||||
void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
|
||||
void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
|
||||
|
||||
QPixmap render(bool ignoreCache = false, Layout *fromLayout = nullptr, QRect bounds = QRect(0, 0, -1, -1));
|
||||
QPixmap renderCollision(bool ignoreCache);
|
||||
// QPixmap renderConnection(MapConnection, Layout *);
|
||||
QPixmap renderBorder(bool ignoreCache = false);
|
||||
|
||||
QPixmap getLayoutItemPixmap();
|
||||
|
||||
void setLayoutItem(LayoutPixmapItem *item) { layoutItem = item; }
|
||||
void setCollisionItem(CollisionPixmapItem *item) { collisionItem = item; }
|
||||
void setBorderItem(BorderMetatilesPixmapItem *item) { borderItem = item; }
|
||||
|
||||
private:
|
||||
void setNewDimensionsBlockdata(int newWidth, int newHeight);
|
||||
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);
|
||||
|
||||
signals:
|
||||
void layoutChanged(Layout *layout);
|
||||
//void modified();
|
||||
void layoutDimensionsChanged(const QSize &size);
|
||||
void needsRedrawing();
|
||||
};
|
||||
|
||||
#endif // MAPLAYOUT_H
|
||||
|
||||
@@ -10,7 +10,7 @@ class MapParser
|
||||
{
|
||||
public:
|
||||
MapParser();
|
||||
MapLayout *parse(QString filepath, bool *error, Project *project);
|
||||
Layout *parse(QString filepath, bool *error, Project *project);
|
||||
};
|
||||
|
||||
#endif // MAPPARSER_H
|
||||
|
||||
@@ -104,7 +104,8 @@ private:
|
||||
};
|
||||
ParsedDefines readCDefines(const QString &filename, const QStringList &filterList, bool useRegex);
|
||||
QMap<QString, int> evaluateCDefines(const QString &filename, const QStringList &filterList, bool useRegex);
|
||||
bool defineNameMatchesFilter(const QString &name, const QStringList &filterList, bool useRegex);
|
||||
bool defineNameMatchesFilter(const QString &name, const QStringList &filterList) const;
|
||||
bool defineNameMatchesFilter(const QString &name, const QList<QRegularExpression> &filterList) const;
|
||||
|
||||
static const QRegularExpression re_incScriptLabel;
|
||||
static const QRegularExpression re_globalIncScriptLabel;
|
||||
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
bool loadLayout(poryjson::Json);
|
||||
bool loadEntries();
|
||||
|
||||
void setEntries(tsl::ordered_map<QString, MapSectionEntry> *entries) { this->region_map_entries = entries; }
|
||||
void setEntries(tsl::ordered_map<QString, MapSectionEntry> entries) { *(this->region_map_entries) = entries; }
|
||||
void setEntries(QMap<QString, MapSectionEntry> *entries) { this->region_map_entries = entries; }
|
||||
void setEntries(const QMap<QString, MapSectionEntry> &entries) { *(this->region_map_entries) = entries; }
|
||||
void clearEntries() { this->region_map_entries->clear(); }
|
||||
MapSectionEntry getEntry(QString section);
|
||||
void setEntry(QString section, MapSectionEntry entry);
|
||||
@@ -114,8 +114,6 @@ public:
|
||||
void setLayer(QString layer) { this->current_layer = layer; }
|
||||
QString getLayer() { return this->current_layer; }
|
||||
|
||||
QString fixCase(QString);
|
||||
|
||||
int padLeft() { return this->offset_left; }
|
||||
int padTop() { return this->offset_top; }
|
||||
int padRight() { return this->tilemap_width - this->layout_width - this->offset_left; }
|
||||
@@ -149,14 +147,12 @@ public:
|
||||
|
||||
const QString section_prefix;
|
||||
const QString default_map_section;
|
||||
const QString count_map_section;
|
||||
|
||||
signals:
|
||||
void mapNeedsDisplaying();
|
||||
|
||||
private:
|
||||
// TODO: defaults needed?
|
||||
tsl::ordered_map<QString, MapSectionEntry> *region_map_entries = nullptr;
|
||||
QMap<QString, MapSectionEntry> *region_map_entries = nullptr;
|
||||
|
||||
QString alias = "";
|
||||
|
||||
|
||||
@@ -64,9 +64,9 @@ private:
|
||||
|
||||
|
||||
/// Edit Layout Dimensions
|
||||
class ResizeLayout : public QUndoCommand {
|
||||
class ResizeRMLayout : public QUndoCommand {
|
||||
public:
|
||||
ResizeLayout(RegionMap *map, int oldWidth, int oldHeight, int newWidth, int newHeight,
|
||||
ResizeRMLayout(RegionMap *map, int oldWidth, int oldHeight, int newWidth, int newHeight,
|
||||
QMap<QString, QList<LayoutSquare>> oldLayouts, QMap<QString, QList<LayoutSquare>> newLayouts, QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
@@ -153,7 +153,7 @@ private:
|
||||
/// ClearEntries
|
||||
class ClearEntries : public QUndoCommand {
|
||||
public:
|
||||
ClearEntries(RegionMap *map, tsl::ordered_map<QString, MapSectionEntry>, QUndoCommand *parent = nullptr);
|
||||
ClearEntries(RegionMap *map, QMap<QString, MapSectionEntry>, QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
@@ -163,7 +163,7 @@ public:
|
||||
|
||||
private:
|
||||
RegionMap *map;
|
||||
tsl::ordered_map<QString, MapSectionEntry> entries;
|
||||
QMap<QString, MapSectionEntry> entries;
|
||||
};
|
||||
|
||||
#endif // REGIONMAPEDITCOMMANDS_H
|
||||
|
||||
@@ -18,6 +18,7 @@ public:
|
||||
Tileset() = default;
|
||||
Tileset(const Tileset &other);
|
||||
Tileset &operator=(const Tileset &other);
|
||||
~Tileset();
|
||||
|
||||
public:
|
||||
QString name;
|
||||
@@ -33,7 +34,6 @@ public:
|
||||
QStringList palettePaths;
|
||||
|
||||
QList<QImage> tiles;
|
||||
QList<Metatile*> metatiles;
|
||||
QHash<int, QString> metatileLabels;
|
||||
QList<QList<QRgb>> palettes;
|
||||
QList<QList<QRgb>> palettePreviews;
|
||||
@@ -59,6 +59,19 @@ public:
|
||||
bool appendToHeaders(QString root, QString friendlyName, bool usingAsm);
|
||||
bool appendToGraphics(QString root, QString friendlyName, bool usingAsm);
|
||||
bool appendToMetatiles(QString root, QString friendlyName, bool usingAsm);
|
||||
|
||||
void setMetatiles(const QList<Metatile*> &metatiles);
|
||||
void addMetatile(Metatile* metatile);
|
||||
|
||||
QList<Metatile*> metatiles() const { return m_metatiles; }
|
||||
Metatile* metatileAt(unsigned int i) const { return m_metatiles.at(i); }
|
||||
|
||||
void clearMetatiles();
|
||||
void resizeMetatiles(unsigned int newNumMetatiles);
|
||||
int numMetatiles() const { return m_metatiles.length(); }
|
||||
|
||||
private:
|
||||
QList<Metatile*> m_metatiles;
|
||||
};
|
||||
|
||||
#endif // TILESET_H
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
struct WildPokemon {
|
||||
int minLevel = 5;
|
||||
int maxLevel = 5;
|
||||
QString species = "SPECIES_NONE";
|
||||
QString species = "SPECIES_NONE"; // TODO: Use define_species_prefix
|
||||
};
|
||||
|
||||
struct WildMonInfo {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <QCheckBox>
|
||||
#include <QCursor>
|
||||
#include <QUndoGroup>
|
||||
#include <QPointer>
|
||||
|
||||
#include "mapconnection.h"
|
||||
#include "metatileselector.h"
|
||||
@@ -21,8 +22,9 @@
|
||||
#include "divingmappixmapitem.h"
|
||||
#include "currentselectedmetatilespixmapitem.h"
|
||||
#include "collisionpixmapitem.h"
|
||||
#include "mappixmapitem.h"
|
||||
#include "layoutpixmapitem.h"
|
||||
#include "settings.h"
|
||||
#include "gridsettings.h"
|
||||
#include "movablerect.h"
|
||||
#include "cursortilerect.h"
|
||||
#include "mapruler.h"
|
||||
@@ -45,17 +47,33 @@ public:
|
||||
public:
|
||||
Ui::MainWindow* ui;
|
||||
QObject *parent = nullptr;
|
||||
|
||||
QPointer<Project> project = nullptr;
|
||||
Map *map = nullptr;
|
||||
QPointer<Map> map = nullptr;
|
||||
QPointer<Layout> layout = nullptr;
|
||||
|
||||
QUndoGroup editGroup; // Manages the undo history for each map
|
||||
|
||||
Settings *settings;
|
||||
GridSettings gridSettings;
|
||||
|
||||
void setProject(Project * project);
|
||||
void saveProject();
|
||||
void save();
|
||||
void closeProject();
|
||||
bool setMap(QString map_name);
|
||||
void saveProject();
|
||||
void saveUiFields();
|
||||
void saveEncounterTabData();
|
||||
|
||||
void closeProject();
|
||||
|
||||
bool setMap(QString map_name);
|
||||
bool setLayout(QString layoutName);
|
||||
void unsetMap();
|
||||
|
||||
Tileset *getCurrentMapPrimaryTileset();
|
||||
|
||||
bool displayMap();
|
||||
bool displayLayout();
|
||||
|
||||
void displayMetatileSelector();
|
||||
void displayMapMetatiles();
|
||||
void displayMapMovementPermissions();
|
||||
@@ -67,61 +85,60 @@ public:
|
||||
void displayMapConnections();
|
||||
void displayMapBorder();
|
||||
void displayMapGrid();
|
||||
void updateMapGrid();
|
||||
void displayWildMonTables();
|
||||
|
||||
void updateMapBorder();
|
||||
void updateMapConnections();
|
||||
|
||||
void setEditingMap();
|
||||
void setEditingCollision();
|
||||
void setEditingObjects();
|
||||
void setEditingConnections();
|
||||
void setMapEditingButtonsEnabled(bool enabled);
|
||||
void setConnectionsVisibility(bool visible);
|
||||
void updateDivingMapsVisibility();
|
||||
void renderDivingConnections();
|
||||
void addConnection(MapConnection* connection);
|
||||
void removeConnection(MapConnection* connection);
|
||||
void removeSelectedConnection();
|
||||
void addNewWildMonGroup(QWidget *window);
|
||||
void deleteWildMonGroup();
|
||||
void configureEncounterJSON(QWidget *);
|
||||
EncounterTableModel* getCurrentWildMonTable();
|
||||
void updateDiveMap(QString mapName);
|
||||
void updateEmergeMap(QString mapName);
|
||||
void setSelectedConnection(MapConnection *connection);
|
||||
|
||||
void updatePrimaryTileset(QString tilesetLabel, bool forceLoad = false);
|
||||
void updateSecondaryTileset(QString tilesetLabel, bool forceLoad = false);
|
||||
void toggleBorderVisibility(bool visible, bool enableScriptCallback = true);
|
||||
void updateCustomMapHeaderValues(QTableWidget *);
|
||||
void configureEncounterJSON(QWidget *);
|
||||
Tileset *getCurrentMapPrimaryTileset();
|
||||
|
||||
DraggablePixmapItem *addMapEvent(Event *event);
|
||||
bool eventLimitReached(Map *, Event::Type);
|
||||
void selectMapEvent(DraggablePixmapItem *object, bool toggle = false);
|
||||
DraggablePixmapItem *addNewEvent(Event::Type type);
|
||||
void updateSelectedEvents();
|
||||
void duplicateSelectedEvents();
|
||||
void redrawObject(DraggablePixmapItem *item);
|
||||
QList<DraggablePixmapItem *> getObjects();
|
||||
|
||||
void updateCursorRectPos(int x, int y);
|
||||
void setCursorRectVisible(bool visible);
|
||||
|
||||
void updateWarpEventWarning(Event *event);
|
||||
void updateWarpEventWarnings();
|
||||
bool eventLimitReached(Map *, Event::Type);
|
||||
|
||||
QPointer<QGraphicsScene> scene = nullptr;
|
||||
QGraphicsPixmapItem *current_view = nullptr;
|
||||
QPointer<MapPixmapItem> map_item = nullptr;
|
||||
QPointer<LayoutPixmapItem> map_item = nullptr;
|
||||
QList<QPointer<ConnectionPixmapItem>> connection_items;
|
||||
QMap<QString, QPointer<DivingMapPixmapItem>> diving_map_items;
|
||||
QGraphicsPathItem *connection_mask = nullptr;
|
||||
QPointer<CollisionPixmapItem> collision_item = nullptr;
|
||||
QGraphicsItemGroup *events_group = nullptr;
|
||||
|
||||
QList<QGraphicsPixmapItem*> borderItems;
|
||||
QList<QGraphicsLineItem*> gridLines;
|
||||
QGraphicsItemGroup *mapGrid = nullptr;
|
||||
MapRuler *map_ruler = nullptr;
|
||||
|
||||
MovableRect *playerViewRect = nullptr;
|
||||
CursorTileRect *cursorMapTileRect = nullptr;
|
||||
MapRuler *map_ruler = nullptr;
|
||||
|
||||
QPointer<QGraphicsScene> scene_metatiles = nullptr;
|
||||
QPointer<QGraphicsScene> scene_current_metatile_selection = nullptr;
|
||||
@@ -137,8 +154,27 @@ public:
|
||||
QPointer<ConnectionPixmapItem> selected_connection_item = nullptr;
|
||||
QPointer<MapConnection> connection_to_select = nullptr;
|
||||
|
||||
QString map_edit_mode = "paint";
|
||||
QString obj_edit_mode = "select";
|
||||
enum class EditAction { None, Paint, Select, Fill, Shift, Pick, Move };
|
||||
EditAction mapEditAction = EditAction::Paint;
|
||||
EditAction objectEditAction = EditAction::Select;
|
||||
|
||||
enum class EditMode { None, Disabled, Metatiles, Collision, Header, Events, Connections, Encounters };
|
||||
EditMode editMode = EditMode::None;
|
||||
void setEditMode(EditMode mode) { this->editMode = mode; }
|
||||
EditMode getEditMode() { return this->editMode; }
|
||||
|
||||
bool getEditingLayout();
|
||||
|
||||
void setEditorView();
|
||||
|
||||
void setEditingMetatiles();
|
||||
void setEditingCollision();
|
||||
void setEditingHeader();
|
||||
void setEditingObjects();
|
||||
void setEditingConnections();
|
||||
void setEditingEncounters();
|
||||
|
||||
void setMapEditingButtonsEnabled(bool enabled);
|
||||
|
||||
int scaleIndex = 2;
|
||||
qreal collisionOpacity = 0.5;
|
||||
@@ -148,10 +184,9 @@ public:
|
||||
|
||||
int getBorderDrawDistance(int dimension);
|
||||
|
||||
QUndoGroup editGroup; // Manages the undo history for each map
|
||||
|
||||
bool selectingEvent = false;
|
||||
|
||||
void deleteSelectedEvents();
|
||||
void shouldReselectEvents();
|
||||
void scaleMapView(int);
|
||||
static void openInTextEditor(const QString &path, int lineNum = 0);
|
||||
@@ -165,6 +200,7 @@ public slots:
|
||||
void maskNonVisibleConnectionTiles();
|
||||
void onBorderMetatilesChanged();
|
||||
void selectedEventIndexChanged(int index, Event::Group eventGroup);
|
||||
void toggleGrid(bool);
|
||||
|
||||
private:
|
||||
const QImage defaultCollisionImgSheet = QImage(":/images/collisions.png");
|
||||
@@ -202,11 +238,11 @@ private:
|
||||
qint64 *pid = nullptr);
|
||||
|
||||
private slots:
|
||||
void onMapStartPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
|
||||
void onMapEndPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
|
||||
void onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
|
||||
void onMapEndPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
|
||||
void setSmartPathCursorMode(QGraphicsSceneMouseEvent *event);
|
||||
void setStraightPathCursorMode(QGraphicsSceneMouseEvent *event);
|
||||
void mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
|
||||
void mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
|
||||
void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item);
|
||||
void setSelectedConnectionItem(ConnectionPixmapItem *connectionItem);
|
||||
void onHoveredMovementPermissionChanged(uint16_t, uint16_t);
|
||||
@@ -219,7 +255,6 @@ private slots:
|
||||
void onHoveredMapMovementPermissionCleared();
|
||||
void onSelectedMetatilesChanged();
|
||||
void onWheelZoom(int);
|
||||
void onToggleGridClicked(bool);
|
||||
|
||||
signals:
|
||||
void objectsChanged();
|
||||
@@ -231,6 +266,7 @@ signals:
|
||||
void currentMetatilesSelectionChanged();
|
||||
void mapRulerStatusChanged(const QString &);
|
||||
void tilesetUpdated(QString);
|
||||
void gridToggled(bool);
|
||||
};
|
||||
|
||||
#endif // EDITOR_H
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
|
||||
namespace fex
|
||||
{
|
||||
@@ -89,9 +90,7 @@ namespace fex
|
||||
Lexer() = default;
|
||||
~Lexer() = default;
|
||||
|
||||
std::vector<Token> LexFile(const std::string &path);
|
||||
std::vector<Token> LexString(const std::string &data);
|
||||
void LexFileDumpTokens(const std::string &path, const std::string &out);
|
||||
std::vector<Token> LexFile(const QString &path);
|
||||
|
||||
private:
|
||||
std::vector<Token> Lex();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace fex
|
||||
std::vector<Array> ParseTopLevelArrays(std::vector<Token> tokens);
|
||||
std::map<std::string, ArrayValue> ParseTopLevelObjects(std::vector<Token> tokens);
|
||||
|
||||
std::map<std::string, int> ReadDefines(const std::string &filename, std::vector<std::string> matching);
|
||||
std::map<std::string, int> ReadDefines(const QString &filename, std::vector<std::string> matching);
|
||||
|
||||
private:
|
||||
int EvaluateExpression(std::vector<Token> tokens);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef PARSER_UTIL_H
|
||||
#define PARSER_UTIL_H
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
class ParserUtil
|
||||
{
|
||||
public:
|
||||
ParserUtil(QString root);
|
||||
QStringList ReadDefines(QString filename, QString prefix);
|
||||
QStringList ReadDefinesValueSort(QString filename, QString prefix);
|
||||
|
||||
private:
|
||||
QString root_;
|
||||
};
|
||||
|
||||
|
||||
#endif // PARSER_UTIL_H
|
||||
@@ -21,11 +21,13 @@
|
||||
#include "regionmapeditor.h"
|
||||
#include "mapimageexporter.h"
|
||||
#include "filterchildrenproxymodel.h"
|
||||
#include "maplistmodels.h"
|
||||
#include "newmappopup.h"
|
||||
#include "newtilesetdialog.h"
|
||||
#include "shortcutseditor.h"
|
||||
#include "preferenceeditor.h"
|
||||
#include "projectsettingseditor.h"
|
||||
#include "gridsettings.h"
|
||||
#include "customscriptseditor.h"
|
||||
#include "wildmonchart.h"
|
||||
#include "updatepromoter.h"
|
||||
@@ -165,13 +167,14 @@ public slots:
|
||||
void on_mainTabBar_tabBarClicked(int index);
|
||||
void on_mapViewTab_tabBarClicked(int index);
|
||||
void onWarpBehaviorWarningClicked();
|
||||
void clearOverlay();
|
||||
|
||||
private slots:
|
||||
void on_action_Open_Project_triggered();
|
||||
void on_action_Reload_Project_triggered();
|
||||
void on_action_Close_Project_triggered();
|
||||
void on_mapList_activated(const QModelIndex &index);
|
||||
void on_action_Save_Project_triggered();
|
||||
|
||||
void openWarpMap(QString map_name, int event_id, Event::Group event_group);
|
||||
|
||||
void duplicate();
|
||||
@@ -180,16 +183,17 @@ private slots:
|
||||
void copy();
|
||||
void paste();
|
||||
|
||||
void onLayoutChanged(Layout *layout);
|
||||
void onOpenConnectedMap(MapConnection*);
|
||||
void onMapNeedsRedrawing();
|
||||
void onTilesetsSaved(QString, QString);
|
||||
void openNewMapPopupWindow();
|
||||
void onNewMapCreated();
|
||||
void onMapCacheCleared();
|
||||
void onMapLoaded(Map *map);
|
||||
void importMapFromAdvanceMap1_92();
|
||||
void onMapRulerStatusChanged(const QString &);
|
||||
void applyUserShortcuts();
|
||||
void markMapEdited();
|
||||
void markSpecificMapEdited(Map*);
|
||||
|
||||
void on_action_NewMap_triggered();
|
||||
void on_actionNew_Tileset_triggered();
|
||||
@@ -200,6 +204,7 @@ private slots:
|
||||
void on_comboBox_Weather_currentTextChanged(const QString &arg1);
|
||||
void on_comboBox_Type_currentTextChanged(const QString &arg1);
|
||||
void on_comboBox_BattleScene_currentTextChanged(const QString &arg1);
|
||||
void on_comboBox_LayoutSelector_currentTextChanged(const QString &arg1);
|
||||
void on_checkBox_ShowLocation_stateChanged(int selected);
|
||||
void on_checkBox_AllowRunning_stateChanged(int selected);
|
||||
void on_checkBox_AllowBiking_stateChanged(int selected);
|
||||
@@ -219,9 +224,6 @@ private slots:
|
||||
void on_actionMove_triggered();
|
||||
void on_actionMap_Shift_triggered();
|
||||
|
||||
void onDeleteKeyPressed();
|
||||
void on_toolButton_deleteObject_clicked();
|
||||
|
||||
void addNewEvent(Event::Type type);
|
||||
void tryAddEventTab(QWidget * tab);
|
||||
void displayEventTabs();
|
||||
@@ -236,9 +238,6 @@ private slots:
|
||||
void on_toolButton_Shift_clicked();
|
||||
|
||||
void onOpenMapListContextMenu(const QPoint &point);
|
||||
void onAddNewMapToGroupClick(QAction* triggeredAction);
|
||||
void onAddNewMapToAreaClick(QAction* triggeredAction);
|
||||
void onAddNewMapToLayoutClick(QAction* triggeredAction);
|
||||
void currentMetatilesSelectionChanged();
|
||||
|
||||
void on_action_Export_Map_Image_triggered();
|
||||
@@ -262,10 +261,6 @@ private slots:
|
||||
|
||||
void on_actionTileset_Editor_triggered();
|
||||
|
||||
void mapSortOrder_changed(QAction *action);
|
||||
|
||||
void on_lineEdit_filterBox_textChanged(const QString &arg1);
|
||||
|
||||
void moveEvent(QMoveEvent *event);
|
||||
void closeEvent(QCloseEvent *);
|
||||
|
||||
@@ -278,8 +273,11 @@ private slots:
|
||||
void on_slider_DiveMapOpacity_valueChanged(int value);
|
||||
void on_slider_EmergeMapOpacity_valueChanged(int value);
|
||||
void on_horizontalSlider_CollisionTransparency_valueChanged(int value);
|
||||
void on_toolButton_ExpandAll_clicked();
|
||||
void on_toolButton_CollapseAll_clicked();
|
||||
|
||||
void mapListShortcut_ToggleEmptyFolders();
|
||||
void mapListShortcut_ExpandAll();
|
||||
void mapListShortcut_CollapseAll();
|
||||
|
||||
void on_actionAbout_Porymap_triggered();
|
||||
void on_actionOpen_Log_File_triggered();
|
||||
void on_actionOpen_Config_Folder_triggered();
|
||||
@@ -302,6 +300,8 @@ private slots:
|
||||
void on_actionProject_Settings_triggered();
|
||||
void on_actionCustom_Scripts_triggered();
|
||||
void reloadScriptEngine();
|
||||
void on_actionShow_Grid_triggered();
|
||||
void on_actionGrid_Settings_triggered();
|
||||
|
||||
public:
|
||||
Ui::MainWindow *ui;
|
||||
@@ -316,16 +316,20 @@ private:
|
||||
QPointer<NewMapPopup> newMapPrompt = nullptr;
|
||||
QPointer<PreferenceEditor> preferenceEditor = nullptr;
|
||||
QPointer<ProjectSettingsEditor> projectSettingsEditor = nullptr;
|
||||
QPointer<GridSettingsDialog> gridSettingsDialog = nullptr;
|
||||
QPointer<CustomScriptsEditor> customScriptsEditor = nullptr;
|
||||
|
||||
QPointer<FilterChildrenProxyModel> groupListProxyModel = nullptr;
|
||||
QPointer<MapGroupModel> mapGroupModel = nullptr;
|
||||
QPointer<FilterChildrenProxyModel> areaListProxyModel = nullptr;
|
||||
QPointer<MapAreaModel> mapAreaModel = nullptr;
|
||||
QPointer<FilterChildrenProxyModel> layoutListProxyModel = nullptr;
|
||||
QPointer<LayoutTreeModel> layoutTreeModel = nullptr;
|
||||
|
||||
QPointer<UpdatePromoter> updatePromoter = nullptr;
|
||||
QPointer<NetworkAccessManager> networkAccessManager = nullptr;
|
||||
QPointer<AboutPorymap> aboutWindow = nullptr;
|
||||
QPointer<WildMonChart> wildMonChart = nullptr;
|
||||
FilterChildrenProxyModel *mapListProxyModel;
|
||||
QStandardItemModel *mapListModel;
|
||||
QList<QStandardItem*> *mapGroupItemsList;
|
||||
QMap<QString, QModelIndex> mapListIndexes;
|
||||
QIcon mapIcon;
|
||||
|
||||
QAction *undoAction = nullptr;
|
||||
QAction *redoAction = nullptr;
|
||||
@@ -337,48 +341,61 @@ private:
|
||||
|
||||
bool isProgrammaticEventTabChange;
|
||||
bool newMapDefaultsSet = false;
|
||||
|
||||
bool tilesetNeedsRedraw = false;
|
||||
|
||||
bool userSetMap(QString, bool scrollTreeView = false);
|
||||
bool setMap(QString, bool scrollTreeView = false);
|
||||
bool setLayout(QString layoutId);
|
||||
bool setMap(QString);
|
||||
void unsetMap();
|
||||
bool userSetLayout(QString layoutId);
|
||||
bool userSetMap(QString);
|
||||
void redrawMapScene();
|
||||
void refreshMapScene();
|
||||
void setLayoutOnlyMode(bool layoutOnly);
|
||||
|
||||
bool checkProjectSanity();
|
||||
bool loadProjectData();
|
||||
bool setProjectUI();
|
||||
void clearProjectUI();
|
||||
void sortMapList();
|
||||
|
||||
void openSubWindow(QWidget * window);
|
||||
void scrollMapList(MapTree *list, QString itemName);
|
||||
void scrollMapListToCurrentMap(MapTree *list);
|
||||
void scrollMapListToCurrentLayout(MapTree *list);
|
||||
void resetMapListFilters();
|
||||
void showFileWatcherWarning(QString filepath);
|
||||
QString getExistingDirectory(QString);
|
||||
bool openProject(QString dir, bool initial = false);
|
||||
bool closeProject();
|
||||
void showProjectOpenFailure();
|
||||
void saveGlobalConfigs();
|
||||
|
||||
bool setInitialMap();
|
||||
QStandardItem* createMapItem(QString mapName, int groupNum, int inGroupNum);
|
||||
void saveGlobalConfigs();
|
||||
|
||||
void refreshRecentProjectsMenu();
|
||||
|
||||
void updateMapListIcon(const QString &mapName);
|
||||
void updateMapList();
|
||||
void mapListAddGroup();
|
||||
void mapListAddLayout();
|
||||
void mapListAddArea();
|
||||
void openMapListItem(const QModelIndex &index);
|
||||
void saveMapListTab(int index);
|
||||
|
||||
void displayMapProperties();
|
||||
void checkToolButtons();
|
||||
void clickToolButtonFromEditMode(QString editMode);
|
||||
void clickToolButtonFromEditAction(Editor::EditAction editAction);
|
||||
|
||||
void markMapEdited();
|
||||
void markMapEdited(Map*);
|
||||
void showWindowTitle();
|
||||
void updateWindowTitle();
|
||||
|
||||
void initWindow();
|
||||
void initCustomUI();
|
||||
void initExtraSignals();
|
||||
void initEditor();
|
||||
void initMiscHeapObjects();
|
||||
void initMapSortOrder();
|
||||
void initMapList();
|
||||
void initShortcuts();
|
||||
void initExtraShortcuts();
|
||||
void loadUserSettings();
|
||||
void applyMapListFilter(QString filterText);
|
||||
void restoreWindowState();
|
||||
void setTheme(QString);
|
||||
void updateTilesetEditor();
|
||||
@@ -398,6 +415,9 @@ private:
|
||||
double getMetatilesZoomScale();
|
||||
void redrawMetatileSelection();
|
||||
void scrollMetatileSelectorToSelection();
|
||||
MapListToolBar* getCurrentMapListToolBar();
|
||||
MapTree* getCurrentMapList();
|
||||
void refreshLocationsComboBox();
|
||||
|
||||
QObjectList shortcutableObjects() const;
|
||||
void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false);
|
||||
@@ -407,12 +427,6 @@ private:
|
||||
void setDivingMapsVisible(bool visible);
|
||||
};
|
||||
|
||||
enum MapListUserRoles {
|
||||
GroupRole = Qt::UserRole + 1, // Used to hold the map group number.
|
||||
TypeRole, // Used to differentiate between the different layers of the map list tree view.
|
||||
TypeRole2, // Used for various extra data needed.
|
||||
};
|
||||
|
||||
// These are namespaced in a struct to avoid colliding with e.g. class Map.
|
||||
struct MainTab {
|
||||
enum {
|
||||
@@ -432,4 +446,10 @@ struct MapViewTab {
|
||||
};
|
||||
};
|
||||
|
||||
struct MapListTab {
|
||||
enum {
|
||||
Groups = 0, Areas, Layouts
|
||||
};
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -25,7 +25,7 @@ class Project : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Project(QWidget *parent = nullptr);
|
||||
Project(QObject *parent = nullptr);
|
||||
~Project();
|
||||
|
||||
Project(const Project &) = delete;
|
||||
@@ -46,11 +46,9 @@ public:
|
||||
QStringList mapLayoutsTable;
|
||||
QStringList mapLayoutsTableMaster;
|
||||
QString layoutsLabel;
|
||||
QMap<QString, MapLayout*> mapLayouts;
|
||||
QMap<QString, MapLayout*> mapLayoutsMaster;
|
||||
QMap<QString, QString> mapSecToMapHoverName;
|
||||
QMap<QString, int> mapSectionNameToValue;
|
||||
QMap<int, QString> mapSectionValueToName;
|
||||
QMap<QString, QString> layoutIdsToNames;
|
||||
QMap<QString, Layout*> mapLayouts;
|
||||
QMap<QString, Layout*> mapLayoutsMaster;
|
||||
QMap<QString, EventGraphics*> eventGraphicsMap;
|
||||
QMap<QString, int> gfxDefines;
|
||||
QString defaultSong;
|
||||
@@ -67,6 +65,8 @@ public:
|
||||
QStringList bgEventFacingDirections;
|
||||
QStringList trainerTypes;
|
||||
QStringList globalScriptLabels;
|
||||
QStringList mapSectionIdNames;
|
||||
QMap<QString, MapSectionEntry> regionMapEntries;
|
||||
QMap<QString, QMap<QString, uint16_t>> metatileLabelsMap;
|
||||
QMap<QString, uint16_t> unusedMetatileLabels;
|
||||
QMap<QString, uint32_t> metatileBehaviorMap;
|
||||
@@ -76,19 +76,19 @@ public:
|
||||
QFileSystemWatcher fileWatcher;
|
||||
QMap<QString, qint64> modifiedFileTimestamps;
|
||||
bool usingAsmTilesets;
|
||||
QString importExportPath;
|
||||
QSet<QString> disabledSettingsNames;
|
||||
int pokemonMinLevel;
|
||||
int pokemonMaxLevel;
|
||||
int maxEncounterRate;
|
||||
bool wildEncountersLoaded;
|
||||
bool saveEmptyMapsec;
|
||||
|
||||
void set_root(QString);
|
||||
|
||||
void initSignals();
|
||||
|
||||
void clearMapCache();
|
||||
void clearTilesetCache();
|
||||
void clearMapLayouts();
|
||||
void clearEventGraphics();
|
||||
|
||||
struct DataQualifiers
|
||||
{
|
||||
@@ -114,8 +114,8 @@ public:
|
||||
QStringList tilesetLabelsOrdered;
|
||||
|
||||
Blockdata readBlockdata(QString);
|
||||
bool loadBlockdata(MapLayout*);
|
||||
bool loadLayoutBorder(MapLayout*);
|
||||
bool loadBlockdata(Layout *);
|
||||
bool loadLayoutBorder(Layout *);
|
||||
|
||||
void saveTextFile(QString path, QString text);
|
||||
void appendTextFile(QString path, QString text);
|
||||
@@ -139,12 +139,20 @@ public:
|
||||
bool readSpeciesIconPaths();
|
||||
QMap<QString, QString> speciesToIconPath;
|
||||
|
||||
void addNewMapsec(const QString &name);
|
||||
void removeMapsec(const QString &name);
|
||||
|
||||
bool hasUnsavedChanges();
|
||||
bool hasUnsavedDataChanges = false;
|
||||
|
||||
QSet<QString> getTopLevelMapFields();
|
||||
bool loadMapData(Map*);
|
||||
bool readMapLayouts();
|
||||
bool loadLayout(MapLayout *);
|
||||
Layout *loadLayout(QString layoutId);
|
||||
Layout *createNewLayout(Layout::SimpleSettings &layoutSettings);
|
||||
bool loadLayout(Layout *);
|
||||
bool loadMapLayout(Map*);
|
||||
bool loadLayoutTilesets(MapLayout*);
|
||||
bool loadLayoutTilesets(Layout *);
|
||||
void loadTilesetAssets(Tileset*);
|
||||
void loadTilesetTiles(Tileset*, QImage);
|
||||
void loadTilesetMetatiles(Tileset*);
|
||||
@@ -152,15 +160,17 @@ public:
|
||||
void loadTilesetPalettes(Tileset*);
|
||||
void readTilesetPaths(Tileset* tileset);
|
||||
|
||||
void saveLayoutBlockdata(Map*);
|
||||
void saveLayoutBorder(Map*);
|
||||
void saveLayout(Layout *);
|
||||
void saveLayoutBlockdata(Layout *);
|
||||
void saveLayoutBorder(Layout *);
|
||||
void writeBlockdata(QString, const Blockdata &);
|
||||
void saveAllMaps();
|
||||
void saveMap(Map*);
|
||||
void saveMap(Map *);
|
||||
void saveAllDataStructures();
|
||||
void saveConfig();
|
||||
void saveMapLayouts();
|
||||
void saveMapGroups();
|
||||
void saveRegionMapSections();
|
||||
void saveWildMonData();
|
||||
void saveMapConstantsHeader();
|
||||
void saveHealLocations(Map*);
|
||||
@@ -214,7 +224,6 @@ public:
|
||||
QString buildMetatileLabelsText(const QMap<QString, uint16_t> defines);
|
||||
QString findMetatileLabelsTileset(QString label);
|
||||
|
||||
void setImportExportPath(QString filename);
|
||||
static QString getExistingFilepath(QString filepath);
|
||||
void applyParsedLimits();
|
||||
|
||||
@@ -232,12 +241,13 @@ public:
|
||||
static bool mapDimensionsValid(int width, int height);
|
||||
bool calculateDefaultMapSize();
|
||||
static int getMaxObjectEvents();
|
||||
static QString getEmptyMapsecName();
|
||||
|
||||
private:
|
||||
void updateMapLayout(Map*);
|
||||
void updateLayout(Layout *);
|
||||
|
||||
void setNewMapBlockdata(Map* map);
|
||||
void setNewMapBorder(Map *map);
|
||||
void setNewLayoutBlockdata(Layout *layout);
|
||||
void setNewLayoutBorder(Layout *layout);
|
||||
void setNewMapEvents(Map *map);
|
||||
void setNewMapConnections(Map *map);
|
||||
|
||||
@@ -256,9 +266,8 @@ private:
|
||||
static int max_object_events;
|
||||
|
||||
signals:
|
||||
void reloadProject();
|
||||
void uncheckMonitorFilesAction();
|
||||
void mapCacheCleared();
|
||||
void fileChanged(QString filepath);
|
||||
void mapSectionIdNamesChanged();
|
||||
void mapLoaded(Map *map);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
#ifndef BORDERMETATILESPIXMAPITEM_H
|
||||
#define BORDERMETATILESPIXMAPITEM_H
|
||||
|
||||
#include "map.h"
|
||||
#include "maplayout.h"
|
||||
#include "metatileselector.h"
|
||||
#include <QGraphicsPixmapItem>
|
||||
|
||||
class BorderMetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
BorderMetatilesPixmapItem(Map *map_, MetatileSelector *metatileSelector) {
|
||||
this->map = map_;
|
||||
this->map->setBorderItem(this);
|
||||
BorderMetatilesPixmapItem(Layout *layout, MetatileSelector *metatileSelector) {
|
||||
this->layout = layout;
|
||||
this->layout->setBorderItem(this);
|
||||
this->metatileSelector = metatileSelector;
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
MetatileSelector *metatileSelector;
|
||||
Map *map;
|
||||
Layout *layout;
|
||||
void draw();
|
||||
signals:
|
||||
void hoveredBorderMetatileSelectionChanged(uint16_t);
|
||||
|
||||
@@ -4,19 +4,20 @@
|
||||
#include <QSpinBox>
|
||||
|
||||
#include "metatileselector.h"
|
||||
#include "mappixmapitem.h"
|
||||
#include "movementpermissionsselector.h"
|
||||
#include "layoutpixmapitem.h"
|
||||
#include "map.h"
|
||||
#include "settings.h"
|
||||
|
||||
class CollisionPixmapItem : public MapPixmapItem {
|
||||
class CollisionPixmapItem : public LayoutPixmapItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CollisionPixmapItem(Map *map, QSpinBox * selectedCollision, QSpinBox * selectedElevation, MetatileSelector *metatileSelector, Settings *settings, qreal *opacity)
|
||||
: MapPixmapItem(map, metatileSelector, settings){
|
||||
CollisionPixmapItem(Layout *layout, QSpinBox * selectedCollision, QSpinBox * selectedElevation, MetatileSelector *metatileSelector, Settings *settings, qreal *opacity)
|
||||
: LayoutPixmapItem(layout, metatileSelector, settings){
|
||||
this->selectedCollision = selectedCollision;
|
||||
this->selectedElevation = selectedElevation;
|
||||
this->opacity = opacity;
|
||||
map->setCollisionItem(this);
|
||||
layout->setCollisionItem(this);
|
||||
}
|
||||
QSpinBox * selectedCollision;
|
||||
QSpinBox * selectedElevation;
|
||||
|
||||
46
include/ui/colorinputwidget.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef COLORINPUTWIDGET_H
|
||||
#define COLORINPUTWIDGET_H
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QValidator>
|
||||
|
||||
namespace Ui {
|
||||
class ColorInputWidget;
|
||||
}
|
||||
|
||||
|
||||
class ColorInputWidget : public QGroupBox {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ColorInputWidget(QWidget *parent = nullptr);
|
||||
explicit ColorInputWidget(const QString &title, QWidget *parent = nullptr);
|
||||
~ColorInputWidget();
|
||||
|
||||
void setColor(QRgb color);
|
||||
QRgb color() const { return m_color; }
|
||||
|
||||
bool setBitDepth(int bits);
|
||||
int bitDepth() const { return m_bitDepth; }
|
||||
|
||||
signals:
|
||||
void colorChanged(QRgb color);
|
||||
void bitDepthChanged(int bits);
|
||||
void editingFinished();
|
||||
|
||||
private:
|
||||
Ui::ColorInputWidget *ui;
|
||||
|
||||
QRgb m_color = 0;
|
||||
int m_bitDepth = 0;
|
||||
|
||||
void init();
|
||||
void updateColorUi();
|
||||
void pickColor();
|
||||
void blockEditSignals(bool block);
|
||||
|
||||
void setRgbFromSliders();
|
||||
void setRgbFromSpinners();
|
||||
void setRgbFromHexString(const QString &);
|
||||
};
|
||||
|
||||
#endif // COLORINPUTWIDGET_H
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QPainter>
|
||||
#include <QPointer>
|
||||
#include <QKeyEvent>
|
||||
|
||||
class ConnectionPixmapItem : public QObject, public QGraphicsPixmapItem {
|
||||
Q_OBJECT
|
||||
@@ -36,14 +37,17 @@ private:
|
||||
static const int mHeight = 16;
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent*) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override;
|
||||
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
|
||||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
|
||||
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override;
|
||||
virtual void keyPressEvent(QKeyEvent*) override;
|
||||
virtual void focusInEvent(QFocusEvent*) override;
|
||||
|
||||
signals:
|
||||
void connectionItemDoubleClicked(MapConnection*);
|
||||
void selectionChanged(bool selected);
|
||||
void deleteRequested(MapConnection*);
|
||||
};
|
||||
|
||||
#endif // CONNECTIONPIXMAPITEM_H
|
||||
|
||||
@@ -34,11 +34,12 @@ private:
|
||||
unsigned actionId = 0;
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent*) override;
|
||||
virtual void mousePressEvent(QMouseEvent*) override;
|
||||
virtual void focusInEvent(QFocusEvent*) override;
|
||||
virtual void keyPressEvent(QKeyEvent*) override;
|
||||
|
||||
signals:
|
||||
void selected();
|
||||
void removed(MapConnection*);
|
||||
void openMapClicked(MapConnection*);
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
#ifndef CURRENTSELECTEDMETATILESPIXMAPITEM_H
|
||||
#define CURRENTSELECTEDMETATILESPIXMAPITEM_H
|
||||
|
||||
#include "map.h"
|
||||
#include "metatileselector.h"
|
||||
#include <QGraphicsPixmapItem>
|
||||
|
||||
class Layout;
|
||||
|
||||
class CurrentSelectedMetatilesPixmapItem : public QGraphicsPixmapItem {
|
||||
public:
|
||||
CurrentSelectedMetatilesPixmapItem(Map *map, MetatileSelector *metatileSelector) {
|
||||
this->map = map;
|
||||
CurrentSelectedMetatilesPixmapItem(Layout *layout, MetatileSelector *metatileSelector) {
|
||||
this->layout = layout;
|
||||
this->metatileSelector = metatileSelector;
|
||||
}
|
||||
Map* map = nullptr;
|
||||
Layout *layout = nullptr;
|
||||
MetatileSelector *metatileSelector;
|
||||
void draw();
|
||||
|
||||
void setMap(Map *map) { this->map = map; }
|
||||
void setLayout(Layout *layout) { this->layout = layout; }
|
||||
};
|
||||
|
||||
QPixmap drawMetatileSelection(MetatileSelection selection, Map *map);
|
||||
QPixmap drawMetatileSelection(MetatileSelection selection, Layout *layout);
|
||||
|
||||
#endif // CURRENTSELECTEDMETATILESPIXMAPITEM_H
|
||||
|
||||
@@ -31,7 +31,6 @@ private:
|
||||
Ui::CustomScriptsEditor *ui;
|
||||
|
||||
bool hasUnsavedChanges = false;
|
||||
QString fileDialogDir;
|
||||
const QString baseDir;
|
||||
|
||||
void displayScript(const QString &filepath, bool enabled);
|
||||
@@ -50,6 +49,7 @@ private:
|
||||
void restoreWindowState();
|
||||
void initShortcuts();
|
||||
QObjectList shortcutableObjects() const;
|
||||
void openManual();
|
||||
|
||||
private slots:
|
||||
void dialogButtonClicked(QAbstractButton *button);
|
||||
|
||||
28
include/ui/eventfilters.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <QObject>
|
||||
#include <QEvent>
|
||||
|
||||
|
||||
|
||||
/// Prevent wheel scroll
|
||||
class WheelFilter : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
WheelFilter(QObject *parent) : QObject(parent) {}
|
||||
virtual ~WheelFilter() {}
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Ctrl+Wheel = zoom
|
||||
class MapSceneEventFilter : public QObject {
|
||||
Q_OBJECT
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
public:
|
||||
explicit MapSceneEventFilter(QObject *parent = nullptr) : QObject(parent) {}
|
||||
|
||||
signals:
|
||||
void wheelZoom(int delta);
|
||||
public slots:
|
||||
};
|
||||
@@ -9,9 +9,11 @@ class FilterChildrenProxyModel : public QSortFilterProxyModel
|
||||
|
||||
public:
|
||||
explicit FilterChildrenProxyModel(QObject *parent = nullptr);
|
||||
void setHideEmpty(bool hidden) { this->hideEmpty = hidden; }
|
||||
protected:
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const;
|
||||
|
||||
private:
|
||||
bool hideEmpty = false;
|
||||
};
|
||||
|
||||
#endif // FILTERCHILDRENPROXYMODEL_H
|
||||
|
||||
@@ -34,6 +34,7 @@ signals:
|
||||
|
||||
class Editor;
|
||||
|
||||
// TODO: This should just be MapView. It makes map-based assumptions, and no other class inherits GraphicsView.
|
||||
class GraphicsView : public QGraphicsView
|
||||
{
|
||||
public:
|
||||
@@ -44,10 +45,10 @@ public:
|
||||
// GraphicsView_Object object;
|
||||
Editor *editor;
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void moveEvent(QMoveEvent *event);
|
||||
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
};
|
||||
|
||||
//Q_DECLARE_METATYPE(GraphicsView)
|
||||
|
||||
99
include/ui/gridsettings.h
Normal file
@@ -0,0 +1,99 @@
|
||||
#ifndef GRIDSETTINGS_H
|
||||
#define GRIDSETTINGS_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAbstractButton>
|
||||
|
||||
class GridSettings {
|
||||
public:
|
||||
explicit GridSettings() {};
|
||||
~GridSettings() {};
|
||||
|
||||
enum Style {
|
||||
Solid,
|
||||
LargeDashes,
|
||||
SmallDashes,
|
||||
Crosshairs,
|
||||
Dots,
|
||||
};
|
||||
|
||||
uint width = 16;
|
||||
uint height = 16;
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
Style style = Style::Solid;
|
||||
QColor color = Qt::black;
|
||||
QVector<qreal> getHorizontalDashPattern() const { return this->getDashPattern(this->width); }
|
||||
QVector<qreal> getVerticalDashPattern() const { return this->getDashPattern(this->height); }
|
||||
|
||||
static QString getStyleName(Style style);
|
||||
static GridSettings::Style getStyleFromName(const QString &name);
|
||||
private:
|
||||
static const QMap<Style, QString> styleToName;
|
||||
|
||||
QVector<qreal> getCenteredDashPattern(uint length, qreal dashLength, qreal gapLength) const;
|
||||
QVector<qreal> getDashPattern(uint length) const;
|
||||
};
|
||||
|
||||
inline bool operator==(const GridSettings &a, const GridSettings &b) {
|
||||
return a.width == b.width
|
||||
&& a.height == b.height
|
||||
&& a.offsetX == b.offsetX
|
||||
&& a.offsetY == b.offsetY
|
||||
&& a.style == b.style
|
||||
&& a.color == b.color;
|
||||
}
|
||||
|
||||
inline bool operator!=(const GridSettings &a, const GridSettings &b) {
|
||||
return !(operator==(a, b));
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class GridSettingsDialog;
|
||||
}
|
||||
|
||||
class GridSettingsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GridSettingsDialog(QWidget *parent = nullptr);
|
||||
explicit GridSettingsDialog(GridSettings *settings, QWidget *parent = nullptr);
|
||||
~GridSettingsDialog();
|
||||
|
||||
void setSettings(const GridSettings &settings);
|
||||
GridSettings settings() const { return *m_settings; }
|
||||
|
||||
void setDefaultSettings(const GridSettings &settings);
|
||||
GridSettings defaultSettings() const { return m_defaultSettings; }
|
||||
|
||||
signals:
|
||||
void changedGridSettings();
|
||||
|
||||
private:
|
||||
Ui::GridSettingsDialog *ui;
|
||||
GridSettings *const m_settings;
|
||||
const GridSettings m_originalSettings;
|
||||
GridSettings m_defaultSettings;
|
||||
bool m_dimensionsLinked = true;
|
||||
bool m_offsetsLinked = true;
|
||||
bool m_ownedSettings = false;
|
||||
|
||||
void init();
|
||||
void updateInput();
|
||||
void setWidth(int value);
|
||||
void setHeight(int value);
|
||||
void setOffsetX(int value);
|
||||
void setOffsetY(int value);
|
||||
|
||||
private slots:
|
||||
void dialogButtonClicked(QAbstractButton *button);
|
||||
void on_spinBox_Width_valueChanged(int value);
|
||||
void on_spinBox_Height_valueChanged(int value);
|
||||
void on_spinBox_X_valueChanged(int value);
|
||||
void on_spinBox_Y_valueChanged(int value);
|
||||
void on_comboBox_Style_currentTextChanged(const QString &text);
|
||||
void onColorChanged(QRgb color);
|
||||
};
|
||||
|
||||
#endif // GRIDSETTINGS_H
|
||||
@@ -1,54 +1,58 @@
|
||||
#ifndef MAPPIXMAPITEM_H
|
||||
#define MAPPIXMAPITEM_H
|
||||
|
||||
#include "map.h"
|
||||
#include "settings.h"
|
||||
#include "metatileselector.h"
|
||||
#include <QGraphicsPixmapItem>
|
||||
|
||||
class MapPixmapItem : public QObject, public QGraphicsPixmapItem {
|
||||
class Layout;
|
||||
|
||||
class LayoutPixmapItem : public QObject, public QGraphicsPixmapItem {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using QGraphicsPixmapItem::paint;
|
||||
|
||||
public:
|
||||
enum class PaintMode {
|
||||
Disabled,
|
||||
Metatiles,
|
||||
EventObjects
|
||||
};
|
||||
MapPixmapItem(Map *map_, MetatileSelector *metatileSelector, Settings *settings) {
|
||||
this->map = map_;
|
||||
this->map->setMapItem(this);
|
||||
LayoutPixmapItem(Layout *layout, MetatileSelector *metatileSelector, Settings *settings) {
|
||||
this->layout = layout;
|
||||
// this->map->setMapItem(this);
|
||||
this->metatileSelector = metatileSelector;
|
||||
this->settings = settings;
|
||||
this->paintingMode = PaintMode::Metatiles;
|
||||
this->lockedAxis = MapPixmapItem::Axis::None;
|
||||
this->lockedAxis = LayoutPixmapItem::Axis::None;
|
||||
this->prevStraightPathState = false;
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
MapPixmapItem::PaintMode paintingMode;
|
||||
Map *map;
|
||||
|
||||
Layout *layout;
|
||||
|
||||
MetatileSelector *metatileSelector;
|
||||
|
||||
Settings *settings;
|
||||
|
||||
bool active;
|
||||
bool has_mouse = false;
|
||||
bool right_click;
|
||||
|
||||
int paint_tile_initial_x;
|
||||
int paint_tile_initial_y;
|
||||
bool prevStraightPathState;
|
||||
int straight_path_initial_x;
|
||||
int straight_path_initial_y;
|
||||
|
||||
QPoint metatilePos;
|
||||
|
||||
enum Axis {
|
||||
None = 0,
|
||||
X,
|
||||
Y
|
||||
};
|
||||
MapPixmapItem::Axis lockedAxis;
|
||||
|
||||
LayoutPixmapItem::Axis lockedAxis;
|
||||
|
||||
QPoint selection_origin;
|
||||
QList<QPoint> selection;
|
||||
|
||||
virtual void paint(QGraphicsSceneMouseEvent*);
|
||||
virtual void floodFill(QGraphicsSceneMouseEvent*);
|
||||
virtual void magicFill(QGraphicsSceneMouseEvent*);
|
||||
@@ -70,26 +74,33 @@ public:
|
||||
QList<CollisionSelectionItem> selectedCollisions,
|
||||
bool fromScriptCall = false);
|
||||
void floodFillSmartPath(int initialX, int initialY, bool fromScriptCall = false);
|
||||
|
||||
virtual void pick(QGraphicsSceneMouseEvent*);
|
||||
virtual void select(QGraphicsSceneMouseEvent*);
|
||||
virtual void shift(QGraphicsSceneMouseEvent*);
|
||||
void shift(int xDelta, int yDelta, bool fromScriptCall = false);
|
||||
virtual void draw(bool ignoreCache = false);
|
||||
|
||||
void updateMetatileSelection(QGraphicsSceneMouseEvent *event);
|
||||
void paintNormal(int x, int y, bool fromScriptCall = false);
|
||||
void lockNondominantAxis(QGraphicsSceneMouseEvent *event);
|
||||
QPoint adjustCoords(QPoint pos);
|
||||
|
||||
void setEditsEnabled(bool enabled) { this->editsEnabled = enabled; }
|
||||
bool getEditsEnabled() { return this->editsEnabled; }
|
||||
|
||||
private:
|
||||
void paintSmartPath(int x, int y, bool fromScriptCall = false);
|
||||
static QList<int> smartPathTable;
|
||||
|
||||
unsigned actionId_ = 0;
|
||||
|
||||
bool editsEnabled = true;
|
||||
|
||||
signals:
|
||||
void startPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
|
||||
void endPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
|
||||
void mouseEvent(QGraphicsSceneMouseEvent *, MapPixmapItem *);
|
||||
void startPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
|
||||
void endPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
|
||||
void mouseEvent(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
|
||||
void hoveredMapMetatileChanged(const QPoint &pos);
|
||||
void hoveredMapMetatileCleared();
|
||||
|
||||
@@ -16,6 +16,24 @@ enum ImageExporterMode {
|
||||
Timelapse,
|
||||
};
|
||||
|
||||
struct ImageExporterSettings {
|
||||
bool showObjects = false;
|
||||
bool showWarps = false;
|
||||
bool showBGs = false;
|
||||
bool showTriggers = false;
|
||||
bool showHealLocations = false;
|
||||
bool showUpConnections = false;
|
||||
bool showDownConnections = false;
|
||||
bool showLeftConnections = false;
|
||||
bool showRightConnections = false;
|
||||
bool showGrid = false;
|
||||
bool showBorder = false;
|
||||
bool showCollision = false;
|
||||
bool previewActualSize = false;
|
||||
int timelapseSkipAmount = 1;
|
||||
int timelapseDelayMs = 200;
|
||||
};
|
||||
|
||||
class MapImageExporter : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -27,56 +45,51 @@ public:
|
||||
private:
|
||||
Ui::MapImageExporter *ui;
|
||||
|
||||
Layout *layout = nullptr;
|
||||
Map *map = nullptr;
|
||||
Editor *editor = nullptr;
|
||||
QGraphicsScene *scene = nullptr;
|
||||
|
||||
QPixmap preview;
|
||||
|
||||
bool showObjects = false;
|
||||
bool showWarps = false;
|
||||
bool showBGs = false;
|
||||
bool showTriggers = false;
|
||||
bool showHealSpots = false;
|
||||
bool showUpConnections = false;
|
||||
bool showDownConnections = false;
|
||||
bool showLeftConnections = false;
|
||||
bool showRightConnections = false;
|
||||
bool showGrid = false;
|
||||
bool showBorder = false;
|
||||
bool showCollision = false;
|
||||
int timelapseSkipAmount = 1;
|
||||
int timelapseDelayMs = 200;
|
||||
ImageExporterSettings settings;
|
||||
ImageExporterMode mode = ImageExporterMode::Normal;
|
||||
|
||||
void updatePreview();
|
||||
void scalePreview();
|
||||
void updateShowBorderState();
|
||||
void saveImage();
|
||||
QPixmap getStitchedImage(QProgressDialog *progress, bool includeBorder);
|
||||
QPixmap getFormattedMapPixmap(Map *map, bool ignoreBorder = false);
|
||||
bool historyItemAppliesToFrame(const QUndoCommand *command);
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent *) override;
|
||||
virtual void resizeEvent(QResizeEvent *) override;
|
||||
|
||||
private slots:
|
||||
void on_checkBox_Objects_stateChanged(int state);
|
||||
void on_checkBox_Warps_stateChanged(int state);
|
||||
void on_checkBox_BGs_stateChanged(int state);
|
||||
void on_checkBox_Triggers_stateChanged(int state);
|
||||
void on_checkBox_HealSpots_stateChanged(int state);
|
||||
void on_checkBox_HealLocations_stateChanged(int state);
|
||||
void on_checkBox_AllEvents_stateChanged(int state);
|
||||
|
||||
void on_checkBox_ConnectionUp_stateChanged(int state);
|
||||
void on_checkBox_ConnectionDown_stateChanged(int state);
|
||||
void on_checkBox_ConnectionLeft_stateChanged(int state);
|
||||
void on_checkBox_ConnectionRight_stateChanged(int state);
|
||||
void on_checkBox_AllConnections_stateChanged(int state);
|
||||
|
||||
void on_checkBox_Elevation_stateChanged(int state);
|
||||
void on_checkBox_Grid_stateChanged(int state);
|
||||
void on_checkBox_Border_stateChanged(int state);
|
||||
|
||||
void on_pushButton_Save_pressed();
|
||||
void on_pushButton_Reset_pressed();
|
||||
void on_pushButton_Cancel_pressed();
|
||||
void on_spinBox_TimelapseDelay_valueChanged(int delayMs);
|
||||
void on_spinBox_FrameSkip_valueChanged(int skip);
|
||||
|
||||
void on_checkBox_ActualSize_stateChanged(int state);
|
||||
};
|
||||
|
||||
#endif // MAPIMAGEEXPORTER_H
|
||||
|
||||
208
include/ui/maplistmodels.h
Normal file
@@ -0,0 +1,208 @@
|
||||
#pragma once
|
||||
#ifndef MAPLISTMODELS_H
|
||||
#define MAPLISTMODELS_H
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QFontDatabase>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QStandardItemModel>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
|
||||
class Project;
|
||||
|
||||
enum MapListUserRoles {
|
||||
GroupRole = Qt::UserRole + 1, // Used to hold the map group number.
|
||||
TypeRole, // Used to differentiate between the different layers of the map list tree view.
|
||||
TypeRole2, // Used for various extra data needed.
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MapTree : public QTreeView {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MapTree(QWidget *parent) : QTreeView(parent) {
|
||||
this->setDropIndicatorShown(true);
|
||||
this->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
this->setFocusPolicy(Qt::StrongFocus);
|
||||
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
public slots:
|
||||
void removeSelected();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class GroupNameDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GroupNameDelegate(Project *project, QObject *parent = nullptr) : QStyledItemDelegate(parent), project(project) {}
|
||||
|
||||
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;
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
Project *project = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class QRegularExpressionValidator;
|
||||
|
||||
class MapListModel : public QStandardItemModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MapListModel(QObject *parent = nullptr) : QStandardItemModel(parent) {};
|
||||
~MapListModel() { }
|
||||
|
||||
virtual QModelIndex indexOf(QString id) const = 0;
|
||||
virtual void removeItemAt(const QModelIndex &index);
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const = 0;
|
||||
|
||||
protected:
|
||||
virtual void removeItem(QStandardItem *item) = 0;
|
||||
};
|
||||
|
||||
class MapGroupModel : public MapListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MapGroupModel(Project *project, QObject *parent = nullptr);
|
||||
~MapGroupModel() { }
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
QStringList mimeTypes() const override;
|
||||
virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
public:
|
||||
void setMap(QString mapName) { this->openMap = mapName; }
|
||||
|
||||
QStandardItem *createGroupItem(QString groupName, int groupIndex, QStandardItem *fromItem = nullptr);
|
||||
QStandardItem *createMapItem(QString mapName, QStandardItem *fromItem = nullptr);
|
||||
|
||||
QStandardItem *insertGroupItem(QString groupName);
|
||||
QStandardItem *insertMapItem(QString mapName, QString groupName);
|
||||
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const override;
|
||||
virtual QModelIndex indexOf(QString mapName) const override;
|
||||
|
||||
void initialize();
|
||||
|
||||
protected:
|
||||
virtual void removeItem(QStandardItem *item) override;
|
||||
|
||||
private:
|
||||
friend class MapTree;
|
||||
void updateProject();
|
||||
|
||||
private:
|
||||
Project *project;
|
||||
QStandardItem *root = nullptr;
|
||||
|
||||
QMap<QString, QStandardItem *> groupItems;
|
||||
QMap<QString, QStandardItem *> mapItems;
|
||||
|
||||
QString openMap;
|
||||
|
||||
signals:
|
||||
void dragMoveCompleted();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MapAreaModel : public MapListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MapAreaModel(Project *project, QObject *parent = nullptr);
|
||||
~MapAreaModel() {}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
public:
|
||||
void setMap(QString mapName) { this->openMap = mapName; }
|
||||
|
||||
QStandardItem *createAreaItem(QString areaName);
|
||||
QStandardItem *createMapItem(QString mapName, int areaIndex, int mapIndex);
|
||||
|
||||
QStandardItem *insertAreaItem(QString areaName);
|
||||
QStandardItem *insertMapItem(QString mapName, QString areaName, int groupIndex);
|
||||
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const override;
|
||||
virtual QModelIndex indexOf(QString mapName) const override;
|
||||
|
||||
void initialize();
|
||||
|
||||
protected:
|
||||
virtual void removeItem(QStandardItem *item) override;
|
||||
|
||||
private:
|
||||
Project *project;
|
||||
QStandardItem *root = nullptr;
|
||||
|
||||
QMap<QString, QStandardItem *> areaItems;
|
||||
QMap<QString, QStandardItem *> mapItems;
|
||||
|
||||
QString openMap;
|
||||
|
||||
signals:
|
||||
void edited();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LayoutTreeModel : public MapListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LayoutTreeModel(Project *project, QObject *parent = nullptr);
|
||||
~LayoutTreeModel() {}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
public:
|
||||
void setLayout(QString layoutId) { this->openLayout = layoutId; }
|
||||
|
||||
QStandardItem *createLayoutItem(QString layoutId);
|
||||
QStandardItem *createMapItem(QString mapName);
|
||||
|
||||
QStandardItem *insertLayoutItem(QString layoutId);
|
||||
QStandardItem *insertMapItem(QString mapName, QString layoutId);
|
||||
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const override;
|
||||
virtual QModelIndex indexOf(QString layoutName) const override;
|
||||
|
||||
void initialize();
|
||||
|
||||
protected:
|
||||
virtual void removeItem(QStandardItem *item) override;
|
||||
|
||||
private:
|
||||
Project *project;
|
||||
QStandardItem *root = nullptr;
|
||||
|
||||
QMap<QString, QStandardItem *> layoutItems;
|
||||
QMap<QString, QStandardItem *> mapItems;
|
||||
|
||||
QString openLayout;
|
||||
|
||||
signals:
|
||||
void edited();
|
||||
};
|
||||
|
||||
#endif // MAPLISTMODELS_H
|
||||
52
include/ui/maplisttoolbar.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef MAPLISTTOOLBAR_H
|
||||
#define MAPLISTTOOLBAR_H
|
||||
|
||||
#include "maplistmodels.h"
|
||||
#include "filterchildrenproxymodel.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QPointer>
|
||||
|
||||
namespace Ui {
|
||||
class MapListToolBar;
|
||||
}
|
||||
|
||||
class MapListToolBar : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MapListToolBar(QWidget *parent = nullptr);
|
||||
~MapListToolBar();
|
||||
|
||||
MapTree* list() const { return m_list; }
|
||||
void setList(MapTree *list);
|
||||
|
||||
void setEditsAllowedButtonVisible(bool visible);
|
||||
void setEditsAllowed(bool allowed);
|
||||
void toggleEditsAllowed();
|
||||
|
||||
void setEmptyFoldersVisible(bool visible);
|
||||
void toggleEmptyFolders();
|
||||
|
||||
void expandList();
|
||||
void collapseList();
|
||||
|
||||
void applyFilter(const QString &filterText);
|
||||
void clearFilter();
|
||||
void setFilterLocked(bool locked) { m_filterLocked = locked; }
|
||||
bool isFilterLocked() const { return m_filterLocked; }
|
||||
|
||||
signals:
|
||||
void filterCleared(MapTree*);
|
||||
void addFolderClicked();
|
||||
|
||||
private:
|
||||
Ui::MapListToolBar *ui;
|
||||
QPointer<MapTree> m_list;
|
||||
bool m_filterLocked = false;
|
||||
bool m_editsAllowed = false;
|
||||
bool m_emptyFoldersVisible = true;
|
||||
};
|
||||
|
||||
#endif // MAPLISTTOOLBAR_H
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef MAPSCENEEVENTFILTER_H
|
||||
#define MAPSCENEEVENTFILTER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class MapSceneEventFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
public:
|
||||
explicit MapSceneEventFilter(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void wheelZoom(int delta);
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // MAPSCENEEVENTFILTER_H
|
||||
@@ -73,7 +73,8 @@ public:
|
||||
private:
|
||||
QMap<int, Overlay*> overlayMap;
|
||||
protected:
|
||||
void drawForeground(QPainter *painter, const QRectF &rect);
|
||||
virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
|
||||
virtual void keyPressEvent(QKeyEvent*) override;
|
||||
};
|
||||
|
||||
#endif // GRAPHICSVIEW_H
|
||||
|
||||
@@ -31,13 +31,13 @@ struct MetatileSelection
|
||||
class MetatileSelector: public SelectablePixmapItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MetatileSelector(int numMetatilesWide, Map *map): SelectablePixmapItem(16, 16) {
|
||||
MetatileSelector(int numMetatilesWide, Layout *layout): SelectablePixmapItem(16, 16) {
|
||||
this->externalSelection = false;
|
||||
this->prefabSelection = false;
|
||||
this->numMetatilesWide = numMetatilesWide;
|
||||
this->map = map;
|
||||
this->primaryTileset = map->layout->tileset_primary;
|
||||
this->secondaryTileset = map->layout->tileset_secondary;
|
||||
this->layout = layout;
|
||||
this->primaryTileset = layout->tileset_primary;
|
||||
this->secondaryTileset = layout->tileset_secondary;
|
||||
this->selection = MetatileSelection{};
|
||||
this->cellPos = QPoint(-1, -1);
|
||||
setAcceptHoverEvents(true);
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
void setPrefabSelection(MetatileSelection selection);
|
||||
void setExternalSelection(int, int, QList<uint16_t>, QList<QPair<uint16_t, uint16_t>>);
|
||||
QPoint getMetatileIdCoordsOnWidget(uint16_t);
|
||||
void setMap(Map*);
|
||||
void setLayout(Layout *layout);
|
||||
bool isInternalSelection() const { return (!this->externalSelection && !this->prefabSelection); }
|
||||
Tileset *primaryTileset;
|
||||
Tileset *secondaryTileset;
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
bool externalSelection;
|
||||
bool prefabSelection;
|
||||
int numMetatilesWide;
|
||||
Map *map;
|
||||
Layout *layout;
|
||||
int externalSelectionWidth;
|
||||
int externalSelectionHeight;
|
||||
QList<uint16_t> externalSelectedMetatiles;
|
||||
|
||||
@@ -32,8 +32,6 @@ public slots:
|
||||
void deactivateTab(int tabIndex);
|
||||
|
||||
private:
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
void actionCopyTab(int index);
|
||||
void actionAddDeleteTab(int index);
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@ public:
|
||||
bool importedMap;
|
||||
QString layoutId;
|
||||
void init();
|
||||
void init(MapSortOrder type, QVariant data);
|
||||
void init(MapLayout *);
|
||||
void initUi();
|
||||
void init(int tabIndex, QString data);
|
||||
void init(Layout *);
|
||||
static void setDefaultSettings(Project *project);
|
||||
|
||||
signals:
|
||||
@@ -37,7 +38,7 @@ private:
|
||||
bool checkNewMapGroup();
|
||||
void saveSettings();
|
||||
void useLayout(QString layoutId);
|
||||
void useLayoutSettings(MapLayout *mapLayout);
|
||||
void useLayoutSettings(Layout *mapLayout);
|
||||
|
||||
struct Settings {
|
||||
QString group;
|
||||
@@ -60,6 +61,8 @@ private:
|
||||
static struct Settings settings;
|
||||
|
||||
private slots:
|
||||
void on_checkBox_UseExistingLayout_stateChanged(int state);
|
||||
void on_comboBox_Layout_currentTextChanged(const QString &text);
|
||||
void on_pushButton_NewMap_Accept_clicked();
|
||||
void on_lineEdit_NewMap_Name_textChanged(const QString &);
|
||||
};
|
||||
|
||||
@@ -50,19 +50,19 @@ private:
|
||||
QColor fillColor;
|
||||
};
|
||||
|
||||
class OverlayImage : public OverlayItem {
|
||||
class OverlayPixmap : public OverlayItem {
|
||||
public:
|
||||
OverlayImage(int x, int y, QImage image) {
|
||||
OverlayPixmap(int x, int y, QPixmap pixmap) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->image = image;
|
||||
this->pixmap = pixmap;
|
||||
}
|
||||
~OverlayImage() {}
|
||||
~OverlayPixmap() {}
|
||||
virtual void render(QPainter *painter);
|
||||
private:
|
||||
int x;
|
||||
int y;
|
||||
QImage image;
|
||||
QPixmap pixmap;
|
||||
};
|
||||
|
||||
class Overlay
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
#define PALETTEEDITOR_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QValidator>
|
||||
#include <QSlider>
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
|
||||
#include "colorinputwidget.h"
|
||||
#include "project.h"
|
||||
#include "history.h"
|
||||
|
||||
@@ -32,43 +30,27 @@ public:
|
||||
private:
|
||||
Ui::PaletteEditor *ui;
|
||||
Project *project = nullptr;
|
||||
|
||||
QList<QList<QSlider*>> sliders;
|
||||
QList<QList<QSpinBox *>> spinners;
|
||||
QList<QFrame*> frames;
|
||||
QList<QToolButton *> pickButtons;
|
||||
QList<QLineEdit *> hexEdits;
|
||||
QList<ColorInputWidget*> colorInputs;
|
||||
|
||||
Tileset *primaryTileset;
|
||||
Tileset *secondaryTileset;
|
||||
|
||||
QList<History<PaletteHistoryItem*>> palettesHistory;
|
||||
|
||||
void refreshColorUis();
|
||||
void updateColorUi(int index, QRgb color);
|
||||
void commitEditHistory(int paletteid);
|
||||
Tileset* getTileset(int paletteId);
|
||||
void refreshColorInputs();
|
||||
void commitEditHistory();
|
||||
void commitEditHistory(int paletteId);
|
||||
void restoreWindowState();
|
||||
void setSignalsEnabled(bool enabled);
|
||||
void setColorsFromHistory(PaletteHistoryItem*, int);
|
||||
void closeEvent(QCloseEvent*);
|
||||
void pickColor(int i);
|
||||
|
||||
void setRgb(int index, QRgb rgb);
|
||||
void setRgbFromSliders(int colorIndex);
|
||||
void setRgbFromHexEdit(int colorIndex);
|
||||
void setRgbFromSpinners(int colorIndex);
|
||||
void setPalette(int paletteId, const QList<QRgb> &palette);
|
||||
|
||||
void setBitDepth(int bits);
|
||||
int bitDepth = 24;
|
||||
|
||||
class HexCodeValidator : public QValidator {
|
||||
virtual QValidator::State validate(QString &input, int &) const override {
|
||||
input = input.toUpper();
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
};
|
||||
|
||||
HexCodeValidator *hexValidator = nullptr;
|
||||
static const int numColors = 16;
|
||||
|
||||
signals:
|
||||
void closed();
|
||||
|
||||
@@ -20,9 +20,9 @@ struct PrefabItem
|
||||
class Prefab
|
||||
{
|
||||
public:
|
||||
void initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLabel *emptyPrefabLabel, Map *map);
|
||||
void addPrefab(MetatileSelection selection, Map *map, QString name);
|
||||
void updatePrefabUi(Map *map);
|
||||
void initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLabel *emptyPrefabLabel, Layout *layout);
|
||||
void addPrefab(MetatileSelection selection, Layout *layout, QString name);
|
||||
void updatePrefabUi(Layout *layout);
|
||||
bool tryImportDefaultPrefabs(QWidget * parent, BaseGameVersion version, QString filepath = "");
|
||||
|
||||
private:
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
#define PREFABCREATIONDIALOG_H
|
||||
|
||||
#include "metatileselector.h"
|
||||
#include "map.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class Layout;
|
||||
|
||||
namespace Ui {
|
||||
class PrefabCreationDialog;
|
||||
}
|
||||
@@ -15,12 +16,12 @@ class PrefabCreationDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PrefabCreationDialog(QWidget *parent, MetatileSelector *metatileSelector, Map *map);
|
||||
explicit PrefabCreationDialog(QWidget *parent, MetatileSelector *metatileSelector, Layout *layout);
|
||||
~PrefabCreationDialog();
|
||||
void savePrefab();
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
Layout *layout = nullptr;
|
||||
Ui::PrefabCreationDialog *ui;
|
||||
MetatileSelection selection;
|
||||
};
|
||||
|
||||
@@ -65,6 +65,8 @@ private:
|
||||
void updateMaskOverlapWarning(QLabel * warning, QList<UIntSpinBox*> masks);
|
||||
QStringList getWarpBehaviorsList();
|
||||
void setWarpBehaviorsList(QStringList list);
|
||||
void openFilesHelp();
|
||||
void openIdentifiersHelp();
|
||||
|
||||
private slots:
|
||||
void dialogButtonClicked(QAbstractButton *button);
|
||||
|
||||
@@ -57,7 +57,6 @@ private:
|
||||
tsl::ordered_map<QString, RegionMap *> region_maps;
|
||||
|
||||
QString configFilepath;
|
||||
QString mapSectionFilepath;
|
||||
|
||||
poryjson::Json rmConfigJson;
|
||||
|
||||
@@ -96,7 +95,7 @@ private:
|
||||
void saveConfig();
|
||||
bool loadRegionMapEntries();
|
||||
bool saveRegionMapEntries();
|
||||
tsl::ordered_map<QString, MapSectionEntry> region_map_entries;
|
||||
QMap<QString, MapSectionEntry> region_map_entries;
|
||||
|
||||
bool buildConfigDialog();
|
||||
poryjson::Json configRegionMapDialog();
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "orderedjson.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFileDialog>
|
||||
|
||||
class Project;
|
||||
|
||||
@@ -33,7 +32,7 @@ private:
|
||||
|
||||
void hideMessages();
|
||||
|
||||
QString browse(QString filter, QFileDialog::FileMode mode);
|
||||
QString browse(QString filter);
|
||||
|
||||
private slots:
|
||||
void on_browse_tilesetImagePath_clicked();
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#include "tileseteditormetatileselector.h"
|
||||
#include "tileseteditortileselector.h"
|
||||
#include "metatilelayersitem.h"
|
||||
#include "map.h"
|
||||
|
||||
class Layout;
|
||||
|
||||
namespace Ui {
|
||||
class TilesetEditor;
|
||||
@@ -39,10 +40,10 @@ class TilesetEditor : public QMainWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TilesetEditor(Project*, Map*, QWidget *parent = nullptr);
|
||||
explicit TilesetEditor(Project *project, Layout *layout, QWidget *parent = nullptr);
|
||||
~TilesetEditor();
|
||||
void update(Map *map, QString primaryTilsetLabel, QString secondaryTilesetLabel);
|
||||
void updateMap(Map *map);
|
||||
void update(Layout *layout, QString primaryTilsetLabel, QString secondaryTilesetLabel);
|
||||
void updateLayout(Layout *layout);
|
||||
void updateTilesets(QString primaryTilsetLabel, QString secondaryTilesetLabel);
|
||||
bool selectMetatile(uint16_t metatileId);
|
||||
uint16_t getSelectedMetatileId();
|
||||
@@ -155,7 +156,7 @@ private:
|
||||
MetatileLayersItem *metatileLayersItem = nullptr;
|
||||
PaletteEditor *paletteEditor = nullptr;
|
||||
Project *project = nullptr;
|
||||
Map *map = nullptr;
|
||||
Layout *layout = nullptr;
|
||||
Metatile *metatile = nullptr;
|
||||
Metatile *copiedMetatile = nullptr;
|
||||
QString copiedMetatileLabel;
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
#include "selectablepixmapitem.h"
|
||||
#include "tileset.h"
|
||||
#include "map.h"
|
||||
|
||||
class Layout;
|
||||
|
||||
class TilesetEditorMetatileSelector: public SelectablePixmapItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TilesetEditorMetatileSelector(Tileset *primaryTileset, Tileset *secondaryTileset, Map *map);
|
||||
Map *map = nullptr;
|
||||
TilesetEditorMetatileSelector(Tileset *primaryTileset, Tileset *secondaryTileset, Layout *layout);
|
||||
Layout *layout = nullptr;
|
||||
void draw();
|
||||
bool select(uint16_t metatileId);
|
||||
void setTilesets(Tileset*, Tileset*, bool draw = true);
|
||||
|
||||
@@ -61,6 +61,7 @@ private:
|
||||
QPoint getTileCoords(uint16_t);
|
||||
QList<QRgb> getCurPaletteTable();
|
||||
QList<Tile> buildSelectedTiles(int, int, QList<Tile>);
|
||||
QImage buildImage(int tileIdStart, int numTiles);
|
||||
|
||||
void drawUnused();
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class UpdatePromoter : public QDialog
|
||||
|
||||
public:
|
||||
explicit UpdatePromoter(QWidget *parent, NetworkAccessManager *manager);
|
||||
~UpdatePromoter() {};
|
||||
~UpdatePromoter();
|
||||
|
||||
void checkForUpdates();
|
||||
void updatePreferences();
|
||||
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
void applySpeciesColors(const QList<QBarSet*> &);
|
||||
QChart::ChartTheme currentTheme() const;
|
||||
void updateTheme();
|
||||
void limitChartAnimation(QChart*);
|
||||
void limitChartAnimation();
|
||||
|
||||
void showHelpDialog();
|
||||
};
|
||||
|
||||
23
porymap.pro
@@ -33,6 +33,7 @@ SOURCES += src/core/block.cpp \
|
||||
src/core/bitpacker.cpp \
|
||||
src/core/blockdata.cpp \
|
||||
src/core/events.cpp \
|
||||
src/core/filedialog.cpp \
|
||||
src/core/heallocation.cpp \
|
||||
src/core/imageexport.cpp \
|
||||
src/core/map.cpp \
|
||||
@@ -51,7 +52,6 @@ SOURCES += src/core/block.cpp \
|
||||
src/core/editcommands.cpp \
|
||||
src/lib/fex/lexer.cpp \
|
||||
src/lib/fex/parser.cpp \
|
||||
src/lib/fex/parser_util.cpp \
|
||||
src/lib/orderedjson.cpp \
|
||||
src/core/regionmapeditcommands.cpp \
|
||||
src/scriptapi/apimap.cpp \
|
||||
@@ -59,6 +59,7 @@ SOURCES += src/core/block.cpp \
|
||||
src/scriptapi/apiutility.cpp \
|
||||
src/scriptapi/scripting.cpp \
|
||||
src/ui/aboutporymap.cpp \
|
||||
src/ui/colorinputwidget.cpp \
|
||||
src/ui/connectionslistitem.cpp \
|
||||
src/ui/customscriptseditor.cpp \
|
||||
src/ui/customscriptslistitem.cpp \
|
||||
@@ -68,6 +69,7 @@ SOURCES += src/core/block.cpp \
|
||||
src/ui/collisionpixmapitem.cpp \
|
||||
src/ui/connectionpixmapitem.cpp \
|
||||
src/ui/currentselectedmetatilespixmapitem.cpp \
|
||||
src/ui/gridsettings.cpp \
|
||||
src/ui/newmapconnectiondialog.cpp \
|
||||
src/ui/overlay.cpp \
|
||||
src/ui/prefab.cpp \
|
||||
@@ -77,14 +79,16 @@ SOURCES += src/core/block.cpp \
|
||||
src/ui/cursortilerect.cpp \
|
||||
src/ui/customattributestable.cpp \
|
||||
src/ui/eventframes.cpp \
|
||||
src/ui/eventfilters.cpp \
|
||||
src/ui/filterchildrenproxymodel.cpp \
|
||||
src/ui/maplistmodels.cpp \
|
||||
src/ui/maplisttoolbar.cpp \
|
||||
src/ui/graphicsview.cpp \
|
||||
src/ui/imageproviders.cpp \
|
||||
src/ui/mappixmapitem.cpp \
|
||||
src/ui/layoutpixmapitem.cpp \
|
||||
src/ui/prefabcreationdialog.cpp \
|
||||
src/ui/regionmappixmapitem.cpp \
|
||||
src/ui/citymappixmapitem.cpp \
|
||||
src/ui/mapsceneeventfilter.cpp \
|
||||
src/ui/metatilelayersitem.cpp \
|
||||
src/ui/metatileselector.cpp \
|
||||
src/ui/movablerect.cpp \
|
||||
@@ -129,6 +133,7 @@ HEADERS += include/core/block.h \
|
||||
include/core/bitpacker.h \
|
||||
include/core/blockdata.h \
|
||||
include/core/events.h \
|
||||
include/core/filedialog.h \
|
||||
include/core/heallocation.h \
|
||||
include/core/history.h \
|
||||
include/core/imageexport.h \
|
||||
@@ -152,7 +157,6 @@ HEADERS += include/core/block.h \
|
||||
include/lib/fex/define_statement.h \
|
||||
include/lib/fex/lexer.h \
|
||||
include/lib/fex/parser.h \
|
||||
include/lib/fex/parser_util.h \
|
||||
include/lib/orderedmap.h \
|
||||
include/lib/orderedjson.h \
|
||||
include/ui/aboutporymap.h \
|
||||
@@ -165,6 +169,7 @@ HEADERS += include/core/block.h \
|
||||
include/ui/collisionpixmapitem.h \
|
||||
include/ui/connectionpixmapitem.h \
|
||||
include/ui/currentselectedmetatilespixmapitem.h \
|
||||
include/ui/gridsettings.h \
|
||||
include/ui/newmapconnectiondialog.h \
|
||||
include/ui/prefabframe.h \
|
||||
include/ui/projectsettingseditor.h \
|
||||
@@ -173,15 +178,18 @@ HEADERS += include/core/block.h \
|
||||
include/ui/cursortilerect.h \
|
||||
include/ui/customattributestable.h \
|
||||
include/ui/eventframes.h \
|
||||
include/ui/eventfilters.h \
|
||||
include/ui/filterchildrenproxymodel.h \
|
||||
include/ui/maplistmodels.h \
|
||||
include/ui/maplisttoolbar.h \
|
||||
include/ui/graphicsview.h \
|
||||
include/ui/imageproviders.h \
|
||||
include/ui/mappixmapitem.h \
|
||||
include/ui/layoutpixmapitem.h \
|
||||
include/ui/mapview.h \
|
||||
include/ui/prefabcreationdialog.h \
|
||||
include/ui/regionmappixmapitem.h \
|
||||
include/ui/citymappixmapitem.h \
|
||||
include/ui/mapsceneeventfilter.h \
|
||||
include/ui/colorinputwidget.h \
|
||||
include/ui/metatilelayersitem.h \
|
||||
include/ui/metatileselector.h \
|
||||
include/ui/movablerect.h \
|
||||
@@ -226,7 +234,10 @@ HEADERS += include/core/block.h \
|
||||
include/ui/wildmonchart.h
|
||||
|
||||
FORMS += forms/mainwindow.ui \
|
||||
forms/colorinputwidget.ui \
|
||||
forms/connectionslistitem.ui \
|
||||
forms/gridsettingsdialog.ui \
|
||||
forms/maplisttoolbar.ui \
|
||||
forms/newmapconnectiondialog.ui \
|
||||
forms/prefabcreationdialog.ui \
|
||||
forms/prefabframe.ui \
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
resources/icons/chart_bar.ico
Executable file
|
After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 1.8 KiB |
BIN
resources/icons/connections.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 2.1 KiB |
BIN
resources/icons/folder_add.ico
Executable file
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 5.4 KiB |
BIN
resources/icons/folder_eye_closed.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
resources/icons/folder_eye_open.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
resources/icons/link.ico
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/icons/link_broken.ico
Executable file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
resources/icons/lock_edit.ico
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
resources/icons/map_grayed.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/icons/minimap.ico
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
resources/icons/unlock_edit.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
@@ -1,6 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>icons/add.ico</file>
|
||||
<file>icons/chart_bar.ico</file>
|
||||
<file>icons/collapse_all.ico</file>
|
||||
<file>icons/cursor.ico</file>
|
||||
<file>icons/delete.ico</file>
|
||||
@@ -10,16 +11,24 @@
|
||||
<file>icons/file_put.ico</file>
|
||||
<file>icons/fill_color_cursor.ico</file>
|
||||
<file>icons/fill_color.ico</file>
|
||||
<file>icons/folder_add.ico</file>
|
||||
<file>icons/folder_closed_map.ico</file>
|
||||
<file>icons/folder_closed.ico</file>
|
||||
<file>icons/folder_eye_closed.ico</file>
|
||||
<file>icons/folder_eye_open.ico</file>
|
||||
<file>icons/folder_map_edited.ico</file>
|
||||
<file>icons/folder_map_opened.ico</file>
|
||||
<file>icons/folder_map.ico</file>
|
||||
<file>icons/folder.ico</file>
|
||||
<file>icons/lock_edit.ico</file>
|
||||
<file>icons/unlock_edit.ico</file>
|
||||
<file>icons/help.ico</file>
|
||||
<file>icons/link_broken.ico</file>
|
||||
<file>icons/link.ico</file>
|
||||
<file>icons/map_edited.ico</file>
|
||||
<file>icons/map_opened.ico</file>
|
||||
<file>icons/map.ico</file>
|
||||
<file>icons/map_grayed.ico</file>
|
||||
<file>icons/move.ico</file>
|
||||
<file>icons/pencil_cursor.ico</file>
|
||||
<file>icons/pencil.ico</file>
|
||||
@@ -35,7 +44,10 @@
|
||||
<file>icons/sort_map.ico</file>
|
||||
<file>icons/sort_number.ico</file>
|
||||
<file>icons/tall_grass.ico</file>
|
||||
<file>icons/minimap.ico</file>
|
||||
<file>icons/viewsprites.ico</file>
|
||||
<file>icons/application_form_edit.ico</file>
|
||||
<file>icons/connections.ico</file>
|
||||
<file>icons/ui/dark_checkbox_checked_disabled.png</file>
|
||||
<file>icons/ui/dark_checkbox_checked_disabled@2x.png</file>
|
||||
<file>icons/ui/dark_checkbox_checked.png</file>
|
||||
|
||||
@@ -110,7 +110,6 @@ const QMap<ProjectIdentifier, QPair<QString, QString>> ProjectConfig::defaultIde
|
||||
{ProjectIdentifier::define_map_empty, {"define_map_empty", "UNDEFINED"}},
|
||||
{ProjectIdentifier::define_map_section_prefix, {"define_map_section_prefix", "MAPSEC_"}},
|
||||
{ProjectIdentifier::define_map_section_empty, {"define_map_section_empty", "NONE"}},
|
||||
{ProjectIdentifier::define_map_section_count, {"define_map_section_count", "COUNT"}},
|
||||
{ProjectIdentifier::define_species_prefix, {"define_species_prefix", "SPECIES_"}},
|
||||
// Regex
|
||||
{ProjectIdentifier::regex_behaviors, {"regex_behaviors", "\\bMB_"}},
|
||||
@@ -167,7 +166,6 @@ const QMap<ProjectFilePath, QPair<QString, QString>> ProjectConfig::defaultPaths
|
||||
{ProjectFilePath::constants_obj_event_movement, { "constants_obj_event_movement", "include/constants/event_object_movement.h"}},
|
||||
{ProjectFilePath::constants_obj_events, { "constants_obj_events", "include/constants/event_objects.h"}},
|
||||
{ProjectFilePath::constants_event_bg, { "constants_event_bg", "include/constants/event_bg.h"}},
|
||||
{ProjectFilePath::constants_region_map_sections, { "constants_region_map_sections", "include/constants/region_map_sections.h"}},
|
||||
{ProjectFilePath::constants_metatile_labels, { "constants_metatile_labels", "include/constants/metatile_labels.h"}},
|
||||
{ProjectFilePath::constants_metatile_behaviors, { "constants_metatile_behaviors", "include/constants/metatile_behaviors.h"}},
|
||||
{ProjectFilePath::constants_species, { "constants_species", "include/constants/species.h"}},
|
||||
@@ -208,7 +206,6 @@ void KeyValueConfigBase::load() {
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
QList<QString> configLines;
|
||||
static const QRegularExpression re("^(?<key>[^=]+)=(?<value>.*)$");
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine().trimmed();
|
||||
@@ -279,18 +276,6 @@ uint32_t KeyValueConfigBase::getConfigUint32(QString key, QString value, uint32_
|
||||
return qMin(max, qMax(min, result));
|
||||
}
|
||||
|
||||
const QMap<MapSortOrder, QString> mapSortOrderMap = {
|
||||
{MapSortOrder::Group, "group"},
|
||||
{MapSortOrder::Layout, "layout"},
|
||||
{MapSortOrder::Area, "area"},
|
||||
};
|
||||
|
||||
const QMap<QString, MapSortOrder> mapSortOrderReverseMap = {
|
||||
{"group", MapSortOrder::Group},
|
||||
{"layout", MapSortOrder::Layout},
|
||||
{"area", MapSortOrder::Area},
|
||||
};
|
||||
|
||||
PorymapConfig porymapConfig;
|
||||
|
||||
QString PorymapConfig::getConfigFilepath() {
|
||||
@@ -315,14 +300,8 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
this->reopenOnLaunch = getConfigBool(key, value);
|
||||
} else if (key == "pretty_cursors") {
|
||||
this->prettyCursors = getConfigBool(key, value);
|
||||
} else if (key == "map_sort_order") {
|
||||
QString sortOrder = value.toLower();
|
||||
if (mapSortOrderReverseMap.contains(sortOrder)) {
|
||||
this->mapSortOrder = mapSortOrderReverseMap.value(sortOrder);
|
||||
} else {
|
||||
this->mapSortOrder = MapSortOrder::Group;
|
||||
logWarn(QString("Invalid config value for map_sort_order: '%1'. Must be 'group', 'area', or 'layout'.").arg(value));
|
||||
}
|
||||
} else if (key == "map_list_tab") {
|
||||
this->mapListTab = getConfigInteger(key, value, 0, 2, 0);
|
||||
} else if (key == "main_window_geometry") {
|
||||
this->mainWindowGeometry = bytesFromString(value);
|
||||
} else if (key == "main_window_state") {
|
||||
@@ -439,7 +418,7 @@ QMap<QString, QString> PorymapConfig::getKeyValueMap() {
|
||||
map.insert("project_manually_closed", this->projectManuallyClosed ? "1" : "0");
|
||||
map.insert("reopen_on_launch", this->reopenOnLaunch ? "1" : "0");
|
||||
map.insert("pretty_cursors", this->prettyCursors ? "1" : "0");
|
||||
map.insert("map_sort_order", mapSortOrderMap.value(this->mapSortOrder));
|
||||
map.insert("map_list_tab", QString::number(this->mapListTab));
|
||||
map.insert("main_window_geometry", stringFromByteArray(this->mainWindowGeometry));
|
||||
map.insert("main_window_state", stringFromByteArray(this->mainWindowState));
|
||||
map.insert("map_splitter_state", stringFromByteArray(this->mapSplitterState));
|
||||
@@ -741,8 +720,8 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
} else if (key == "enable_map_allow_flags") {
|
||||
this->mapAllowFlagsEnabled = getConfigBool(key, value);
|
||||
#ifdef CONFIG_BACKWARDS_COMPATABILITY
|
||||
} else if (key == "recent_map") {
|
||||
userConfig.recentMap = value;
|
||||
} else if (key == "recent_map_or_layout") {
|
||||
userConfig.recentMapOrLayout = value;
|
||||
} else if (key == "use_encounter_json") {
|
||||
userConfig.useEncounterJson = getConfigBool(key, value);
|
||||
} else if (key == "custom_scripts") {
|
||||
@@ -1036,8 +1015,8 @@ QString UserConfig::getConfigFilepath() {
|
||||
}
|
||||
|
||||
void UserConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
if (key == "recent_map") {
|
||||
this->recentMap = value;
|
||||
if (key == "recent_map_or_layout") {
|
||||
this->recentMapOrLayout = value;
|
||||
} else if (key == "use_encounter_json") {
|
||||
this->useEncounterJson = getConfigBool(key, value);
|
||||
} else if (key == "custom_scripts") {
|
||||
@@ -1053,14 +1032,13 @@ void UserConfig::setUnreadKeys() {
|
||||
|
||||
QMap<QString, QString> UserConfig::getKeyValueMap() {
|
||||
QMap<QString, QString> map;
|
||||
map.insert("recent_map", this->recentMap);
|
||||
map.insert("recent_map_or_layout", this->recentMapOrLayout);
|
||||
map.insert("use_encounter_json", QString::number(this->useEncounterJson));
|
||||
map.insert("custom_scripts", this->outputCustomScripts());
|
||||
return map;
|
||||
}
|
||||
|
||||
void UserConfig::init() {
|
||||
QString dirName = QDir(this->projectDir).dirName().toLower();
|
||||
this->useEncounterJson = true;
|
||||
this->customScripts.clear();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "editcommands.h"
|
||||
#include "mappixmapitem.h"
|
||||
#include "draggablepixmapitem.h"
|
||||
#include "bordermetatilespixmapitem.h"
|
||||
#include "editor.h"
|
||||
@@ -25,17 +24,17 @@ int getEventTypeMask(QList<Event *> events) {
|
||||
return eventTypeMask;
|
||||
}
|
||||
|
||||
void renderMapBlocks(Map *map, bool ignoreCache = false) {
|
||||
map->mapItem->draw(ignoreCache);
|
||||
map->collisionItem->draw(ignoreCache);
|
||||
void renderBlocks(Layout *layout, bool ignoreCache = false) {
|
||||
layout->layoutItem->draw(ignoreCache);
|
||||
layout->collisionItem->draw(ignoreCache);
|
||||
}
|
||||
|
||||
PaintMetatile::PaintMetatile(Map *map,
|
||||
PaintMetatile::PaintMetatile(Layout *layout,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Paint Metatiles");
|
||||
|
||||
this->map = map;
|
||||
this->layout = layout;
|
||||
this->oldMetatiles = oldMetatiles;
|
||||
this->newMetatiles = newMetatiles;
|
||||
|
||||
@@ -45,23 +44,23 @@ PaintMetatile::PaintMetatile(Map *map,
|
||||
void PaintMetatile::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
if (!layout) return;
|
||||
|
||||
map->setBlockdata(newMetatiles, true);
|
||||
layout->setBlockdata(newMetatiles, true);
|
||||
|
||||
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
|
||||
layout->lastCommitBlocks.blocks = layout->blockdata;
|
||||
|
||||
renderMapBlocks(map);
|
||||
renderBlocks(layout);
|
||||
}
|
||||
|
||||
void PaintMetatile::undo() {
|
||||
if (!map) return;
|
||||
if (!layout) return;
|
||||
|
||||
map->setBlockdata(oldMetatiles, true);
|
||||
layout->setBlockdata(oldMetatiles, true);
|
||||
|
||||
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
|
||||
layout->lastCommitBlocks.blocks = layout->blockdata;
|
||||
|
||||
renderMapBlocks(map);
|
||||
renderBlocks(layout);
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
@@ -69,7 +68,7 @@ void PaintMetatile::undo() {
|
||||
bool PaintMetatile::mergeWith(const QUndoCommand *command) {
|
||||
const PaintMetatile *other = static_cast<const PaintMetatile *>(command);
|
||||
|
||||
if (map != other->map)
|
||||
if (layout != other->layout)
|
||||
return false;
|
||||
|
||||
if (actionId != other->actionId)
|
||||
@@ -84,12 +83,12 @@ bool PaintMetatile::mergeWith(const QUndoCommand *command) {
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
PaintBorder::PaintBorder(Map *map,
|
||||
PaintBorder::PaintBorder(Layout *layout,
|
||||
const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||
unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Paint Border");
|
||||
|
||||
this->map = map;
|
||||
this->layout = layout;
|
||||
this->oldBorder = oldBorder;
|
||||
this->newBorder = newBorder;
|
||||
|
||||
@@ -99,23 +98,23 @@ PaintBorder::PaintBorder(Map *map,
|
||||
void PaintBorder::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
if (!layout) return;
|
||||
|
||||
map->setBorderBlockData(newBorder, true);
|
||||
layout->setBorderBlockData(newBorder, true);
|
||||
|
||||
map->layout->lastCommitBlocks.border = map->layout->border;
|
||||
layout->lastCommitBlocks.border = layout->border;
|
||||
|
||||
map->borderItem->draw();
|
||||
layout->borderItem->draw();
|
||||
}
|
||||
|
||||
void PaintBorder::undo() {
|
||||
if (!map) return;
|
||||
if (!layout) return;
|
||||
|
||||
map->setBorderBlockData(oldBorder, true);
|
||||
layout->setBorderBlockData(oldBorder, true);
|
||||
|
||||
map->layout->lastCommitBlocks.border = map->layout->border;
|
||||
layout->lastCommitBlocks.border = layout->border;
|
||||
|
||||
map->borderItem->draw();
|
||||
layout->borderItem->draw();
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
@@ -124,12 +123,12 @@ void PaintBorder::undo() {
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
ShiftMetatiles::ShiftMetatiles(Map *map,
|
||||
ShiftMetatiles::ShiftMetatiles(Layout *layout,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Shift Metatiles");
|
||||
|
||||
this->map = map;
|
||||
this->layout = layout;
|
||||
this->oldMetatiles = oldMetatiles;
|
||||
this->newMetatiles = newMetatiles;
|
||||
|
||||
@@ -139,23 +138,23 @@ ShiftMetatiles::ShiftMetatiles(Map *map,
|
||||
void ShiftMetatiles::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
if (!layout) return;
|
||||
|
||||
map->setBlockdata(newMetatiles, true);
|
||||
layout->setBlockdata(newMetatiles, true);
|
||||
|
||||
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
|
||||
layout->lastCommitBlocks.blocks = layout->blockdata;
|
||||
|
||||
renderMapBlocks(map, true);
|
||||
renderBlocks(layout, true);
|
||||
}
|
||||
|
||||
void ShiftMetatiles::undo() {
|
||||
if (!map) return;
|
||||
if (!layout) return;
|
||||
|
||||
map->setBlockdata(oldMetatiles, true);
|
||||
layout->setBlockdata(oldMetatiles, true);
|
||||
|
||||
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
|
||||
layout->lastCommitBlocks.blocks = layout->blockdata;
|
||||
|
||||
renderMapBlocks(map, true);
|
||||
renderBlocks(layout, true);
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
@@ -163,7 +162,7 @@ void ShiftMetatiles::undo() {
|
||||
bool ShiftMetatiles::mergeWith(const QUndoCommand *command) {
|
||||
const ShiftMetatiles *other = static_cast<const ShiftMetatiles *>(command);
|
||||
|
||||
if (this->map != other->map)
|
||||
if (this->layout != other->layout)
|
||||
return false;
|
||||
|
||||
if (actionId != other->actionId)
|
||||
@@ -178,20 +177,20 @@ bool ShiftMetatiles::mergeWith(const QUndoCommand *command) {
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
ResizeMap::ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
|
||||
ResizeLayout::ResizeLayout(Layout *layout, QSize oldLayoutDimensions, QSize newLayoutDimensions,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||
const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||
QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Resize Map");
|
||||
|
||||
this->map = map;
|
||||
this->layout = layout;
|
||||
|
||||
this->oldMapWidth = oldMapDimensions.width();
|
||||
this->oldMapHeight = oldMapDimensions.height();
|
||||
this->oldLayoutWidth = oldLayoutDimensions.width();
|
||||
this->oldLayoutHeight = oldLayoutDimensions.height();
|
||||
|
||||
this->newMapWidth = newMapDimensions.width();
|
||||
this->newMapHeight = newMapDimensions.height();
|
||||
this->newLayoutWidth = newLayoutDimensions.width();
|
||||
this->newLayoutHeight = newLayoutDimensions.height();
|
||||
|
||||
this->oldMetatiles = oldMetatiles;
|
||||
this->newMetatiles = newMetatiles;
|
||||
@@ -206,36 +205,36 @@ ResizeMap::ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
|
||||
this->newBorder = newBorder;
|
||||
}
|
||||
|
||||
void ResizeMap::redo() {
|
||||
void ResizeLayout::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
if (!layout) return;
|
||||
|
||||
map->layout->blockdata = newMetatiles;
|
||||
map->setDimensions(newMapWidth, newMapHeight, false, true);
|
||||
layout->blockdata = newMetatiles;
|
||||
layout->setDimensions(newLayoutWidth, newLayoutHeight, false, true);
|
||||
|
||||
map->layout->border = newBorder;
|
||||
map->setBorderDimensions(newBorderWidth, newBorderHeight, false, true);
|
||||
layout->border = newBorder;
|
||||
layout->setBorderDimensions(newBorderWidth, newBorderHeight, false, true);
|
||||
|
||||
map->layout->lastCommitBlocks.mapDimensions = QSize(map->getWidth(), map->getHeight());
|
||||
map->layout->lastCommitBlocks.borderDimensions = QSize(map->getBorderWidth(), map->getBorderHeight());
|
||||
layout->lastCommitBlocks.layoutDimensions = QSize(layout->getWidth(), layout->getHeight());
|
||||
layout->lastCommitBlocks.borderDimensions = QSize(layout->getBorderWidth(), layout->getBorderHeight());
|
||||
|
||||
map->mapNeedsRedrawing();
|
||||
layout->needsRedrawing();
|
||||
}
|
||||
|
||||
void ResizeMap::undo() {
|
||||
if (!map) return;
|
||||
void ResizeLayout::undo() {
|
||||
if (!layout) return;
|
||||
|
||||
map->layout->blockdata = oldMetatiles;
|
||||
map->setDimensions(oldMapWidth, oldMapHeight, false, true);
|
||||
layout->blockdata = oldMetatiles;
|
||||
layout->setDimensions(oldLayoutWidth, oldLayoutHeight, false, true);
|
||||
|
||||
map->layout->border = oldBorder;
|
||||
map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false, true);
|
||||
layout->border = oldBorder;
|
||||
layout->setBorderDimensions(oldBorderWidth, oldBorderHeight, false, true);
|
||||
|
||||
map->layout->lastCommitBlocks.mapDimensions = QSize(map->getWidth(), map->getHeight());
|
||||
map->layout->lastCommitBlocks.borderDimensions = QSize(map->getBorderWidth(), map->getBorderHeight());
|
||||
layout->lastCommitBlocks.layoutDimensions = QSize(layout->getWidth(), layout->getHeight());
|
||||
layout->lastCommitBlocks.borderDimensions = QSize(layout->getBorderWidth(), layout->getBorderHeight());
|
||||
|
||||
map->mapNeedsRedrawing();
|
||||
layout->needsRedrawing();
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
@@ -487,23 +486,23 @@ int EventPaste::id() const {
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
ScriptEditMap::ScriptEditMap(Map *map,
|
||||
QSize oldMapDimensions, QSize newMapDimensions,
|
||||
ScriptEditLayout::ScriptEditLayout(Layout *layout,
|
||||
QSize oldLayoutDimensions, QSize newLayoutDimensions,
|
||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||
QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||
const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||
QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Script Edit Map");
|
||||
setText("Script Edit Layout");
|
||||
|
||||
this->map = map;
|
||||
this->layout = layout;
|
||||
|
||||
this->newMetatiles = newMetatiles;
|
||||
this->oldMetatiles = oldMetatiles;
|
||||
|
||||
this->oldMapWidth = oldMapDimensions.width();
|
||||
this->oldMapHeight = oldMapDimensions.height();
|
||||
this->newMapWidth = newMapDimensions.width();
|
||||
this->newMapHeight = newMapDimensions.height();
|
||||
this->oldLayoutWidth = oldLayoutDimensions.width();
|
||||
this->oldLayoutHeight = oldLayoutDimensions.height();
|
||||
this->newLayoutWidth = newLayoutDimensions.width();
|
||||
this->newLayoutHeight = newLayoutDimensions.height();
|
||||
|
||||
this->oldBorder = oldBorder;
|
||||
this->newBorder = newBorder;
|
||||
@@ -514,58 +513,58 @@ ScriptEditMap::ScriptEditMap(Map *map,
|
||||
this->newBorderHeight = newBorderDimensions.height();
|
||||
}
|
||||
|
||||
void ScriptEditMap::redo() {
|
||||
void ScriptEditLayout::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
if (!layout) return;
|
||||
|
||||
if (newMapWidth != map->getWidth() || newMapHeight != map->getHeight()) {
|
||||
map->layout->blockdata = newMetatiles;
|
||||
map->setDimensions(newMapWidth, newMapHeight, false);
|
||||
if (newLayoutWidth != layout->getWidth() || newLayoutHeight != layout->getHeight()) {
|
||||
layout->blockdata = newMetatiles;
|
||||
layout->setDimensions(newLayoutWidth, newLayoutHeight, false);
|
||||
} else {
|
||||
map->setBlockdata(newMetatiles);
|
||||
layout->setBlockdata(newMetatiles);
|
||||
}
|
||||
|
||||
if (newBorderWidth != map->getBorderWidth() || newBorderHeight != map->getBorderHeight()) {
|
||||
map->layout->border = newBorder;
|
||||
map->setBorderDimensions(newBorderWidth, newBorderHeight, false);
|
||||
if (newBorderWidth != layout->getBorderWidth() || newBorderHeight != layout->getBorderHeight()) {
|
||||
layout->border = newBorder;
|
||||
layout->setBorderDimensions(newBorderWidth, newBorderHeight, false);
|
||||
} else {
|
||||
map->setBorderBlockData(newBorder);
|
||||
layout->setBorderBlockData(newBorder);
|
||||
}
|
||||
|
||||
map->layout->lastCommitBlocks.blocks = newMetatiles;
|
||||
map->layout->lastCommitBlocks.mapDimensions = QSize(newMapWidth, newMapHeight);
|
||||
map->layout->lastCommitBlocks.border = newBorder;
|
||||
map->layout->lastCommitBlocks.borderDimensions = QSize(newBorderWidth, newBorderHeight);
|
||||
layout->lastCommitBlocks.blocks = newMetatiles;
|
||||
layout->lastCommitBlocks.layoutDimensions = QSize(newLayoutWidth, newLayoutHeight);
|
||||
layout->lastCommitBlocks.border = newBorder;
|
||||
layout->lastCommitBlocks.borderDimensions = QSize(newBorderWidth, newBorderHeight);
|
||||
|
||||
renderMapBlocks(map);
|
||||
map->borderItem->draw();
|
||||
renderBlocks(layout, true);
|
||||
layout->borderItem->draw();
|
||||
}
|
||||
|
||||
void ScriptEditMap::undo() {
|
||||
if (!map) return;
|
||||
void ScriptEditLayout::undo() {
|
||||
if (!layout) return;
|
||||
|
||||
if (oldMapWidth != map->getWidth() || oldMapHeight != map->getHeight()) {
|
||||
map->layout->blockdata = oldMetatiles;
|
||||
map->setDimensions(oldMapWidth, oldMapHeight, false);
|
||||
if (oldLayoutWidth != layout->getWidth() || oldLayoutHeight != layout->getHeight()) {
|
||||
layout->blockdata = oldMetatiles;
|
||||
layout->setDimensions(oldLayoutWidth, oldLayoutHeight, false);
|
||||
} else {
|
||||
map->setBlockdata(oldMetatiles);
|
||||
layout->setBlockdata(oldMetatiles);
|
||||
}
|
||||
|
||||
if (oldBorderWidth != map->getBorderWidth() || oldBorderHeight != map->getBorderHeight()) {
|
||||
map->layout->border = oldBorder;
|
||||
map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false);
|
||||
if (oldBorderWidth != layout->getBorderWidth() || oldBorderHeight != layout->getBorderHeight()) {
|
||||
layout->border = oldBorder;
|
||||
layout->setBorderDimensions(oldBorderWidth, oldBorderHeight, false);
|
||||
} else {
|
||||
map->setBorderBlockData(oldBorder);
|
||||
layout->setBorderBlockData(oldBorder);
|
||||
}
|
||||
|
||||
map->layout->lastCommitBlocks.blocks = oldMetatiles;
|
||||
map->layout->lastCommitBlocks.mapDimensions = QSize(oldMapWidth, oldMapHeight);
|
||||
map->layout->lastCommitBlocks.border = oldBorder;
|
||||
map->layout->lastCommitBlocks.borderDimensions = QSize(oldBorderWidth, oldBorderHeight);
|
||||
layout->lastCommitBlocks.blocks = oldMetatiles;
|
||||
layout->lastCommitBlocks.layoutDimensions = QSize(oldLayoutWidth, oldLayoutHeight);
|
||||
layout->lastCommitBlocks.border = oldBorder;
|
||||
layout->lastCommitBlocks.borderDimensions = QSize(oldBorderWidth, oldBorderHeight);
|
||||
|
||||
renderMapBlocks(map);
|
||||
map->borderItem->draw();
|
||||
renderBlocks(layout, true);
|
||||
layout->borderItem->draw();
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
|
||||
@@ -146,10 +146,13 @@ void Event::loadPixmap(Project *) {
|
||||
this->pixmap = pixmap ? *pixmap : QPixmap();
|
||||
}
|
||||
|
||||
void Event::setIcons() {
|
||||
void Event::clearIcons() {
|
||||
qDeleteAll(icons);
|
||||
icons.clear();
|
||||
}
|
||||
|
||||
void Event::setIcons() {
|
||||
clearIcons();
|
||||
const int w = 16;
|
||||
const int h = 16;
|
||||
static const QPixmap defaultIcons = QPixmap(":/images/Entities_16x16.png");
|
||||
|
||||
51
src/core/filedialog.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "filedialog.h"
|
||||
|
||||
QString FileDialog::prevDirectory;
|
||||
|
||||
QString FileDialog::getDirectoryFromInput(const QString &dir) {
|
||||
if (dir.isEmpty())
|
||||
return FileDialog::prevDirectory;
|
||||
return dir;
|
||||
}
|
||||
|
||||
void FileDialog::setDirectoryFromFile(const QString &fileName) {
|
||||
if (!fileName.isEmpty())
|
||||
FileDialog::prevDirectory = QFileInfo(fileName).absolutePath();
|
||||
}
|
||||
|
||||
void FileDialog::restoreFocus(QWidget *parent) {
|
||||
if (parent) {
|
||||
parent->raise();
|
||||
parent->activateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
QString FileDialog::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) {
|
||||
const QString fileName = QFileDialog::getOpenFileName(parent, caption, getDirectoryFromInput(dir), filter, selectedFilter, options);
|
||||
setDirectoryFromFile(fileName);
|
||||
restoreFocus(parent);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
QStringList FileDialog::getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) {
|
||||
const QStringList fileNames = QFileDialog::getOpenFileNames(parent, caption, getDirectoryFromInput(dir), filter, selectedFilter, options);
|
||||
if (!fileNames.isEmpty())
|
||||
setDirectoryFromFile(fileNames.last());
|
||||
restoreFocus(parent);
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
QString FileDialog::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) {
|
||||
const QString fileName = QFileDialog::getSaveFileName(parent, caption, getDirectoryFromInput(dir), filter, selectedFilter, options);
|
||||
setDirectoryFromFile(fileName);
|
||||
restoreFocus(parent);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
QString FileDialog::getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options) {
|
||||
const QString existingDir = QFileDialog::getExistingDirectory(parent, caption, getDirectoryFromInput(dir), options);
|
||||
if (!existingDir.isEmpty())
|
||||
setDirectory(existingDir);
|
||||
restoreFocus(parent);
|
||||
return existingDir;
|
||||
}
|
||||
382
src/core/map.cpp
@@ -28,6 +28,13 @@ void Map::setName(QString mapName) {
|
||||
scriptsLoaded = false;
|
||||
}
|
||||
|
||||
void Map::setLayout(Layout *layout) {
|
||||
this->layout = layout;
|
||||
if (layout) {
|
||||
this->layoutId = layout->id;
|
||||
}
|
||||
}
|
||||
|
||||
QString Map::mapConstantFromName(QString mapName, bool includePrefix) {
|
||||
// Transform map names of the form 'GraniteCave_B1F` into map constants like 'MAP_GRANITE_CAVE_B1F'.
|
||||
static const QRegularExpression caseChange("([a-z])([A-Z])");
|
||||
@@ -60,165 +67,10 @@ int Map::getBorderHeight() {
|
||||
return layout->getBorderHeight();
|
||||
}
|
||||
|
||||
bool Map::mapBlockChanged(int i, const Blockdata &cache) {
|
||||
if (cache.length() <= i)
|
||||
return true;
|
||||
if (layout->blockdata.length() <= i)
|
||||
return true;
|
||||
|
||||
return layout->blockdata.at(i) != cache.at(i);
|
||||
}
|
||||
|
||||
bool Map::borderBlockChanged(int i, const Blockdata &cache) {
|
||||
if (cache.length() <= i)
|
||||
return true;
|
||||
if (layout->border.length() <= i)
|
||||
return true;
|
||||
|
||||
return layout->border.at(i) != cache.at(i);
|
||||
}
|
||||
|
||||
void Map::clearBorderCache() {
|
||||
layout->cached_border.clear();
|
||||
}
|
||||
|
||||
void Map::cacheBorder() {
|
||||
layout->cached_border.clear();
|
||||
for (const auto &block : layout->border)
|
||||
layout->cached_border.append(block);
|
||||
}
|
||||
|
||||
void Map::cacheBlockdata() {
|
||||
layout->cached_blockdata.clear();
|
||||
for (const auto &block : layout->blockdata)
|
||||
layout->cached_blockdata.append(block);
|
||||
}
|
||||
|
||||
void Map::cacheCollision() {
|
||||
layout->cached_collision.clear();
|
||||
for (const auto &block : layout->blockdata)
|
||||
layout->cached_collision.append(block);
|
||||
}
|
||||
|
||||
QPixmap Map::renderCollision(bool ignoreCache) {
|
||||
bool changed_any = false;
|
||||
int width_ = getWidth();
|
||||
int height_ = getHeight();
|
||||
if (collision_image.isNull() || collision_image.width() != width_ * 16 || collision_image.height() != height_ * 16) {
|
||||
collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
changed_any = true;
|
||||
}
|
||||
if (layout->blockdata.isEmpty() || !width_ || !height_) {
|
||||
collision_pixmap = collision_pixmap.fromImage(collision_image);
|
||||
return collision_pixmap;
|
||||
}
|
||||
QPainter painter(&collision_image);
|
||||
for (int i = 0; i < layout->blockdata.length(); i++) {
|
||||
if (!ignoreCache && !mapBlockChanged(i, layout->cached_collision)) {
|
||||
continue;
|
||||
}
|
||||
changed_any = true;
|
||||
Block block = layout->blockdata.at(i);
|
||||
QImage collision_metatile_image = getCollisionMetatileImage(block);
|
||||
int map_y = width_ ? i / width_ : 0;
|
||||
int map_x = width_ ? i % width_ : 0;
|
||||
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
|
||||
painter.drawImage(metatile_origin, collision_metatile_image);
|
||||
}
|
||||
painter.end();
|
||||
cacheCollision();
|
||||
if (changed_any) {
|
||||
collision_pixmap = collision_pixmap.fromImage(collision_image);
|
||||
}
|
||||
return collision_pixmap;
|
||||
}
|
||||
|
||||
QPixmap Map::render(bool ignoreCache, MapLayout * fromLayout, QRect bounds) {
|
||||
bool changed_any = false;
|
||||
int width_ = getWidth();
|
||||
int height_ = getHeight();
|
||||
if (image.isNull() || image.width() != width_ * 16 || image.height() != height_ * 16) {
|
||||
image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
changed_any = true;
|
||||
}
|
||||
if (layout->blockdata.isEmpty() || !width_ || !height_) {
|
||||
pixmap = pixmap.fromImage(image);
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QPainter painter(&image);
|
||||
for (int i = 0; i < layout->blockdata.length(); i++) {
|
||||
if (!ignoreCache && !mapBlockChanged(i, layout->cached_blockdata)) {
|
||||
continue;
|
||||
}
|
||||
changed_any = true;
|
||||
int map_y = width_ ? i / width_ : 0;
|
||||
int map_x = width_ ? i % width_ : 0;
|
||||
if (bounds.isValid() && !bounds.contains(map_x, map_y)) {
|
||||
continue;
|
||||
}
|
||||
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
|
||||
Block block = layout->blockdata.at(i);
|
||||
QImage metatile_image = getMetatileImage(
|
||||
block.metatileId(),
|
||||
fromLayout ? fromLayout->tileset_primary : layout->tileset_primary,
|
||||
fromLayout ? fromLayout->tileset_secondary : layout->tileset_secondary,
|
||||
metatileLayerOrder,
|
||||
metatileLayerOpacity
|
||||
);
|
||||
painter.drawImage(metatile_origin, metatile_image);
|
||||
}
|
||||
painter.end();
|
||||
if (changed_any) {
|
||||
cacheBlockdata();
|
||||
pixmap = pixmap.fromImage(image);
|
||||
}
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QPixmap Map::renderBorder(bool ignoreCache) {
|
||||
bool changed_any = false, border_resized = false;
|
||||
int width_ = getBorderWidth();
|
||||
int height_ = getBorderHeight();
|
||||
if (layout->border_image.isNull()) {
|
||||
layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
changed_any = true;
|
||||
}
|
||||
if (layout->border_image.width() != width_ * 16 || layout->border_image.height() != height_ * 16) {
|
||||
layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
border_resized = true;
|
||||
}
|
||||
if (layout->border.isEmpty()) {
|
||||
layout->border_pixmap = layout->border_pixmap.fromImage(layout->border_image);
|
||||
return layout->border_pixmap;
|
||||
}
|
||||
QPainter painter(&layout->border_image);
|
||||
for (int i = 0; i < layout->border.length(); i++) {
|
||||
if (!ignoreCache && (!border_resized && !borderBlockChanged(i, layout->cached_border))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
changed_any = true;
|
||||
Block block = layout->border.at(i);
|
||||
uint16_t metatileId = block.metatileId();
|
||||
QImage metatile_image = getMetatileImage(metatileId, layout->tileset_primary, layout->tileset_secondary, metatileLayerOrder, metatileLayerOpacity);
|
||||
int map_y = width_ ? i / width_ : 0;
|
||||
int map_x = width_ ? i % width_ : 0;
|
||||
painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image);
|
||||
}
|
||||
painter.end();
|
||||
if (changed_any) {
|
||||
cacheBorder();
|
||||
layout->border_pixmap = layout->border_pixmap.fromImage(layout->border_image);
|
||||
}
|
||||
return layout->border_pixmap;
|
||||
}
|
||||
|
||||
// Get the portion of the map that can be rendered when rendered as a map connection.
|
||||
// Cardinal connections render the nearest segment of their map and within the bounds of the border draw distance,
|
||||
// Dive/Emerge connections are rendered normally within the bounds of their parent map.
|
||||
QRect Map::getConnectionRect(const QString &direction, MapLayout * fromLayout) {
|
||||
QRect Map::getConnectionRect(const QString &direction, Layout * fromLayout) {
|
||||
int x = 0, y = 0;
|
||||
int w = getWidth(), h = getHeight();
|
||||
|
||||
@@ -244,7 +96,7 @@ QRect Map::getConnectionRect(const QString &direction, MapLayout * fromLayout) {
|
||||
return QRect(x, y, w, h);
|
||||
}
|
||||
|
||||
QPixmap Map::renderConnection(const QString &direction, MapLayout * fromLayout) {
|
||||
QPixmap Map::renderConnection(const QString &direction, Layout * fromLayout) {
|
||||
QRect bounds = getConnectionRect(direction, fromLayout);
|
||||
if (!bounds.isValid())
|
||||
return QPixmap();
|
||||
@@ -254,214 +106,14 @@ QPixmap Map::renderConnection(const QString &direction, MapLayout * fromLayout)
|
||||
if (MapConnection::isDiving(direction))
|
||||
fromLayout = nullptr;
|
||||
|
||||
render(true, fromLayout, bounds);
|
||||
QImage connection_image = image.copy(bounds.x() * 16, bounds.y() * 16, bounds.width() * 16, bounds.height() * 16);
|
||||
return QPixmap::fromImage(connection_image);
|
||||
}
|
||||
|
||||
void Map::setNewDimensionsBlockdata(int newWidth, int newHeight) {
|
||||
int oldWidth = getWidth();
|
||||
int oldHeight = getHeight();
|
||||
|
||||
Blockdata newBlockdata;
|
||||
|
||||
for (int y = 0; y < newHeight; y++)
|
||||
for (int x = 0; x < newWidth; x++) {
|
||||
if (x < oldWidth && y < oldHeight) {
|
||||
int index = y * oldWidth + x;
|
||||
newBlockdata.append(layout->blockdata.value(index));
|
||||
} else {
|
||||
newBlockdata.append(0);
|
||||
}
|
||||
}
|
||||
|
||||
layout->blockdata = newBlockdata;
|
||||
}
|
||||
|
||||
void Map::setNewBorderDimensionsBlockdata(int newWidth, int newHeight) {
|
||||
int oldWidth = getBorderWidth();
|
||||
int oldHeight = getBorderHeight();
|
||||
|
||||
Blockdata newBlockdata;
|
||||
|
||||
for (int y = 0; y < newHeight; y++)
|
||||
for (int x = 0; x < newWidth; x++) {
|
||||
if (x < oldWidth && y < oldHeight) {
|
||||
int index = y * oldWidth + x;
|
||||
newBlockdata.append(layout->border.value(index));
|
||||
} else {
|
||||
newBlockdata.append(0);
|
||||
}
|
||||
}
|
||||
|
||||
layout->border = newBlockdata;
|
||||
}
|
||||
|
||||
void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata, bool enableScriptCallback) {
|
||||
if (setNewBlockdata) {
|
||||
setNewDimensionsBlockdata(newWidth, newHeight);
|
||||
}
|
||||
|
||||
int oldWidth = layout->width;
|
||||
int oldHeight = layout->height;
|
||||
layout->width = newWidth;
|
||||
layout->height = newHeight;
|
||||
|
||||
if (enableScriptCallback && (oldWidth != newWidth || oldHeight != newHeight)) {
|
||||
Scripting::cb_MapResized(oldWidth, oldHeight, newWidth, newHeight);
|
||||
}
|
||||
|
||||
emit mapDimensionsChanged(QSize(getWidth(), getHeight()));
|
||||
modify();
|
||||
}
|
||||
|
||||
void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata, bool enableScriptCallback) {
|
||||
if (setNewBlockdata) {
|
||||
setNewBorderDimensionsBlockdata(newWidth, newHeight);
|
||||
}
|
||||
|
||||
int oldWidth = layout->border_width;
|
||||
int oldHeight = layout->border_height;
|
||||
layout->border_width = newWidth;
|
||||
layout->border_height = newHeight;
|
||||
|
||||
if (enableScriptCallback && (oldWidth != newWidth || oldHeight != newHeight)) {
|
||||
Scripting::cb_BorderResized(oldWidth, oldHeight, newWidth, newHeight);
|
||||
}
|
||||
|
||||
modify();
|
||||
QPixmap connectionPixmap = this->layout->render(true, fromLayout, bounds);
|
||||
return connectionPixmap.copy(bounds.x() * 16, bounds.y() * 16, bounds.width() * 16, bounds.height() * 16);
|
||||
}
|
||||
|
||||
void Map::openScript(QString label) {
|
||||
emit openScriptRequested(label);
|
||||
}
|
||||
|
||||
bool Map::getBlock(int x, int y, Block *out) {
|
||||
if (isWithinBounds(x, y)) {
|
||||
int i = y * getWidth() + x;
|
||||
*out = layout->blockdata.value(i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Map::setBlock(int x, int y, Block block, bool enableScriptCallback) {
|
||||
if (!isWithinBounds(x, y)) return;
|
||||
int i = y * getWidth() + x;
|
||||
if (i < layout->blockdata.size()) {
|
||||
Block prevBlock = layout->blockdata.at(i);
|
||||
layout->blockdata.replace(i, block);
|
||||
if (enableScriptCallback) {
|
||||
Scripting::cb_MetatileChanged(x, y, prevBlock, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::setBlockdata(Blockdata blockdata, bool enableScriptCallback) {
|
||||
int width = getWidth();
|
||||
int size = qMin(blockdata.size(), layout->blockdata.size());
|
||||
for (int i = 0; i < size; i++) {
|
||||
Block prevBlock = layout->blockdata.at(i);
|
||||
Block newBlock = blockdata.at(i);
|
||||
if (prevBlock != newBlock) {
|
||||
layout->blockdata.replace(i, newBlock);
|
||||
if (enableScriptCallback)
|
||||
Scripting::cb_MetatileChanged(i % width, i / width, prevBlock, newBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Map::getBorderMetatileId(int x, int y) {
|
||||
int i = y * getBorderWidth() + x;
|
||||
return layout->border[i].metatileId();
|
||||
}
|
||||
|
||||
void Map::setBorderMetatileId(int x, int y, uint16_t metatileId, bool enableScriptCallback) {
|
||||
int i = y * getBorderWidth() + x;
|
||||
if (i < layout->border.size()) {
|
||||
uint16_t prevMetatileId = layout->border[i].metatileId();
|
||||
layout->border[i].setMetatileId(metatileId);
|
||||
if (prevMetatileId != metatileId && enableScriptCallback) {
|
||||
Scripting::cb_BorderMetatileChanged(x, y, prevMetatileId, metatileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::setBorderBlockData(Blockdata blockdata, bool enableScriptCallback) {
|
||||
int width = getBorderWidth();
|
||||
int size = qMin(blockdata.size(), layout->border.size());
|
||||
for (int i = 0; i < size; i++) {
|
||||
Block prevBlock = layout->border.at(i);
|
||||
Block newBlock = blockdata.at(i);
|
||||
if (prevBlock != newBlock) {
|
||||
layout->border.replace(i, newBlock);
|
||||
if (enableScriptCallback)
|
||||
Scripting::cb_BorderMetatileChanged(i % width, i / width, prevBlock.metatileId(), newBlock.metatileId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::_floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) {
|
||||
QList<QPoint> todo;
|
||||
todo.append(QPoint(x, y));
|
||||
while (todo.length()) {
|
||||
QPoint point = todo.takeAt(0);
|
||||
x = point.x();
|
||||
y = point.y();
|
||||
Block block;
|
||||
if (!getBlock(x, y, &block)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint old_coll = block.collision();
|
||||
uint old_elev = block.elevation();
|
||||
if (old_coll == collision && old_elev == elevation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
block.setCollision(collision);
|
||||
block.setElevation(elevation);
|
||||
setBlock(x, y, block, true);
|
||||
if (getBlock(x + 1, y, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
todo.append(QPoint(x + 1, y));
|
||||
}
|
||||
if (getBlock(x - 1, y, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
todo.append(QPoint(x - 1, y));
|
||||
}
|
||||
if (getBlock(x, y + 1, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
todo.append(QPoint(x, y + 1));
|
||||
}
|
||||
if (getBlock(x, y - 1, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
todo.append(QPoint(x, y - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) {
|
||||
Block block;
|
||||
if (getBlock(x, y, &block) && (block.collision() != collision || block.elevation() != elevation)) {
|
||||
_floodFillCollisionElevation(x, y, collision, elevation);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::magicFillCollisionElevation(int initialX, int initialY, uint16_t collision, uint16_t elevation) {
|
||||
Block block;
|
||||
if (getBlock(initialX, initialY, &block) && (block.collision() != collision || block.elevation() != elevation)) {
|
||||
uint old_coll = block.collision();
|
||||
uint old_elev = block.elevation();
|
||||
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int x = 0; x < getWidth(); x++) {
|
||||
if (getBlock(x, y, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
block.setCollision(collision);
|
||||
block.setElevation(elevation);
|
||||
setBlock(x, y, block, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<Event *> Map::getAllEvents() const {
|
||||
QList<Event *> all_events;
|
||||
for (const auto &event_list : events) {
|
||||
@@ -604,8 +256,8 @@ void Map::clean() {
|
||||
this->hasUnsavedDataChanges = false;
|
||||
}
|
||||
|
||||
bool Map::hasUnsavedChanges() {
|
||||
return !editHistory.isClean() || hasUnsavedDataChanges || !isPersistedToFile;
|
||||
bool Map::hasUnsavedChanges() const {
|
||||
return !editHistory.isClean() || this->layout->hasUnsavedChanges() || hasUnsavedDataChanges || !isPersistedToFile;
|
||||
}
|
||||
|
||||
void Map::pruneEditHistory() {
|
||||
@@ -628,11 +280,3 @@ void Map::pruneEditHistory() {
|
||||
command->setObsolete(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool Map::isWithinBounds(int x, int y) {
|
||||
return (x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight());
|
||||
}
|
||||
|
||||
bool Map::isWithinBorderBounds(int x, int y) {
|
||||
return (x >= 0 && x < this->getBorderWidth() && y >= 0 && y < this->getBorderHeight());
|
||||
}
|
||||
|
||||
@@ -2,7 +2,35 @@
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
QString MapLayout::layoutConstantFromName(QString mapName) {
|
||||
#include "scripting.h"
|
||||
#include "imageproviders.h"
|
||||
|
||||
|
||||
|
||||
Layout *Layout::copy() {
|
||||
Layout *layout = new Layout;
|
||||
layout->copyFrom(this);
|
||||
return layout;
|
||||
}
|
||||
|
||||
void Layout::copyFrom(Layout *other) {
|
||||
this->id = other->id;
|
||||
this->name = other->name;
|
||||
this->width = other->width;
|
||||
this->height = other->height;
|
||||
this->border_width = other->border_width;
|
||||
this->border_height = other->border_height;
|
||||
this->border_path = other->border_path;
|
||||
this->blockdata_path = other->blockdata_path;
|
||||
this->tileset_primary_label = other->tileset_primary_label;
|
||||
this->tileset_secondary_label = other->tileset_secondary_label;
|
||||
this->tileset_primary = other->tileset_primary;
|
||||
this->tileset_secondary = other->tileset_secondary;
|
||||
this->blockdata = other->blockdata;
|
||||
this->border = other->border;
|
||||
}
|
||||
|
||||
QString Layout::layoutConstantFromName(QString mapName) {
|
||||
// Transform map names of the form 'GraniteCave_B1F` into layout constants like 'LAYOUT_GRANITE_CAVE_B1F'.
|
||||
static const QRegularExpression caseChange("([a-z])([A-Z])");
|
||||
QString nameWithUnderscores = mapName.replace(caseChange, "\\1_\\2");
|
||||
@@ -17,18 +45,379 @@ QString MapLayout::layoutConstantFromName(QString mapName) {
|
||||
return constantName;
|
||||
}
|
||||
|
||||
int MapLayout::getWidth() {
|
||||
int Layout::getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
int MapLayout::getHeight() {
|
||||
int Layout::getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
int MapLayout::getBorderWidth() {
|
||||
int Layout::getBorderWidth() {
|
||||
return border_width;
|
||||
}
|
||||
|
||||
int MapLayout::getBorderHeight() {
|
||||
int Layout::getBorderHeight() {
|
||||
return border_height;
|
||||
}
|
||||
|
||||
bool Layout::isWithinBounds(int x, int y) {
|
||||
return (x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight());
|
||||
}
|
||||
|
||||
bool Layout::isWithinBorderBounds(int x, int y) {
|
||||
return (x >= 0 && x < this->getBorderWidth() && y >= 0 && y < this->getBorderHeight());
|
||||
}
|
||||
|
||||
bool Layout::getBlock(int x, int y, Block *out) {
|
||||
if (isWithinBounds(x, y)) {
|
||||
int i = y * getWidth() + x;
|
||||
*out = this->blockdata.value(i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Layout::setBlock(int x, int y, Block block, bool enableScriptCallback) {
|
||||
if (!isWithinBounds(x, y)) return;
|
||||
int i = y * getWidth() + x;
|
||||
if (i < this->blockdata.size()) {
|
||||
Block prevBlock = this->blockdata.at(i);
|
||||
this->blockdata.replace(i, block);
|
||||
if (enableScriptCallback) {
|
||||
Scripting::cb_MetatileChanged(x, y, prevBlock, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::setBlockdata(Blockdata newBlockdata, bool enableScriptCallback) {
|
||||
int width = getWidth();
|
||||
int size = qMin(newBlockdata.size(), this->blockdata.size());
|
||||
for (int i = 0; i < size; i++) {
|
||||
Block prevBlock = this->blockdata.at(i);
|
||||
Block newBlock = newBlockdata.at(i);
|
||||
if (prevBlock != newBlock) {
|
||||
this->blockdata.replace(i, newBlock);
|
||||
if (enableScriptCallback)
|
||||
Scripting::cb_MetatileChanged(i % width, i / width, prevBlock, newBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::clearBorderCache() {
|
||||
this->cached_border.clear();
|
||||
}
|
||||
|
||||
void Layout::cacheBorder() {
|
||||
this->cached_border.clear();
|
||||
for (const auto &block : this->border)
|
||||
this->cached_border.append(block);
|
||||
}
|
||||
|
||||
void Layout::cacheBlockdata() {
|
||||
this->cached_blockdata.clear();
|
||||
for (const auto &block : this->blockdata)
|
||||
this->cached_blockdata.append(block);
|
||||
}
|
||||
|
||||
void Layout::cacheCollision() {
|
||||
this->cached_collision.clear();
|
||||
for (const auto &block : this->blockdata)
|
||||
this->cached_collision.append(block);
|
||||
}
|
||||
|
||||
bool Layout::layoutBlockChanged(int i, const Blockdata &cache) {
|
||||
if (cache.length() <= i)
|
||||
return true;
|
||||
if (this->blockdata.length() <= i)
|
||||
return true;
|
||||
|
||||
return this->blockdata.at(i) != cache.at(i);
|
||||
}
|
||||
|
||||
uint16_t Layout::getBorderMetatileId(int x, int y) {
|
||||
int i = y * getBorderWidth() + x;
|
||||
return this->border[i].metatileId();
|
||||
}
|
||||
|
||||
void Layout::setBorderMetatileId(int x, int y, uint16_t metatileId, bool enableScriptCallback) {
|
||||
int i = y * getBorderWidth() + x;
|
||||
if (i < this->border.size()) {
|
||||
uint16_t prevMetatileId = this->border[i].metatileId();
|
||||
this->border[i].setMetatileId(metatileId);
|
||||
if (prevMetatileId != metatileId && enableScriptCallback) {
|
||||
Scripting::cb_BorderMetatileChanged(x, y, prevMetatileId, metatileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::setBorderBlockData(Blockdata newBlockdata, bool enableScriptCallback) {
|
||||
int width = getBorderWidth();
|
||||
int size = qMin(newBlockdata.size(), this->border.size());
|
||||
for (int i = 0; i < size; i++) {
|
||||
Block prevBlock = this->border.at(i);
|
||||
Block newBlock = newBlockdata.at(i);
|
||||
if (prevBlock != newBlock) {
|
||||
this->border.replace(i, newBlock);
|
||||
if (enableScriptCallback)
|
||||
Scripting::cb_BorderMetatileChanged(i % width, i / width, prevBlock.metatileId(), newBlock.metatileId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::setDimensions(int newWidth, int newHeight, bool setNewBlockdata, bool enableScriptCallback) {
|
||||
if (setNewBlockdata) {
|
||||
setNewDimensionsBlockdata(newWidth, newHeight);
|
||||
}
|
||||
|
||||
int oldWidth = this->width;
|
||||
int oldHeight = this->height;
|
||||
this->width = newWidth;
|
||||
this->height = newHeight;
|
||||
|
||||
if (enableScriptCallback && (oldWidth != newWidth || oldHeight != newHeight)) {
|
||||
Scripting::cb_MapResized(oldWidth, oldHeight, newWidth, newHeight);
|
||||
}
|
||||
|
||||
emit layoutChanged(this);
|
||||
emit layoutDimensionsChanged(QSize(getWidth(), getHeight()));
|
||||
}
|
||||
|
||||
void Layout::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata, bool enableScriptCallback) {
|
||||
if (setNewBlockdata) {
|
||||
setNewBorderDimensionsBlockdata(newWidth, newHeight);
|
||||
}
|
||||
|
||||
int oldWidth = this->border_width;
|
||||
int oldHeight = this->border_height;
|
||||
this->border_width = newWidth;
|
||||
this->border_height = newHeight;
|
||||
|
||||
if (enableScriptCallback && (oldWidth != newWidth || oldHeight != newHeight)) {
|
||||
Scripting::cb_BorderResized(oldWidth, oldHeight, newWidth, newHeight);
|
||||
}
|
||||
|
||||
emit layoutChanged(this);
|
||||
}
|
||||
|
||||
void Layout::setNewDimensionsBlockdata(int newWidth, int newHeight) {
|
||||
int oldWidth = getWidth();
|
||||
int oldHeight = getHeight();
|
||||
|
||||
Blockdata newBlockdata;
|
||||
|
||||
for (int y = 0; y < newHeight; y++)
|
||||
for (int x = 0; x < newWidth; x++) {
|
||||
if (x < oldWidth && y < oldHeight) {
|
||||
int index = y * oldWidth + x;
|
||||
newBlockdata.append(this->blockdata.value(index));
|
||||
} else {
|
||||
newBlockdata.append(0);
|
||||
}
|
||||
}
|
||||
|
||||
this->blockdata = newBlockdata;
|
||||
}
|
||||
|
||||
void Layout::setNewBorderDimensionsBlockdata(int newWidth, int newHeight) {
|
||||
int oldWidth = getBorderWidth();
|
||||
int oldHeight = getBorderHeight();
|
||||
|
||||
Blockdata newBlockdata;
|
||||
|
||||
for (int y = 0; y < newHeight; y++)
|
||||
for (int x = 0; x < newWidth; x++) {
|
||||
if (x < oldWidth && y < oldHeight) {
|
||||
int index = y * oldWidth + x;
|
||||
newBlockdata.append(this->border.value(index));
|
||||
} else {
|
||||
newBlockdata.append(0);
|
||||
}
|
||||
}
|
||||
|
||||
this->border = newBlockdata;
|
||||
}
|
||||
|
||||
void Layout::_floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) {
|
||||
QList<QPoint> todo;
|
||||
todo.append(QPoint(x, y));
|
||||
while (todo.length()) {
|
||||
QPoint point = todo.takeAt(0);
|
||||
x = point.x();
|
||||
y = point.y();
|
||||
Block block;
|
||||
if (!getBlock(x, y, &block)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint old_coll = block.collision();
|
||||
uint old_elev = block.elevation();
|
||||
if (old_coll == collision && old_elev == elevation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
block.setCollision(collision);
|
||||
block.setElevation(elevation);
|
||||
setBlock(x, y, block, true);
|
||||
if (getBlock(x + 1, y, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
todo.append(QPoint(x + 1, y));
|
||||
}
|
||||
if (getBlock(x - 1, y, &block) && block.collision() == old_coll && block.elevation()== old_elev) {
|
||||
todo.append(QPoint(x - 1, y));
|
||||
}
|
||||
if (getBlock(x, y + 1, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
todo.append(QPoint(x, y + 1));
|
||||
}
|
||||
if (getBlock(x, y - 1, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
todo.append(QPoint(x, y - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) {
|
||||
Block block;
|
||||
if (getBlock(x, y, &block) && (block.collision() != collision || block.elevation() != elevation)) {
|
||||
_floodFillCollisionElevation(x, y, collision, elevation);
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::magicFillCollisionElevation(int initialX, int initialY, uint16_t collision, uint16_t elevation) {
|
||||
Block block;
|
||||
if (getBlock(initialX, initialY, &block) && (block.collision() != collision || block.elevation() != elevation)) {
|
||||
uint old_coll = block.collision();
|
||||
uint old_elev = block.elevation();
|
||||
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int x = 0; x < getWidth(); x++) {
|
||||
if (getBlock(x, y, &block) && block.collision() == old_coll && block.elevation() == old_elev) {
|
||||
block.setCollision(collision);
|
||||
block.setElevation(elevation);
|
||||
setBlock(x, y, block, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap Layout::render(bool ignoreCache, Layout *fromLayout, QRect bounds) {
|
||||
bool changed_any = false;
|
||||
int width_ = getWidth();
|
||||
int height_ = getHeight();
|
||||
if (image.isNull() || image.width() != width_ * 16 || image.height() != height_ * 16) {
|
||||
image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
changed_any = true;
|
||||
}
|
||||
if (this->blockdata.isEmpty() || !width_ || !height_) {
|
||||
pixmap = pixmap.fromImage(image);
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QPainter painter(&image);
|
||||
for (int i = 0; i < this->blockdata.length(); i++) {
|
||||
if (!ignoreCache && !layoutBlockChanged(i, this->cached_blockdata)) {
|
||||
continue;
|
||||
}
|
||||
changed_any = true;
|
||||
int map_y = width_ ? i / width_ : 0;
|
||||
int map_x = width_ ? i % width_ : 0;
|
||||
if (bounds.isValid() && !bounds.contains(map_x, map_y)) {
|
||||
continue;
|
||||
}
|
||||
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
|
||||
Block block = this->blockdata.at(i);
|
||||
QImage metatile_image = getMetatileImage(
|
||||
block.metatileId(),
|
||||
fromLayout ? fromLayout->tileset_primary : this->tileset_primary,
|
||||
fromLayout ? fromLayout->tileset_secondary : this->tileset_secondary,
|
||||
metatileLayerOrder,
|
||||
metatileLayerOpacity
|
||||
);
|
||||
painter.drawImage(metatile_origin, metatile_image);
|
||||
}
|
||||
painter.end();
|
||||
if (changed_any) {
|
||||
cacheBlockdata();
|
||||
pixmap = pixmap.fromImage(image);
|
||||
}
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QPixmap Layout::renderCollision(bool ignoreCache) {
|
||||
bool changed_any = false;
|
||||
int width_ = getWidth();
|
||||
int height_ = getHeight();
|
||||
if (collision_image.isNull() || collision_image.width() != width_ * 16 || collision_image.height() != height_ * 16) {
|
||||
collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
changed_any = true;
|
||||
}
|
||||
if (this->blockdata.isEmpty() || !width_ || !height_) {
|
||||
collision_pixmap = collision_pixmap.fromImage(collision_image);
|
||||
return collision_pixmap;
|
||||
}
|
||||
QPainter painter(&collision_image);
|
||||
for (int i = 0; i < this->blockdata.length(); i++) {
|
||||
if (!ignoreCache && !layoutBlockChanged(i, this->cached_collision)) {
|
||||
continue;
|
||||
}
|
||||
changed_any = true;
|
||||
Block block = this->blockdata.at(i);
|
||||
QImage collision_metatile_image = getCollisionMetatileImage(block);
|
||||
int map_y = width_ ? i / width_ : 0;
|
||||
int map_x = width_ ? i % width_ : 0;
|
||||
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
|
||||
painter.drawImage(metatile_origin, collision_metatile_image);
|
||||
}
|
||||
painter.end();
|
||||
cacheCollision();
|
||||
if (changed_any) {
|
||||
collision_pixmap = collision_pixmap.fromImage(collision_image);
|
||||
}
|
||||
return collision_pixmap;
|
||||
}
|
||||
|
||||
QPixmap Layout::renderBorder(bool ignoreCache) {
|
||||
bool changed_any = false, border_resized = false;
|
||||
int width_ = getBorderWidth();
|
||||
int height_ = getBorderHeight();
|
||||
if (this->border_image.isNull()) {
|
||||
this->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
changed_any = true;
|
||||
}
|
||||
if (this->border_image.width() != width_ * 16 || this->border_image.height() != height_ * 16) {
|
||||
this->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
border_resized = true;
|
||||
}
|
||||
if (this->border.isEmpty()) {
|
||||
this->border_pixmap = this->border_pixmap.fromImage(this->border_image);
|
||||
return this->border_pixmap;
|
||||
}
|
||||
QPainter painter(&this->border_image);
|
||||
for (int i = 0; i < this->border.length(); i++) {
|
||||
if (!ignoreCache && (!border_resized && !layoutBlockChanged(i, this->cached_border))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
changed_any = true;
|
||||
Block block = this->border.at(i);
|
||||
uint16_t metatileId = block.metatileId();
|
||||
QImage metatile_image = getMetatileImage(metatileId, this->tileset_primary, this->tileset_secondary, metatileLayerOrder, metatileLayerOpacity);
|
||||
int map_y = width_ ? i / width_ : 0;
|
||||
int map_x = width_ ? i % width_ : 0;
|
||||
painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image);
|
||||
}
|
||||
painter.end();
|
||||
if (changed_any) {
|
||||
cacheBorder();
|
||||
this->border_pixmap = this->border_pixmap.fromImage(this->border_image);
|
||||
}
|
||||
return this->border_pixmap;
|
||||
}
|
||||
|
||||
QPixmap Layout::getLayoutItemPixmap() {
|
||||
return this->layoutItem ? this->layoutItem->pixmap() : QPixmap();
|
||||
}
|
||||
|
||||
bool Layout::hasUnsavedChanges() const {
|
||||
return !this->editHistory.isClean();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ MapParser::MapParser()
|
||||
{
|
||||
}
|
||||
|
||||
MapLayout *MapParser::parse(QString filepath, bool *error, Project *project)
|
||||
Layout *MapParser::parse(QString filepath, bool *error, Project *project)
|
||||
{
|
||||
QFile file(filepath);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
@@ -69,7 +69,7 @@ MapLayout *MapParser::parse(QString filepath, bool *error, Project *project)
|
||||
}
|
||||
}
|
||||
|
||||
MapLayout *mapLayout = new MapLayout();
|
||||
Layout *mapLayout = new Layout();
|
||||
mapLayout->width = mapWidth;
|
||||
mapLayout->height = mapHeight;
|
||||
mapLayout->border_width = (borderWidth == 0) ? DEFAULT_BORDER_WIDTH : borderWidth;
|
||||
|
||||
@@ -49,10 +49,10 @@ void ParseUtil::recordErrors(const QStringList &errors) {
|
||||
}
|
||||
|
||||
void ParseUtil::logRecordedErrors() {
|
||||
QStringList errors = this->errorMap.value(this->curDefine);
|
||||
const QStringList errors = this->errorMap.value(this->curDefine);
|
||||
if (errors.isEmpty()) return;
|
||||
QString message = QString("Failed to parse '%1':").arg(this->curDefine);
|
||||
for (const auto error : errors)
|
||||
for (const auto &error : errors)
|
||||
message.append(QString("\n%1").arg(error));
|
||||
logError(message);
|
||||
}
|
||||
@@ -370,13 +370,14 @@ QStringList ParseUtil::readCIncbinArray(const QString &filename, const QString &
|
||||
return paths;
|
||||
}
|
||||
|
||||
bool ParseUtil::defineNameMatchesFilter(const QString &name, const QStringList &filterList, bool useRegex) {
|
||||
bool ParseUtil::defineNameMatchesFilter(const QString &name, const QStringList &filterList) const {
|
||||
return filterList.contains(name);
|
||||
}
|
||||
|
||||
bool ParseUtil::defineNameMatchesFilter(const QString &name, const QList<QRegularExpression> &filterList) const {
|
||||
for (auto filter : filterList) {
|
||||
if (useRegex) {
|
||||
// TODO: These QRegularExpression should probably be constructed beforehand,
|
||||
// otherwise we recreate them for every define we check.
|
||||
if (QRegularExpression(filter).match(name).hasMatch()) return true;
|
||||
} else if (name == filter) return true;
|
||||
if (filter.match(name).hasMatch())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -405,6 +406,21 @@ ParseUtil::ParsedDefines ParseUtil::readCDefines(const QString &filename, const
|
||||
if (this->text.isEmpty())
|
||||
return result;
|
||||
|
||||
// If necessary, construct regular expressions from filter list
|
||||
QList<QRegularExpression> filterList_Regex;
|
||||
if (useRegex) {
|
||||
for (auto filter : filterList) {
|
||||
filterList_Regex.append(QRegularExpression(filter));
|
||||
}
|
||||
}
|
||||
|
||||
// Create lambda function to match the define name to the filter, depending on the filter type
|
||||
auto matchesFilter = [this, &filterList, &filterList_Regex, useRegex](const QString &name) {
|
||||
if (useRegex)
|
||||
return defineNameMatchesFilter(name, filterList_Regex);
|
||||
return defineNameMatchesFilter(name, filterList);
|
||||
};
|
||||
|
||||
// Capture either the name and value of a #define, or everything between the braces of 'enum { }'
|
||||
static const QRegularExpression re("#define\\s+(?<defineName>\\w+)[\\s\\n][^\\S\\n]*(?<defineValue>.+)?"
|
||||
"|\\benum\\b[^{]*{(?<enumBody>[^}]*)}");
|
||||
@@ -437,14 +453,14 @@ ParseUtil::ParsedDefines ParseUtil::readCDefines(const QString &filename, const
|
||||
baseNum = 1;
|
||||
}
|
||||
result.expressions.insert(name, expression);
|
||||
if (defineNameMatchesFilter(name, filterList, useRegex))
|
||||
if (matchesFilter(name))
|
||||
result.filteredNames.append(name);
|
||||
}
|
||||
} else {
|
||||
// Encountered a #define
|
||||
const QString name = match.captured("defineName");
|
||||
result.expressions.insert(name, match.captured("defineValue"));
|
||||
if (defineNameMatchesFilter(name, filterList, useRegex))
|
||||
if (matchesFilter(name))
|
||||
result.filteredNames.append(name);
|
||||
}
|
||||
}
|
||||
@@ -580,7 +596,7 @@ bool ParseUtil::gameStringToBool(QString gameString, bool * ok) {
|
||||
QMap<QString, QHash<QString, QString>> ParseUtil::readCStructs(const QString &filename, const QString &label, const QHash<int, QString> memberMap) {
|
||||
QString filePath = this->root + "/" + filename;
|
||||
auto cParser = fex::Parser();
|
||||
auto tokens = fex::Lexer().LexFile(filePath.toStdString());
|
||||
auto tokens = fex::Lexer().LexFile(filePath);
|
||||
auto structs = cParser.ParseTopLevelObjects(tokens);
|
||||
QMap<QString, QHash<QString, QString>> structMaps;
|
||||
for (auto it = structs.begin(); it != structs.end(); it++) {
|
||||
|
||||
@@ -19,8 +19,7 @@ using std::make_shared;
|
||||
|
||||
RegionMap::RegionMap(Project *project) :
|
||||
section_prefix(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix)),
|
||||
default_map_section(section_prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_empty)),
|
||||
count_map_section(section_prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_count))
|
||||
default_map_section(project->getEmptyMapsecName())
|
||||
{
|
||||
this->project = project;
|
||||
}
|
||||
@@ -157,7 +156,7 @@ bool RegionMap::loadLayout(poryjson::Json layoutJson) {
|
||||
for (int x = 0; x < this->layout_width; x++) {
|
||||
int bin_index = x + y * this->layout_width;
|
||||
uint8_t square_section_id = mapBinData.at(bin_index);
|
||||
QString square_section_name = project->mapSectionValueToName.value(square_section_id);
|
||||
QString square_section_name = project->mapSectionIdNames.value(square_section_id, this->default_map_section);
|
||||
|
||||
LayoutSquare square;
|
||||
square.map_section = square_section_name;
|
||||
@@ -401,7 +400,7 @@ void RegionMap::saveLayout() {
|
||||
for (int m = 0; m < this->layout_height; m++) {
|
||||
for (int n = 0; n < this->layout_width; n++) {
|
||||
int i = n + this->layout_width * m;
|
||||
data.append(this->project->mapSectionNameToValue.value(this->layouts["main"][i].map_section));
|
||||
data.append(this->project->mapSectionIdNames.indexOf(this->layouts["main"][i].map_section));
|
||||
}
|
||||
}
|
||||
QFile bfile(fullPath(this->layout_path));
|
||||
@@ -760,18 +759,15 @@ bool RegionMap::squareInLayout(int x, int y) {
|
||||
}
|
||||
|
||||
MapSectionEntry RegionMap::getEntry(QString section) {
|
||||
if (this->region_map_entries->contains(section))
|
||||
return this->region_map_entries->operator[](section);
|
||||
else
|
||||
return MapSectionEntry();
|
||||
return this->region_map_entries->value(section, MapSectionEntry());
|
||||
}
|
||||
|
||||
void RegionMap::setEntry(QString section, MapSectionEntry entry) {
|
||||
this->region_map_entries->operator[](section) = entry;
|
||||
this->region_map_entries->insert(section, entry);
|
||||
}
|
||||
|
||||
void RegionMap::removeEntry(QString section) {
|
||||
this->region_map_entries->erase(section);
|
||||
this->region_map_entries->remove(section);
|
||||
}
|
||||
|
||||
QString RegionMap::palPath() {
|
||||
@@ -788,27 +784,6 @@ int RegionMap::getMapSquareIndex(int x, int y) {
|
||||
return ((index < tilemap.length()) && (index >= 0)) ? index : 0;
|
||||
}
|
||||
|
||||
// For turning a MAPSEC_NAME into a unique identifier sMapName-style variable.
|
||||
// CAPS_WITH_UNDERSCORE to CamelCase
|
||||
QString RegionMap::fixCase(QString caps) {
|
||||
bool big = true;
|
||||
QString camel;
|
||||
|
||||
static const QRegularExpression re_braced("({.*})");
|
||||
for (auto ch : caps.remove(re_braced).remove(this->section_prefix)) {
|
||||
if (ch == '_' || ch == ' ') {
|
||||
big = true;
|
||||
continue;
|
||||
}
|
||||
if (big) {
|
||||
camel += ch.toUpper();
|
||||
big = false;
|
||||
}
|
||||
else camel += ch.toLower();
|
||||
}
|
||||
return camel;
|
||||
}
|
||||
|
||||
QString RegionMap::fullPath(QString local) {
|
||||
return this->project->root + "/" + local;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ bool EditLayout::mergeWith(const QUndoCommand *command) {
|
||||
|
||||
///
|
||||
|
||||
ResizeLayout::ResizeLayout(RegionMap *map, int oldWidth, int oldHeight, int newWidth, int newHeight,
|
||||
ResizeRMLayout::ResizeRMLayout(RegionMap *map, int oldWidth, int oldHeight, int newWidth, int newHeight,
|
||||
QMap<QString, QList<LayoutSquare>> oldLayouts, QMap<QString, QList<LayoutSquare>> newLayouts, QUndoCommand *parent)
|
||||
: QUndoCommand(parent) {
|
||||
setText("Change Layout Dimensions");
|
||||
@@ -104,7 +104,7 @@ ResizeLayout::ResizeLayout(RegionMap *map, int oldWidth, int oldHeight, int newW
|
||||
this->newLayouts = newLayouts;
|
||||
}
|
||||
|
||||
void ResizeLayout::redo() {
|
||||
void ResizeRMLayout::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
@@ -113,7 +113,7 @@ void ResizeLayout::redo() {
|
||||
map->setAllLayouts(this->newLayouts);
|
||||
}
|
||||
|
||||
void ResizeLayout::undo() {
|
||||
void ResizeRMLayout::undo() {
|
||||
if (!map) return;
|
||||
|
||||
map->setLayoutDimensions(oldWidth, oldHeight, false);
|
||||
@@ -122,8 +122,8 @@ void ResizeLayout::undo() {
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
|
||||
bool ResizeLayout::mergeWith(const QUndoCommand *command) {
|
||||
const ResizeLayout *other = static_cast<const ResizeLayout *>(command);
|
||||
bool ResizeRMLayout::mergeWith(const QUndoCommand *command) {
|
||||
const ResizeRMLayout *other = static_cast<const ResizeRMLayout *>(command);
|
||||
|
||||
if (this->map != other->map)
|
||||
return false;
|
||||
@@ -260,7 +260,7 @@ void ResizeTilemap::undo() {
|
||||
|
||||
///
|
||||
|
||||
ClearEntries::ClearEntries(RegionMap *map, tsl::ordered_map<QString, MapSectionEntry> entries, QUndoCommand *parent)
|
||||
ClearEntries::ClearEntries(RegionMap *map, QMap<QString, MapSectionEntry> entries, QUndoCommand *parent)
|
||||
: QUndoCommand(parent) {
|
||||
setText("Clear Entries");
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ Tileset::Tileset(const Tileset &other)
|
||||
tiles.append(tile.copy());
|
||||
}
|
||||
|
||||
for (auto *metatile : other.metatiles) {
|
||||
metatiles.append(new Metatile(*metatile));
|
||||
for (auto *metatile : other.m_metatiles) {
|
||||
m_metatiles.append(new Metatile(*metatile));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,14 +55,42 @@ Tileset &Tileset::operator=(const Tileset &other) {
|
||||
tiles.append(tile.copy());
|
||||
}
|
||||
|
||||
metatiles.clear();
|
||||
for (auto *metatile : other.metatiles) {
|
||||
metatiles.append(new Metatile(*metatile));
|
||||
clearMetatiles();
|
||||
for (auto *metatile : other.m_metatiles) {
|
||||
m_metatiles.append(new Metatile(*metatile));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Tileset::~Tileset() {
|
||||
clearMetatiles();
|
||||
}
|
||||
|
||||
void Tileset::clearMetatiles() {
|
||||
qDeleteAll(m_metatiles);
|
||||
m_metatiles.clear();
|
||||
}
|
||||
|
||||
void Tileset::setMetatiles(const QList<Metatile*> &metatiles) {
|
||||
clearMetatiles();
|
||||
m_metatiles = metatiles;
|
||||
}
|
||||
|
||||
void Tileset::addMetatile(Metatile* metatile) {
|
||||
m_metatiles.append(metatile);
|
||||
}
|
||||
|
||||
void Tileset::resizeMetatiles(unsigned int newNumMetatiles) {
|
||||
while (m_metatiles.length() > newNumMetatiles) {
|
||||
delete m_metatiles.takeLast();
|
||||
}
|
||||
const int numTiles = projectConfig.getNumTilesInMetatile();
|
||||
while (m_metatiles.length() < newNumMetatiles) {
|
||||
m_metatiles.append(new Metatile(numTiles));
|
||||
}
|
||||
}
|
||||
|
||||
Tileset* Tileset::getTileTileset(int tileId, Tileset *primaryTileset, Tileset *secondaryTileset) {
|
||||
if (tileId < Project::getNumTilesPrimary()) {
|
||||
return primaryTileset;
|
||||
@@ -89,7 +117,7 @@ Metatile* Tileset::getMetatile(int metatileId, Tileset *primaryTileset, Tileset
|
||||
return nullptr;
|
||||
}
|
||||
int index = Metatile::getIndexInTileset(metatileId);
|
||||
return tileset->metatiles.value(index, nullptr);
|
||||
return tileset->m_metatiles.value(index, nullptr);
|
||||
}
|
||||
|
||||
// Metatile labels are stored per-tileset. When looking for a metatile label, first search in the tileset
|
||||
@@ -178,10 +206,10 @@ bool Tileset::metatileIsValid(uint16_t metatileId, Tileset *primaryTileset, Tile
|
||||
if (metatileId >= Project::getNumMetatilesTotal())
|
||||
return false;
|
||||
|
||||
if (metatileId < Project::getNumMetatilesPrimary() && metatileId >= primaryTileset->metatiles.length())
|
||||
if (metatileId < Project::getNumMetatilesPrimary() && metatileId >= primaryTileset->numMetatiles())
|
||||
return false;
|
||||
|
||||
if (metatileId >= Project::getNumMetatilesPrimary() + secondaryTileset->metatiles.length())
|
||||
if (metatileId >= Project::getNumMetatilesPrimary() + secondaryTileset->numMetatiles())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
571
src/editor.cpp
@@ -4,7 +4,7 @@
|
||||
#include "log.h"
|
||||
#include "connectionslistitem.h"
|
||||
#include "currentselectedmetatilespixmapitem.h"
|
||||
#include "mapsceneeventfilter.h"
|
||||
#include "eventfilters.h"
|
||||
#include "metatile.h"
|
||||
#include "montabwidget.h"
|
||||
#include "editcommands.h"
|
||||
@@ -47,6 +47,10 @@ Editor::Editor(Ui::MainWindow* ui)
|
||||
connect(ui->stackedWidget_WildMons, &QStackedWidget::currentChanged, [this] {
|
||||
emit wildMonTableOpened(getCurrentWildMonTable());
|
||||
});
|
||||
|
||||
connect(ui->toolButton_Open_Scripts, &QToolButton::pressed, this, &Editor::openMapScripts);
|
||||
connect(ui->actionOpen_Project_in_Text_Editor, &QAction::triggered, this, &Editor::openProjectInTextEditor);
|
||||
connect(ui->checkBox_ToggleGrid, &QCheckBox::toggled, this, &Editor::toggleGrid);
|
||||
}
|
||||
|
||||
Editor::~Editor()
|
||||
@@ -71,10 +75,14 @@ void Editor::saveProject() {
|
||||
}
|
||||
|
||||
void Editor::save() {
|
||||
if (project && map) {
|
||||
if (this->project && this->map) {
|
||||
saveUiFields();
|
||||
project->saveMap(map);
|
||||
project->saveAllDataStructures();
|
||||
this->project->saveMap(this->map);
|
||||
this->project->saveAllDataStructures();
|
||||
}
|
||||
else if (this->project && this->layout) {
|
||||
this->project->saveLayout(this->layout);
|
||||
this->project->saveAllDataStructures();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,66 +106,103 @@ void Editor::closeProject() {
|
||||
delete this->project;
|
||||
}
|
||||
|
||||
void Editor::setEditingMap() {
|
||||
current_view = map_item;
|
||||
if (map_item) {
|
||||
map_item->paintingMode = MapPixmapItem::PaintMode::Metatiles;
|
||||
map_item->draw();
|
||||
map_item->setVisible(true);
|
||||
}
|
||||
if (collision_item) {
|
||||
collision_item->setVisible(false);
|
||||
}
|
||||
if (events_group) {
|
||||
events_group->setVisible(false);
|
||||
bool Editor::getEditingLayout() {
|
||||
return this->editMode == EditMode::Metatiles || this->editMode == EditMode::Collision;
|
||||
}
|
||||
|
||||
void Editor::setEditorView() {
|
||||
// based on editMode
|
||||
if (!map_item || !collision_item) return;
|
||||
if (!this->layout) return;
|
||||
|
||||
map_item->setVisible(true); // is map item ever not visible
|
||||
collision_item->setVisible(false);
|
||||
|
||||
switch (this->editMode) {
|
||||
case EditMode::Metatiles:
|
||||
case EditMode::Connections:
|
||||
case EditMode::Events:
|
||||
current_view = map_item;
|
||||
break;
|
||||
case EditMode::Collision:
|
||||
current_view = collision_item;
|
||||
break;
|
||||
default:
|
||||
current_view = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
map_item->draw();
|
||||
collision_item->draw();
|
||||
|
||||
current_view->setVisible(true);
|
||||
|
||||
updateBorderVisibility();
|
||||
this->cursorMapTileRect->stopSingleTileMode();
|
||||
this->cursorMapTileRect->setSingleTileMode();
|
||||
this->cursorMapTileRect->setActive(true);
|
||||
|
||||
setMapEditingButtonsEnabled(true);
|
||||
switch (this->editMode) {
|
||||
case EditMode::Metatiles:
|
||||
case EditMode::Collision:
|
||||
map_item->setEditsEnabled(true);
|
||||
this->editGroup.setActiveStack(&this->layout->editHistory);
|
||||
break;
|
||||
case EditMode::Connections:
|
||||
this->cursorMapTileRect->setActive(false);
|
||||
map_item->setEditsEnabled(false);
|
||||
case EditMode::Events:
|
||||
if (this->map) {
|
||||
this->editGroup.setActiveStack(&this->map->editHistory);
|
||||
}
|
||||
break;
|
||||
case EditMode::Header:
|
||||
case EditMode::Encounters:
|
||||
default:
|
||||
this->editGroup.setActiveStack(nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this->events_group) {
|
||||
this->events_group->setVisible(this->editMode == EditMode::Events);
|
||||
}
|
||||
setMapEditingButtonsEnabled(this->editMode != EditMode::Events);
|
||||
}
|
||||
|
||||
void Editor::setEditingMetatiles() {
|
||||
this->editMode = EditMode::Metatiles;
|
||||
|
||||
setEditorView();
|
||||
}
|
||||
|
||||
void Editor::setEditingCollision() {
|
||||
current_view = collision_item;
|
||||
if (collision_item) {
|
||||
collision_item->draw();
|
||||
collision_item->setVisible(true);
|
||||
}
|
||||
if (map_item) {
|
||||
map_item->paintingMode = MapPixmapItem::PaintMode::Metatiles;
|
||||
map_item->draw();
|
||||
map_item->setVisible(true);
|
||||
}
|
||||
if (events_group) {
|
||||
events_group->setVisible(false);
|
||||
}
|
||||
updateBorderVisibility();
|
||||
this->cursorMapTileRect->setSingleTileMode();
|
||||
this->cursorMapTileRect->setActive(true);
|
||||
this->editMode = EditMode::Collision;
|
||||
|
||||
setMapEditingButtonsEnabled(true);
|
||||
setEditorView();
|
||||
}
|
||||
|
||||
void Editor::setEditingHeader() {
|
||||
this->editMode = EditMode::Header;
|
||||
|
||||
setEditorView();
|
||||
}
|
||||
|
||||
void Editor::setEditingObjects() {
|
||||
current_view = map_item;
|
||||
if (events_group) {
|
||||
events_group->setVisible(true);
|
||||
}
|
||||
if (map_item) {
|
||||
map_item->paintingMode = MapPixmapItem::PaintMode::EventObjects;
|
||||
map_item->draw();
|
||||
map_item->setVisible(true);
|
||||
}
|
||||
if (collision_item) {
|
||||
collision_item->setVisible(false);
|
||||
}
|
||||
updateBorderVisibility();
|
||||
this->cursorMapTileRect->setSingleTileMode();
|
||||
this->cursorMapTileRect->setActive(false);
|
||||
updateWarpEventWarnings();
|
||||
this->editMode = EditMode::Events;
|
||||
|
||||
setMapEditingButtonsEnabled(false);
|
||||
setEditorView();
|
||||
updateWarpEventWarnings();
|
||||
}
|
||||
|
||||
void Editor::setEditingConnections() {
|
||||
this->editMode = EditMode::Connections;
|
||||
|
||||
setEditorView();
|
||||
}
|
||||
|
||||
void Editor::setEditingEncounters() {
|
||||
this->editMode = EditMode::Encounters;
|
||||
|
||||
setEditorView();
|
||||
}
|
||||
|
||||
void Editor::setMapEditingButtonsEnabled(bool enabled) {
|
||||
@@ -166,7 +211,7 @@ void Editor::setMapEditingButtonsEnabled(bool enabled) {
|
||||
this->ui->pushButton_ChangeDimensions->setEnabled(enabled);
|
||||
// If the fill button is pressed, unpress it and select the pointer.
|
||||
if (!enabled && (this->ui->toolButton_Fill->isChecked() || this->ui->toolButton_Dropper->isChecked())) {
|
||||
this->map_edit_mode = "select";
|
||||
this->mapEditAction = EditAction::Select;
|
||||
this->settings->mapCursor = QCursor();
|
||||
this->cursorMapTileRect->setSingleTileMode();
|
||||
this->ui->toolButton_Fill->setChecked(false);
|
||||
@@ -176,24 +221,6 @@ void Editor::setMapEditingButtonsEnabled(bool enabled) {
|
||||
this->ui->checkBox_smartPaths->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void Editor::setEditingConnections() {
|
||||
current_view = map_item;
|
||||
if (map_item) {
|
||||
map_item->paintingMode = MapPixmapItem::PaintMode::Disabled;
|
||||
map_item->draw();
|
||||
map_item->setVisible(true);
|
||||
}
|
||||
if (collision_item) {
|
||||
collision_item->setVisible(false);
|
||||
}
|
||||
if (events_group) {
|
||||
events_group->setVisible(false);
|
||||
}
|
||||
updateBorderVisibility();
|
||||
this->cursorMapTileRect->setSingleTileMode();
|
||||
this->cursorMapTileRect->setActive(false);
|
||||
}
|
||||
|
||||
void Editor::clearWildMonTables() {
|
||||
QStackedWidget *stack = ui->stackedWidget_WildMons;
|
||||
const QSignalBlocker blocker(stack);
|
||||
@@ -784,6 +811,9 @@ void Editor::displayConnection(MapConnection *connection) {
|
||||
connect(listItem, &ConnectionsListItem::openMapClicked, this, &Editor::openConnectedMap);
|
||||
connect(pixmapItem, &ConnectionPixmapItem::connectionItemDoubleClicked, this, &Editor::openConnectedMap);
|
||||
|
||||
// Pressing the delete key on a selected connection's pixmap deletes it
|
||||
connect(pixmapItem, &ConnectionPixmapItem::deleteRequested, this, &Editor::removeConnection);
|
||||
|
||||
// Sync the selection highlight between the list UI and the pixmap
|
||||
connect(pixmapItem, &ConnectionPixmapItem::selectionChanged, [=](bool selected) {
|
||||
listItem->setSelected(selected);
|
||||
@@ -842,11 +872,6 @@ void Editor::removeConnection(MapConnection *connection) {
|
||||
this->map->editHistory.push(new MapConnectionRemove(this->map, connection));
|
||||
}
|
||||
|
||||
void Editor::removeSelectedConnection() {
|
||||
if (selected_connection_item)
|
||||
removeConnection(selected_connection_item->connection);
|
||||
}
|
||||
|
||||
void Editor::removeConnectionPixmap(MapConnection *connection) {
|
||||
if (!connection)
|
||||
return;
|
||||
@@ -1055,8 +1080,8 @@ void Editor::onHoveredMovementPermissionCleared() {
|
||||
}
|
||||
|
||||
QString Editor::getMetatileDisplayMessage(uint16_t metatileId) {
|
||||
Metatile *metatile = Tileset::getMetatile(metatileId, map->layout->tileset_primary, map->layout->tileset_secondary);
|
||||
QString label = Tileset::getMetatileLabel(metatileId, map->layout->tileset_primary, map->layout->tileset_secondary);
|
||||
Metatile *metatile = Tileset::getMetatile(metatileId, this->layout->tileset_primary, this->layout->tileset_secondary);
|
||||
QString label = Tileset::getMetatileLabel(metatileId, this->layout->tileset_primary, this->layout->tileset_secondary);
|
||||
QString message = QString("Metatile: %1").arg(Metatile::getMetatileIdString(metatileId));
|
||||
if (label.size())
|
||||
message += QString(" \"%1\"").arg(label);
|
||||
@@ -1142,46 +1167,46 @@ void Editor::setCursorRectVisible(bool visible) {
|
||||
void Editor::onHoveredMapMetatileChanged(const QPoint &pos) {
|
||||
int x = pos.x();
|
||||
int y = pos.y();
|
||||
if (!map->isWithinBounds(x, y))
|
||||
if (!layout->isWithinBounds(x, y))
|
||||
return;
|
||||
|
||||
this->updateCursorRectPos(x, y);
|
||||
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles) {
|
||||
int blockIndex = y * map->getWidth() + x;
|
||||
int metatileId = map->layout->blockdata.at(blockIndex).metatileId();
|
||||
if (this->getEditingLayout()) {
|
||||
int blockIndex = y * layout->getWidth() + x;
|
||||
int metatileId = layout->blockdata.at(blockIndex).metatileId();
|
||||
this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3, Scale = %4x")
|
||||
.arg(x)
|
||||
.arg(y)
|
||||
.arg(getMetatileDisplayMessage(metatileId))
|
||||
.arg(QString::number(zoomLevels[this->scaleIndex], 'g', 2)));
|
||||
}
|
||||
else if (map_item->paintingMode == MapPixmapItem::PaintMode::EventObjects) {
|
||||
else if (this->editMode == EditMode::Events) {
|
||||
this->ui->statusBar->showMessage(QString("X: %1, Y: %2, Scale = %3x")
|
||||
.arg(x)
|
||||
.arg(y)
|
||||
.arg(QString::number(zoomLevels[this->scaleIndex], 'g', 2)));
|
||||
}
|
||||
|
||||
Scripting::cb_BlockHoverChanged(x, y);
|
||||
}
|
||||
|
||||
void Editor::onHoveredMapMetatileCleared() {
|
||||
this->setCursorRectVisible(false);
|
||||
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles
|
||||
|| map_item->paintingMode == MapPixmapItem::PaintMode::EventObjects) {
|
||||
if (!map_item->getEditsEnabled()) {
|
||||
this->ui->statusBar->clearMessage();
|
||||
}
|
||||
Scripting::cb_BlockHoverCleared();
|
||||
}
|
||||
|
||||
void Editor::onHoveredMapMovementPermissionChanged(int x, int y) {
|
||||
if (!map->isWithinBounds(x, y))
|
||||
if (!layout->isWithinBounds(x, y))
|
||||
return;
|
||||
|
||||
this->updateCursorRectPos(x, y);
|
||||
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles) {
|
||||
int blockIndex = y * map->getWidth() + x;
|
||||
uint16_t collision = map->layout->blockdata.at(blockIndex).collision();
|
||||
uint16_t elevation = map->layout->blockdata.at(blockIndex).elevation();
|
||||
if (this->getEditingLayout()) {
|
||||
int blockIndex = y * layout->getWidth() + x;
|
||||
uint16_t collision = layout->blockdata.at(blockIndex).collision();
|
||||
uint16_t elevation = layout->blockdata.at(blockIndex).elevation();
|
||||
QString message = QString("X: %1, Y: %2, %3")
|
||||
.arg(x)
|
||||
.arg(y)
|
||||
@@ -1193,7 +1218,7 @@ void Editor::onHoveredMapMovementPermissionChanged(int x, int y) {
|
||||
|
||||
void Editor::onHoveredMapMovementPermissionCleared() {
|
||||
this->setCursorRectVisible(false);
|
||||
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles) {
|
||||
if (this->getEditingLayout()) {
|
||||
this->ui->statusBar->clearMessage();
|
||||
}
|
||||
Scripting::cb_BlockHoverCleared();
|
||||
@@ -1215,11 +1240,7 @@ QString Editor::getMovementPermissionText(uint16_t collision, uint16_t elevation
|
||||
return message;
|
||||
}
|
||||
|
||||
bool Editor::setMap(QString map_name) {
|
||||
if (map_name.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Editor::unsetMap() {
|
||||
// disconnect previous map's signals so they are not firing
|
||||
// multiple times if set again in the future
|
||||
if (map) {
|
||||
@@ -1228,47 +1249,90 @@ bool Editor::setMap(QString map_name) {
|
||||
for (auto connection : map->getConnections())
|
||||
disconnectMapConnection(connection);
|
||||
}
|
||||
clearMapConnections();
|
||||
|
||||
if (project) {
|
||||
Map *loadedMap = project->loadMap(map_name);
|
||||
if (!loadedMap) {
|
||||
return false;
|
||||
}
|
||||
this->map = nullptr;
|
||||
}
|
||||
|
||||
map = loadedMap;
|
||||
|
||||
editGroup.addStack(&map->editHistory);
|
||||
editGroup.setActiveStack(&map->editHistory);
|
||||
selected_events->clear();
|
||||
if (!displayMap()) {
|
||||
return false;
|
||||
}
|
||||
map_ruler->setMapDimensions(QSize(map->getWidth(), map->getHeight()));
|
||||
connect(map, &Map::mapDimensionsChanged, map_ruler, &MapRuler::setMapDimensions);
|
||||
connect(map, &Map::openScriptRequested, this, &Editor::openScript);
|
||||
connect(map, &Map::connectionAdded, this, &Editor::displayConnection);
|
||||
connect(map, &Map::connectionRemoved, this, &Editor::removeConnectionPixmap);
|
||||
updateSelectedEvents();
|
||||
bool Editor::setMap(QString map_name) {
|
||||
if (!project || map_name.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsetMap();
|
||||
|
||||
Map *loadedMap = project->loadMap(map_name);
|
||||
if (!loadedMap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->map = loadedMap;
|
||||
|
||||
setLayout(map->layout->id);
|
||||
|
||||
editGroup.addStack(&map->editHistory);
|
||||
editGroup.setActiveStack(&map->editHistory);
|
||||
|
||||
selected_events->clear();
|
||||
if (!displayMap()) {
|
||||
return false;
|
||||
}
|
||||
displayWildMonTables();
|
||||
|
||||
connect(map, &Map::openScriptRequested, this, &Editor::openScript);
|
||||
connect(map, &Map::connectionAdded, this, &Editor::displayConnection);
|
||||
connect(map, &Map::connectionRemoved, this, &Editor::removeConnectionPixmap);
|
||||
updateSelectedEvents();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Editor::onMapStartPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item) {
|
||||
if (item->paintingMode != MapPixmapItem::PaintMode::Metatiles) {
|
||||
bool Editor::setLayout(QString layoutId) {
|
||||
if (!project || layoutId.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->layout = this->project->loadLayout(layoutId);
|
||||
|
||||
if (!displayLayout()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
editGroup.addStack(&layout->editHistory);
|
||||
|
||||
map_ruler->setMapDimensions(QSize(this->layout->getWidth(), this->layout->getHeight()));
|
||||
connect(this->layout, &Layout::layoutDimensionsChanged, map_ruler, &MapRuler::setMapDimensions);
|
||||
|
||||
ui->comboBox_PrimaryTileset->blockSignals(true);
|
||||
ui->comboBox_SecondaryTileset->blockSignals(true);
|
||||
ui->comboBox_PrimaryTileset->setCurrentText(this->layout->tileset_primary_label);
|
||||
ui->comboBox_SecondaryTileset->setCurrentText(this->layout->tileset_secondary_label);
|
||||
ui->comboBox_PrimaryTileset->blockSignals(false);
|
||||
ui->comboBox_SecondaryTileset->blockSignals(false);
|
||||
|
||||
const QSignalBlocker b0(this->ui->comboBox_LayoutSelector);
|
||||
int index = this->ui->comboBox_LayoutSelector->findText(layoutId);
|
||||
if (index < 0) index = 0;
|
||||
this->ui->comboBox_LayoutSelector->setCurrentIndex(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Editor::onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *) {
|
||||
if (!this->getEditingLayout()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
|
||||
if (event->buttons() & Qt::RightButton && (map_edit_mode == "paint" || map_edit_mode == "fill")) {
|
||||
if (event->buttons() & Qt::RightButton && (mapEditAction == EditAction::Paint || mapEditAction == EditAction::Fill)) {
|
||||
this->cursorMapTileRect->initRightClickSelectionAnchor(pos.x(), pos.y());
|
||||
} else {
|
||||
this->cursorMapTileRect->initAnchor(pos.x(), pos.y());
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::onMapEndPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *item) {
|
||||
if (!(item->paintingMode == MapPixmapItem::PaintMode::Metatiles)) {
|
||||
void Editor::onMapEndPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *) {
|
||||
if (!this->getEditingLayout()) {
|
||||
return;
|
||||
}
|
||||
this->cursorMapTileRect->stopRightClickSelectionAnchor();
|
||||
@@ -1301,16 +1365,16 @@ void Editor::setStraightPathCursorMode(QGraphicsSceneMouseEvent *event) {
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item) {
|
||||
void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item) {
|
||||
// TODO: add event tab object painting tool buttons stuff here
|
||||
if (item->paintingMode == MapPixmapItem::PaintMode::Disabled) {
|
||||
if (!item->getEditsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
|
||||
|
||||
if (item->paintingMode == MapPixmapItem::PaintMode::Metatiles) {
|
||||
if (map_edit_mode == "paint") {
|
||||
if (this->getEditingLayout()) {
|
||||
if (mapEditAction == EditAction::Paint) {
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
item->updateMetatileSelection(event);
|
||||
} else if (event->buttons() & Qt::MiddleButton) {
|
||||
@@ -1332,9 +1396,9 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
|
||||
}
|
||||
item->paint(event);
|
||||
}
|
||||
} else if (map_edit_mode == "select") {
|
||||
} else if (mapEditAction == EditAction::Select) {
|
||||
item->select(event);
|
||||
} else if (map_edit_mode == "fill") {
|
||||
} else if (mapEditAction == EditAction::Fill) {
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
item->updateMetatileSelection(event);
|
||||
} else if (event->modifiers() & Qt::ControlModifier) {
|
||||
@@ -1342,13 +1406,13 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
|
||||
} else {
|
||||
item->floodFill(event);
|
||||
}
|
||||
} else if (map_edit_mode == "pick") {
|
||||
} else if (mapEditAction == EditAction::Pick) {
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
item->updateMetatileSelection(event);
|
||||
} else {
|
||||
item->pick(event);
|
||||
}
|
||||
} else if (map_edit_mode == "shift") {
|
||||
} else if (mapEditAction == EditAction::Shift) {
|
||||
this->setStraightPathCursorMode(event);
|
||||
if (this->cursorMapTileRect->getStraightPathMode()) {
|
||||
item->lockNondominantAxis(event);
|
||||
@@ -1356,11 +1420,11 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
|
||||
}
|
||||
item->shift(event);
|
||||
}
|
||||
} else if (item->paintingMode == MapPixmapItem::PaintMode::EventObjects) {
|
||||
if (obj_edit_mode == "paint" && event->type() == QEvent::GraphicsSceneMousePress) {
|
||||
} else if (this->editMode == EditMode::Events) {
|
||||
if (objectEditAction == EditAction::Paint && event->type() == QEvent::GraphicsSceneMousePress) {
|
||||
// Right-clicking while in paint mode will change mode to select.
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
this->obj_edit_mode = "select";
|
||||
this->objectEditAction = EditAction::Select;
|
||||
this->settings->mapCursor = QCursor();
|
||||
this->cursorMapTileRect->setSingleTileMode();
|
||||
this->ui->toolButton_Paint->setChecked(false);
|
||||
@@ -1382,9 +1446,9 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (obj_edit_mode == "select") {
|
||||
} else if (objectEditAction == EditAction::Select) {
|
||||
// do nothing here, at least for now
|
||||
} else if (obj_edit_mode == "shift" && item->map) {
|
||||
} else if (objectEditAction == EditAction::Shift) {
|
||||
static QPoint selection_origin;
|
||||
static unsigned actionId = 0;
|
||||
|
||||
@@ -1400,8 +1464,8 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
|
||||
|
||||
QList<Event *> selectedEvents;
|
||||
|
||||
for (DraggablePixmapItem *item : getObjects()) {
|
||||
selectedEvents.append(item->event);
|
||||
for (DraggablePixmapItem *pixmapItem : getObjects()) {
|
||||
selectedEvents.append(pixmapItem->event);
|
||||
}
|
||||
selection_origin = QPoint(pos.x(), pos.y());
|
||||
|
||||
@@ -1414,13 +1478,13 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
|
||||
}
|
||||
|
||||
void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item) {
|
||||
if (item->paintingMode != MapPixmapItem::PaintMode::Metatiles) {
|
||||
if (!item->getEditsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
|
||||
|
||||
if (map_edit_mode == "paint") {
|
||||
if (mapEditAction == EditAction::Paint) {
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
item->updateMovementPermissionSelection(event);
|
||||
} else if (event->buttons() & Qt::MiddleButton) {
|
||||
@@ -1437,9 +1501,9 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm
|
||||
}
|
||||
item->paint(event);
|
||||
}
|
||||
} else if (map_edit_mode == "select") {
|
||||
} else if (mapEditAction == EditAction::Select) {
|
||||
item->select(event);
|
||||
} else if (map_edit_mode == "fill") {
|
||||
} else if (mapEditAction == EditAction::Fill) {
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
item->pick(event);
|
||||
} else if (event->modifiers() & Qt::ControlModifier) {
|
||||
@@ -1447,9 +1511,9 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm
|
||||
} else {
|
||||
item->floodFill(event);
|
||||
}
|
||||
} else if (map_edit_mode == "pick") {
|
||||
} else if (mapEditAction == EditAction::Pick) {
|
||||
item->pick(event);
|
||||
} else if (map_edit_mode == "shift") {
|
||||
} else if (mapEditAction == EditAction::Shift) {
|
||||
this->setStraightPathCursorMode(event);
|
||||
if (this->cursorMapTileRect->getStraightPathMode()) {
|
||||
item->lockNondominantAxis(event);
|
||||
@@ -1486,26 +1550,40 @@ void Editor::clearMap() {
|
||||
}
|
||||
|
||||
bool Editor::displayMap() {
|
||||
if (!this->map)
|
||||
return false;
|
||||
|
||||
displayMapEvents();
|
||||
displayMapConnections();
|
||||
maskNonVisibleConnectionTiles();
|
||||
|
||||
if (events_group) {
|
||||
events_group->setVisible(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Editor::displayLayout() {
|
||||
if (!this->layout)
|
||||
return false;
|
||||
|
||||
if (!scene) {
|
||||
scene = new QGraphicsScene;
|
||||
MapSceneEventFilter *filter = new MapSceneEventFilter();
|
||||
MapSceneEventFilter *filter = new MapSceneEventFilter(scene);
|
||||
scene->installEventFilter(filter);
|
||||
connect(filter, &MapSceneEventFilter::wheelZoom, this, &Editor::onWheelZoom);
|
||||
scene->installEventFilter(this->map_ruler);
|
||||
}
|
||||
|
||||
clearConnectionMask();
|
||||
displayMetatileSelector();
|
||||
displayMovementPermissionSelector();
|
||||
displayMapMetatiles();
|
||||
displayMovementPermissionSelector();
|
||||
displayMapMovementPermissions();
|
||||
displayBorderMetatiles();
|
||||
displayCurrentMetatilesSelection();
|
||||
displayMapEvents();
|
||||
displayMapConnections();
|
||||
displayMapBorder();
|
||||
displayMapGrid();
|
||||
displayWildMonTables();
|
||||
maskNonVisibleConnectionTiles();
|
||||
|
||||
this->map_ruler->setZValue(1000);
|
||||
scene->addItem(this->map_ruler);
|
||||
@@ -1516,9 +1594,7 @@ bool Editor::displayMap() {
|
||||
if (collision_item) {
|
||||
collision_item->setVisible(false);
|
||||
}
|
||||
if (events_group) {
|
||||
events_group->setVisible(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1534,7 +1610,7 @@ void Editor::displayMetatileSelector() {
|
||||
|
||||
scene_metatiles = new QGraphicsScene;
|
||||
if (!metatile_selector_item) {
|
||||
metatile_selector_item = new MetatileSelector(8, map);
|
||||
metatile_selector_item = new MetatileSelector(8, this->layout);
|
||||
connect(metatile_selector_item, &MetatileSelector::hoveredMetatileSelectionChanged,
|
||||
this, &Editor::onHoveredMetatileSelectionChanged);
|
||||
connect(metatile_selector_item, &MetatileSelector::hoveredMetatileSelectionCleared,
|
||||
@@ -1543,14 +1619,14 @@ void Editor::displayMetatileSelector() {
|
||||
this, &Editor::onSelectedMetatilesChanged);
|
||||
metatile_selector_item->select(0);
|
||||
} else {
|
||||
metatile_selector_item->setMap(map);
|
||||
metatile_selector_item->setLayout(this->layout);
|
||||
if (metatile_selector_item->primaryTileset
|
||||
&& metatile_selector_item->primaryTileset != map->layout->tileset_primary)
|
||||
emit tilesetUpdated(map->layout->tileset_primary->name);
|
||||
&& metatile_selector_item->primaryTileset != this->layout->tileset_primary)
|
||||
emit tilesetUpdated(this->layout->tileset_primary->name);
|
||||
if (metatile_selector_item->secondaryTileset
|
||||
&& metatile_selector_item->secondaryTileset != map->layout->tileset_secondary)
|
||||
emit tilesetUpdated(map->layout->tileset_secondary->name);
|
||||
metatile_selector_item->setTilesets(map->layout->tileset_primary, map->layout->tileset_secondary);
|
||||
&& metatile_selector_item->secondaryTileset != this->layout->tileset_secondary)
|
||||
emit tilesetUpdated(this->layout->tileset_secondary->name);
|
||||
metatile_selector_item->setTilesets(this->layout->tileset_primary, this->layout->tileset_secondary);
|
||||
}
|
||||
|
||||
scene_metatiles->addItem(metatile_selector_item);
|
||||
@@ -1567,12 +1643,12 @@ void Editor::clearMapMetatiles() {
|
||||
void Editor::displayMapMetatiles() {
|
||||
clearMapMetatiles();
|
||||
|
||||
map_item = new MapPixmapItem(map, this->metatile_selector_item, this->settings);
|
||||
connect(map_item, &MapPixmapItem::mouseEvent, this, &Editor::mouseEvent_map);
|
||||
connect(map_item, &MapPixmapItem::startPaint, this, &Editor::onMapStartPaint);
|
||||
connect(map_item, &MapPixmapItem::endPaint, this, &Editor::onMapEndPaint);
|
||||
connect(map_item, &MapPixmapItem::hoveredMapMetatileChanged, this, &Editor::onHoveredMapMetatileChanged);
|
||||
connect(map_item, &MapPixmapItem::hoveredMapMetatileCleared, this, &Editor::onHoveredMapMetatileCleared);
|
||||
map_item = new LayoutPixmapItem(this->layout, this->metatile_selector_item, this->settings);
|
||||
connect(map_item, &LayoutPixmapItem::mouseEvent, this, &Editor::mouseEvent_map);
|
||||
connect(map_item, &LayoutPixmapItem::startPaint, this, &Editor::onMapStartPaint);
|
||||
connect(map_item, &LayoutPixmapItem::endPaint, this, &Editor::onMapEndPaint);
|
||||
connect(map_item, &LayoutPixmapItem::hoveredMapMetatileChanged, this, &Editor::onHoveredMapMetatileChanged);
|
||||
connect(map_item, &LayoutPixmapItem::hoveredMapMetatileCleared, this, &Editor::onHoveredMapMetatileCleared);
|
||||
|
||||
map_item->draw(true);
|
||||
scene->addItem(map_item);
|
||||
@@ -1597,7 +1673,7 @@ void Editor::clearMapMovementPermissions() {
|
||||
void Editor::displayMapMovementPermissions() {
|
||||
clearMapMovementPermissions();
|
||||
|
||||
collision_item = new CollisionPixmapItem(map, ui->spinBox_SelectedCollision, ui->spinBox_SelectedElevation,
|
||||
collision_item = new CollisionPixmapItem(this->layout, ui->spinBox_SelectedCollision, ui->spinBox_SelectedElevation,
|
||||
this->metatile_selector_item, this->settings, &this->collisionOpacity);
|
||||
connect(collision_item, &CollisionPixmapItem::mouseEvent, this, &Editor::mouseEvent_collision);
|
||||
connect(collision_item, &CollisionPixmapItem::hoveredMapMovementPermissionChanged,
|
||||
@@ -1621,7 +1697,7 @@ void Editor::displayBorderMetatiles() {
|
||||
clearBorderMetatiles();
|
||||
|
||||
scene_selected_border_metatiles = new QGraphicsScene;
|
||||
selected_border_metatiles_item = new BorderMetatilesPixmapItem(map, this->metatile_selector_item);
|
||||
selected_border_metatiles_item = new BorderMetatilesPixmapItem(this->layout, this->metatile_selector_item);
|
||||
selected_border_metatiles_item->draw();
|
||||
scene_selected_border_metatiles->addItem(selected_border_metatiles_item);
|
||||
|
||||
@@ -1646,14 +1722,14 @@ void Editor::displayCurrentMetatilesSelection() {
|
||||
clearCurrentMetatilesSelection();
|
||||
|
||||
scene_current_metatile_selection = new QGraphicsScene;
|
||||
current_metatile_selection_item = new CurrentSelectedMetatilesPixmapItem(map, this->metatile_selector_item);
|
||||
current_metatile_selection_item = new CurrentSelectedMetatilesPixmapItem(this->layout, this->metatile_selector_item);
|
||||
current_metatile_selection_item->draw();
|
||||
scene_current_metatile_selection->addItem(current_metatile_selection_item);
|
||||
}
|
||||
|
||||
void Editor::redrawCurrentMetatilesSelection() {
|
||||
if (current_metatile_selection_item) {
|
||||
current_metatile_selection_item->setMap(map);
|
||||
current_metatile_selection_item->setLayout(this->layout);
|
||||
current_metatile_selection_item->draw();
|
||||
emit currentMetatilesSelectionChanged();
|
||||
}
|
||||
@@ -1779,8 +1855,8 @@ void Editor::maskNonVisibleConnectionTiles() {
|
||||
mask.addRect(
|
||||
-BORDER_DISTANCE * 16,
|
||||
-BORDER_DISTANCE * 16,
|
||||
(map->getWidth() + BORDER_DISTANCE * 2) * 16,
|
||||
(map->getHeight() + BORDER_DISTANCE * 2) * 16
|
||||
(layout->getWidth() + BORDER_DISTANCE * 2) * 16,
|
||||
(layout->getHeight() + BORDER_DISTANCE * 2) * 16
|
||||
);
|
||||
|
||||
// Mask the tiles with the current theme's background color.
|
||||
@@ -1803,13 +1879,13 @@ void Editor::clearMapBorder() {
|
||||
void Editor::displayMapBorder() {
|
||||
clearMapBorder();
|
||||
|
||||
int borderWidth = map->getBorderWidth();
|
||||
int borderHeight = map->getBorderHeight();
|
||||
int borderWidth = this->layout->getBorderWidth();
|
||||
int borderHeight = this->layout->getBorderHeight();
|
||||
int borderHorzDist = getBorderDrawDistance(borderWidth);
|
||||
int borderVertDist = getBorderDrawDistance(borderHeight);
|
||||
QPixmap pixmap = map->renderBorder();
|
||||
for (int y = -borderVertDist; y < map->getHeight() + borderVertDist; y += borderHeight)
|
||||
for (int x = -borderHorzDist; x < map->getWidth() + borderHorzDist; x += borderWidth) {
|
||||
QPixmap pixmap = this->layout->renderBorder();
|
||||
for (int y = -borderVertDist; y < this->layout->getHeight() + borderVertDist; y += borderHeight)
|
||||
for (int x = -borderHorzDist; x < this->layout->getWidth() + borderHorzDist; x += borderWidth) {
|
||||
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
|
||||
item->setX(x * 16);
|
||||
item->setY(y * 16);
|
||||
@@ -1820,7 +1896,7 @@ void Editor::displayMapBorder() {
|
||||
}
|
||||
|
||||
void Editor::updateMapBorder() {
|
||||
QPixmap pixmap = this->map->renderBorder(true);
|
||||
QPixmap pixmap = this->layout->renderBorder(true);
|
||||
for (auto item : this->borderItems) {
|
||||
item->setPixmap(pixmap);
|
||||
}
|
||||
@@ -1842,59 +1918,88 @@ int Editor::getBorderDrawDistance(int dimension) {
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::onToggleGridClicked(bool checked) {
|
||||
void Editor::toggleGrid(bool checked) {
|
||||
if (porymapConfig.showGrid == checked)
|
||||
return;
|
||||
porymapConfig.showGrid = checked;
|
||||
|
||||
// Synchronize action and checkbox
|
||||
const QSignalBlocker b_Action(ui->actionShow_Grid);
|
||||
const QSignalBlocker b_Checkbox(ui->checkBox_ToggleGrid);
|
||||
ui->actionShow_Grid->setChecked(checked);
|
||||
ui->checkBox_ToggleGrid->setChecked(checked);
|
||||
|
||||
this->mapGrid->setVisible(checked);
|
||||
|
||||
if (ui->graphicsView_Map->scene())
|
||||
ui->graphicsView_Map->scene()->update();
|
||||
}
|
||||
|
||||
void Editor::clearMapGrid() {
|
||||
for (QGraphicsLineItem* item : gridLines) {
|
||||
if (item) delete item;
|
||||
}
|
||||
gridLines.clear();
|
||||
delete this->mapGrid;
|
||||
this->mapGrid = nullptr;
|
||||
}
|
||||
|
||||
void Editor::displayMapGrid() {
|
||||
clearMapGrid();
|
||||
ui->checkBox_ToggleGrid->disconnect();
|
||||
|
||||
int pixelWidth = map->getWidth() * 16;
|
||||
int pixelHeight = map->getHeight() * 16;
|
||||
for (int i = 0; i <= map->getWidth(); i++) {
|
||||
int x = i * 16;
|
||||
QGraphicsLineItem *line = new QGraphicsLineItem(x, 0, x, pixelHeight);
|
||||
line->setVisible(ui->checkBox_ToggleGrid->isChecked());
|
||||
gridLines.append(line);
|
||||
connect(ui->checkBox_ToggleGrid, &QCheckBox::toggled, [=](bool checked){line->setVisible(checked);});
|
||||
// Note: The grid lines are not added to the scene. They need to be drawn on top of the overlay
|
||||
// elements of the scripting API, so they're painted manually in MapView::drawForeground.
|
||||
this->mapGrid = new QGraphicsItemGroup();
|
||||
|
||||
const int pixelMapWidth = this->layout->getWidth() * 16;
|
||||
const int pixelMapHeight = this->layout->getHeight() * 16;
|
||||
|
||||
// The grid can be moved with a user-specified x/y offset. The grid's dash patterns will only wrap in full pattern increments,
|
||||
// so we draw an additional row/column outside the map that can be revealed as the offset changes.
|
||||
const int offsetX = (this->gridSettings.offsetX % this->gridSettings.width) - this->gridSettings.width;
|
||||
const int offsetY = (this->gridSettings.offsetY % this->gridSettings.height) - this->gridSettings.height;
|
||||
|
||||
QPen pen;
|
||||
pen.setColor(this->gridSettings.color);
|
||||
|
||||
// Create vertical lines
|
||||
pen.setDashPattern(this->gridSettings.getVerticalDashPattern());
|
||||
for (int i = offsetX; i <= pixelMapWidth; i += this->gridSettings.width) {
|
||||
auto line = new QGraphicsLineItem(i, offsetY, i, pixelMapHeight);
|
||||
line->setPen(pen);
|
||||
this->mapGrid->addToGroup(line);
|
||||
}
|
||||
for (int j = 0; j <= map->getHeight(); j++) {
|
||||
int y = j * 16;
|
||||
QGraphicsLineItem *line = new QGraphicsLineItem(0, y, pixelWidth, y);
|
||||
line->setVisible(ui->checkBox_ToggleGrid->isChecked());
|
||||
gridLines.append(line);
|
||||
connect(ui->checkBox_ToggleGrid, &QCheckBox::toggled, [=](bool checked){line->setVisible(checked);});
|
||||
|
||||
// Create horizontal lines
|
||||
pen.setDashPattern(this->gridSettings.getHorizontalDashPattern());
|
||||
for (int i = offsetY; i <= pixelMapHeight; i += this->gridSettings.height) {
|
||||
auto line = new QGraphicsLineItem(offsetX, i, pixelMapWidth, i);
|
||||
line->setPen(pen);
|
||||
this->mapGrid->addToGroup(line);
|
||||
}
|
||||
connect(ui->checkBox_ToggleGrid, &QCheckBox::toggled, this, &Editor::onToggleGridClicked);
|
||||
|
||||
this->mapGrid->setVisible(porymapConfig.showGrid);
|
||||
}
|
||||
|
||||
void Editor::updateMapGrid() {
|
||||
displayMapGrid();
|
||||
if (ui->graphicsView_Map->scene())
|
||||
ui->graphicsView_Map->scene()->update();
|
||||
}
|
||||
|
||||
void Editor::updatePrimaryTileset(QString tilesetLabel, bool forceLoad)
|
||||
{
|
||||
if (map->layout->tileset_primary_label != tilesetLabel || forceLoad)
|
||||
if (this->layout->tileset_primary_label != tilesetLabel || forceLoad)
|
||||
{
|
||||
map->layout->tileset_primary_label = tilesetLabel;
|
||||
map->layout->tileset_primary = project->getTileset(tilesetLabel, forceLoad);
|
||||
map->clearBorderCache();
|
||||
this->layout->tileset_primary_label = tilesetLabel;
|
||||
this->layout->tileset_primary = project->getTileset(tilesetLabel, forceLoad);
|
||||
layout->clearBorderCache();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::updateSecondaryTileset(QString tilesetLabel, bool forceLoad)
|
||||
{
|
||||
if (map->layout->tileset_secondary_label != tilesetLabel || forceLoad)
|
||||
if (this->layout->tileset_secondary_label != tilesetLabel || forceLoad)
|
||||
{
|
||||
map->layout->tileset_secondary_label = tilesetLabel;
|
||||
map->layout->tileset_secondary = project->getTileset(tilesetLabel, forceLoad);
|
||||
map->clearBorderCache();
|
||||
this->layout->tileset_secondary_label = tilesetLabel;
|
||||
this->layout->tileset_secondary = project->getTileset(tilesetLabel, forceLoad);
|
||||
layout->clearBorderCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1940,7 +2045,7 @@ void Editor::updateCustomMapHeaderValues(QTableWidget *table)
|
||||
|
||||
Tileset* Editor::getCurrentMapPrimaryTileset()
|
||||
{
|
||||
QString tilesetLabel = map->layout->tileset_primary_label;
|
||||
QString tilesetLabel = this->layout->tileset_primary_label;
|
||||
return project->getTileset(tilesetLabel);
|
||||
}
|
||||
|
||||
@@ -1975,12 +2080,12 @@ void Editor::redrawObject(DraggablePixmapItem *item) {
|
||||
void Editor::updateWarpEventWarning(Event *event) {
|
||||
if (porymapConfig.warpBehaviorWarningDisabled)
|
||||
return;
|
||||
if (!project || !map || !event || event->getEventType() != Event::Type::Warp)
|
||||
if (!project || !map || !map->layout || !event || event->getEventType() != Event::Type::Warp)
|
||||
return;
|
||||
Block block;
|
||||
Metatile * metatile = nullptr;
|
||||
WarpEvent * warpEvent = static_cast<WarpEvent*>(event);
|
||||
if (map->getBlock(warpEvent->getX(), warpEvent->getY(), &block)) {
|
||||
if (map->layout->getBlock(warpEvent->getX(), warpEvent->getY(), &block)) {
|
||||
metatile = Tileset::getMetatile(block.metatileId(), map->layout->tileset_primary, map->layout->tileset_secondary);
|
||||
}
|
||||
// metatile may be null if the warp is in the map border. Display the warning in this case
|
||||
@@ -2060,7 +2165,7 @@ void Editor::selectedEventIndexChanged(int index, Event::Group eventGroup) {
|
||||
}
|
||||
|
||||
void Editor::duplicateSelectedEvents() {
|
||||
if (!selected_events || !selected_events->length() || !map || !current_view || map_item->paintingMode != MapPixmapItem::PaintMode::EventObjects)
|
||||
if (!selected_events || !selected_events->length() || !map || !current_view || this->getEditingLayout())
|
||||
return;
|
||||
|
||||
QList<Event *> selectedEvents;
|
||||
@@ -2117,6 +2222,50 @@ bool Editor::eventLimitReached(Event::Type event_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Editor::deleteSelectedEvents() {
|
||||
if (!this->selected_events || this->selected_events->length() == 0 || !this->map || this->editMode != EditMode::Events)
|
||||
return;
|
||||
|
||||
DraggablePixmapItem *nextSelectedEvent = nullptr;
|
||||
QList<Event *> selectedEvents;
|
||||
int numDeleted = 0;
|
||||
for (DraggablePixmapItem *item : *this->selected_events) {
|
||||
Event::Group event_group = item->event->getEventGroup();
|
||||
if (event_group != Event::Group::Heal) {
|
||||
numDeleted++;
|
||||
item->event->setPixmapItem(item);
|
||||
selectedEvents.append(item->event);
|
||||
}
|
||||
else { // don't allow deletion of heal locations
|
||||
logWarn(QString("Cannot delete event of type '%1'").arg(Event::eventTypeToString(item->event->getEventType())));
|
||||
}
|
||||
}
|
||||
if (numDeleted) {
|
||||
// Get the index for the event that should be selected after this event has been deleted.
|
||||
// Select event at next smallest index when deleting a single event.
|
||||
// If deleting multiple events, just let editor work out next selected.
|
||||
if (numDeleted == 1) {
|
||||
Event::Group event_group = selectedEvents[0]->getEventGroup();
|
||||
int index = this->map->events.value(event_group).indexOf(selectedEvents[0]);
|
||||
if (index != this->map->events.value(event_group).size() - 1)
|
||||
index++;
|
||||
else
|
||||
index--;
|
||||
Event *event = nullptr;
|
||||
if (index >= 0)
|
||||
event = this->map->events.value(event_group).at(index);
|
||||
for (QGraphicsItem *child : this->events_group->childItems()) {
|
||||
DraggablePixmapItem *event_item = static_cast<DraggablePixmapItem *>(child);
|
||||
if (event_item->event == event) {
|
||||
nextSelectedEvent = event_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->map->editHistory.push(new EventDelete(this, this->map, selectedEvents, nextSelectedEvent ? nextSelectedEvent->event : nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::openMapScripts() const {
|
||||
openInTextEditor(map->getScriptsFilePath());
|
||||
}
|
||||
@@ -2199,11 +2348,11 @@ bool Editor::startDetachedProcess(const QString &command, const QString &working
|
||||
// is clicking on the background instead of an event.
|
||||
void Editor::objectsView_onMousePress(QMouseEvent *event) {
|
||||
// make sure we are in object editing mode
|
||||
if (map_item && map_item->paintingMode != MapPixmapItem::PaintMode::EventObjects) {
|
||||
if (map_item && this->editMode != EditMode::Events) {
|
||||
return;
|
||||
}
|
||||
if (this->obj_edit_mode == "paint" && event->buttons() & Qt::RightButton) {
|
||||
this->obj_edit_mode = "select";
|
||||
if (this->objectEditAction == EditAction::Paint && event->buttons() & Qt::RightButton) {
|
||||
this->objectEditAction = EditAction::Select;
|
||||
this->settings->mapCursor = QCursor();
|
||||
this->cursorMapTileRect->setSingleTileMode();
|
||||
this->ui->toolButton_Paint->setChecked(false);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <QFile>
|
||||
|
||||
namespace fex
|
||||
{
|
||||
@@ -155,48 +156,26 @@ namespace fex
|
||||
return Token(Token::Type::kDefine, filename_, line_number_);
|
||||
}
|
||||
|
||||
std::vector<Token> Lexer::LexString(const std::string &data)
|
||||
std::vector<Token> Lexer::LexFile(const QString &path)
|
||||
{
|
||||
filename_ = "string literal";
|
||||
line_number_ = 1;
|
||||
index_ = 0;
|
||||
data_ = data;
|
||||
|
||||
return Lex();
|
||||
}
|
||||
|
||||
std::vector<Token> Lexer::LexFile(const std::string &path)
|
||||
{
|
||||
filename_ = path;
|
||||
filename_ = path.toStdString();
|
||||
line_number_ = 1;
|
||||
|
||||
std::ifstream file;
|
||||
file.open(path);
|
||||
// Note: Using QFile instead of ifstream to handle encoding differences between platforms
|
||||
// (specifically to handle accented characters on Windows)
|
||||
QFile file(path);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
|
||||
std::stringstream stream;
|
||||
stream << file.rdbuf();
|
||||
const QByteArray data = file.readAll();
|
||||
|
||||
index_ = 0;
|
||||
data_ = stream.str();
|
||||
data_ = data.toStdString();
|
||||
|
||||
file.close();
|
||||
|
||||
return Lex();
|
||||
}
|
||||
|
||||
void Lexer::LexFileDumpTokens(const std::string &path, const std::string &out)
|
||||
{
|
||||
std::ofstream file;
|
||||
file.open(out);
|
||||
|
||||
for (Token token : LexFile(path))
|
||||
{
|
||||
file << token.ToString() << std::endl;
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
std::vector<Token> Lexer::Lex()
|
||||
{
|
||||
std::vector<Token> tokens;
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace fex
|
||||
return DefineStatement(identifer, value);
|
||||
}
|
||||
|
||||
std::map<std::string, int> Parser::ReadDefines(const std::string &filename, std::vector<std::string> matching)
|
||||
std::map<std::string, int> Parser::ReadDefines(const QString &filename, std::vector<std::string> matching)
|
||||
{
|
||||
std::map<std::string, int> out;
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#include "lib/fex/parser_util.h"
|
||||
|
||||
#include <QMap>
|
||||
|
||||
#include "lib/fex/parser.h"
|
||||
|
||||
ParserUtil::ParserUtil(QString root): root_(root) {}
|
||||
|
||||
QStringList ParserUtil::ReadDefines(QString filename, QString prefix)
|
||||
{
|
||||
if (filename.isEmpty()) {
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QString filepath = root_ + "/" + filename;
|
||||
|
||||
fex::Parser parser;
|
||||
|
||||
std::vector<std::string> match_list = { prefix.toStdString() + ".*" };
|
||||
std::map<std::string, int> defines = parser.ReadDefines(filepath.toStdString(), match_list);
|
||||
|
||||
QStringList out;
|
||||
for(auto const& define : defines) {
|
||||
out.append(QString::fromStdString(define.first));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
QStringList ParserUtil::ReadDefinesValueSort(QString filename, QString prefix)
|
||||
{
|
||||
|
||||
if (filename.isEmpty()) {
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QString filepath = root_ + "/" + filename;
|
||||
|
||||
fex::Parser parser;
|
||||
|
||||
std::vector<std::string> match_list = { prefix.toStdString() + ".*" };
|
||||
std::map<std::string, int> defines = parser.ReadDefines(filepath.toStdString(), match_list);
|
||||
|
||||
QMultiMap<int, QString> defines_keyed_by_value;
|
||||
for (const auto& pair : defines) {
|
||||
defines_keyed_by_value.insert(pair.second, QString::fromStdString(pair.first));
|
||||
}
|
||||
|
||||
return defines_keyed_by_value.values();
|
||||
}
|
||||
@@ -33,7 +33,6 @@ static const int max_depth = 200;
|
||||
using std::map;
|
||||
using std::make_shared;
|
||||
using std::initializer_list;
|
||||
using std::move;
|
||||
|
||||
/* Helper for representing null - just a do-nothing struct, plus comparison
|
||||
* operators so the helpers in JsonValue work. We can't use nullptr_t because
|
||||
@@ -164,7 +163,7 @@ protected:
|
||||
|
||||
// Constructors
|
||||
explicit Value(const T &value) : m_value(value) {}
|
||||
explicit Value(T &&value) : m_value(move(value)) {}
|
||||
explicit Value(T &&value) : m_value(std::move(value)) {}
|
||||
|
||||
// Get type tag
|
||||
Json::Type type() const override {
|
||||
@@ -211,7 +210,7 @@ class JsonString final : public Value<Json::STRING, QString> {
|
||||
const QString &string_value() const override { return m_value; }
|
||||
public:
|
||||
explicit JsonString(const QString &value) : Value(value) {}
|
||||
explicit JsonString(QString &&value) : Value(move(value)) {}
|
||||
explicit JsonString(QString &&value) : Value(std::move(value)) {}
|
||||
};
|
||||
|
||||
class JsonArray final : public Value<Json::ARRAY, Json::array> {
|
||||
@@ -219,7 +218,7 @@ class JsonArray final : public Value<Json::ARRAY, Json::array> {
|
||||
const Json & operator[](int i) const override;
|
||||
public:
|
||||
explicit JsonArray(const Json::array &value) : Value(value) {}
|
||||
explicit JsonArray(Json::array &&value) : Value(move(value)) {}
|
||||
explicit JsonArray(Json::array &&value) : Value(std::move(value)) {}
|
||||
};
|
||||
|
||||
class JsonObject final : public Value<Json::OBJECT, Json::object> {
|
||||
@@ -227,7 +226,7 @@ class JsonObject final : public Value<Json::OBJECT, Json::object> {
|
||||
const Json & operator[](const QString &key) const override;
|
||||
public:
|
||||
explicit JsonObject(const Json::object &value) : Value(value) {}
|
||||
explicit JsonObject(Json::object &&value) : Value(move(value)) {}
|
||||
explicit JsonObject(Json::object &&value) : Value(std::move(value)) {}
|
||||
};
|
||||
|
||||
class JsonNull final : public Value<Json::NUL, NullStruct> {
|
||||
@@ -269,12 +268,12 @@ Json::Json(double value) : m_ptr(make_shared<JsonDouble>(value)) {
|
||||
Json::Json(int value) : m_ptr(make_shared<JsonInt>(value)) {}
|
||||
Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {}
|
||||
Json::Json(const QString &value) : m_ptr(make_shared<JsonString>(value)) {}
|
||||
Json::Json(QString &&value) : m_ptr(make_shared<JsonString>(move(value))) {}
|
||||
Json::Json(QString &&value) : m_ptr(make_shared<JsonString>(std::move(value))) {}
|
||||
Json::Json(const char * value) : m_ptr(make_shared<JsonString>(value)) {}
|
||||
Json::Json(const Json::array &values) : m_ptr(make_shared<JsonArray>(values)) {}
|
||||
Json::Json(Json::array &&values) : m_ptr(make_shared<JsonArray>(move(values))) {}
|
||||
Json::Json(Json::array &&values) : m_ptr(make_shared<JsonArray>(std::move(values))) {}
|
||||
Json::Json(const Json::object &values) : m_ptr(make_shared<JsonObject>(values)) {}
|
||||
Json::Json(Json::object &&values) : m_ptr(make_shared<JsonObject>(move(values))) {}
|
||||
Json::Json(Json::object &&values) : m_ptr(make_shared<JsonObject>(std::move(values))) {}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * *
|
||||
* Accessors
|
||||
@@ -399,7 +398,7 @@ struct JsonParser final {
|
||||
* Mark this parse as failed.
|
||||
*/
|
||||
Json fail(QString &&msg) {
|
||||
return fail(move(msg), Json());
|
||||
return fail(std::move(msg), Json());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
1404
src/mainwindow.cpp
451
src/project.cpp
@@ -7,6 +7,7 @@
|
||||
#include "tile.h"
|
||||
#include "tileset.h"
|
||||
#include "map.h"
|
||||
#include "filedialog.h"
|
||||
|
||||
#include "orderedjson.h"
|
||||
|
||||
@@ -34,60 +35,23 @@ int Project::max_map_data_size = 10240; // 0x2800
|
||||
int Project::default_map_size = 20;
|
||||
int Project::max_object_events = 64;
|
||||
|
||||
Project::Project(QWidget *parent) :
|
||||
Project::Project(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
initSignals();
|
||||
QObject::connect(&this->fileWatcher, &QFileSystemWatcher::fileChanged, this, &Project::fileChanged);
|
||||
}
|
||||
|
||||
Project::~Project()
|
||||
{
|
||||
clearMapCache();
|
||||
clearTilesetCache();
|
||||
}
|
||||
|
||||
void Project::initSignals() {
|
||||
// detect changes to specific filepaths being monitored
|
||||
QObject::connect(&fileWatcher, &QFileSystemWatcher::fileChanged, [this](QString changed){
|
||||
if (!porymapConfig.monitorFiles) return;
|
||||
if (modifiedFileTimestamps.contains(changed)) {
|
||||
if (QDateTime::currentMSecsSinceEpoch() < modifiedFileTimestamps[changed]) {
|
||||
return;
|
||||
}
|
||||
modifiedFileTimestamps.remove(changed);
|
||||
}
|
||||
|
||||
static bool showing = false;
|
||||
if (showing) return;
|
||||
|
||||
QMessageBox notice(this->parentWidget());
|
||||
notice.setText("File Changed");
|
||||
notice.setInformativeText(QString("The file %1 has changed on disk. Would you like to reload the project?")
|
||||
.arg(changed.remove(this->root + "/")));
|
||||
notice.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
|
||||
notice.setDefaultButton(QMessageBox::No);
|
||||
notice.setIcon(QMessageBox::Question);
|
||||
|
||||
QCheckBox showAgainCheck("Do not ask again.");
|
||||
notice.setCheckBox(&showAgainCheck);
|
||||
|
||||
showing = true;
|
||||
int choice = notice.exec();
|
||||
if (choice == QMessageBox::Yes) {
|
||||
emit reloadProject();
|
||||
} else if (choice == QMessageBox::No) {
|
||||
if (showAgainCheck.isChecked()) {
|
||||
porymapConfig.monitorFiles = false;
|
||||
emit uncheckMonitorFilesAction();
|
||||
}
|
||||
}
|
||||
showing = false;
|
||||
});
|
||||
clearMapLayouts();
|
||||
clearEventGraphics();
|
||||
}
|
||||
|
||||
void Project::set_root(QString dir) {
|
||||
this->root = dir;
|
||||
this->importExportPath = dir;
|
||||
FileDialog::setDirectory(dir);
|
||||
this->parser.set_root(dir);
|
||||
}
|
||||
|
||||
@@ -160,7 +124,6 @@ void Project::clearMapCache() {
|
||||
delete map;
|
||||
}
|
||||
mapCache.clear();
|
||||
emit mapCacheCleared();
|
||||
}
|
||||
|
||||
void Project::clearTilesetCache() {
|
||||
@@ -362,6 +325,7 @@ bool Project::loadMapData(Map* map) {
|
||||
heal->setRespawnNPC(loc.respawnNPC);
|
||||
}
|
||||
map->events[Event::Group::Heal].append(heal);
|
||||
map->ownedEvents.append(heal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,15 +389,87 @@ QString Project::readMapLocation(QString map_name) {
|
||||
return ParseUtil::jsonToQString(mapObj["region_map_section"]);
|
||||
}
|
||||
|
||||
bool Project::loadLayout(MapLayout *layout) {
|
||||
// Force these to run even if one fails
|
||||
bool loadedTilesets = loadLayoutTilesets(layout);
|
||||
bool loadedBlockdata = loadBlockdata(layout);
|
||||
bool loadedBorder = loadLayoutBorder(layout);
|
||||
Layout *Project::createNewLayout(Layout::SimpleSettings &layoutSettings) {
|
||||
QString basePath = projectConfig.getFilePath(ProjectFilePath::data_layouts_folders);
|
||||
Layout *layout;
|
||||
|
||||
return loadedTilesets
|
||||
&& loadedBlockdata
|
||||
&& loadedBorder;
|
||||
// Handle the case where we are copying from an existing layout first.
|
||||
if (!layoutSettings.from_id.isEmpty()) {
|
||||
// load from layout
|
||||
loadLayout(mapLayouts[layoutSettings.from_id]);
|
||||
|
||||
layout = mapLayouts[layoutSettings.from_id]->copy();
|
||||
layout->name = layoutSettings.name;
|
||||
layout->id = layoutSettings.id;
|
||||
layout->border_path = QString("%1%2/border.bin").arg(basePath, layoutSettings.name);
|
||||
layout->blockdata_path = QString("%1%2/map.bin").arg(basePath, layoutSettings.name);
|
||||
}
|
||||
else {
|
||||
layout = new Layout;
|
||||
|
||||
layout->name = layoutSettings.name;
|
||||
layout->id = layoutSettings.id;
|
||||
layout->width = layoutSettings.width;
|
||||
layout->height = layoutSettings.height;
|
||||
layout->border_width = DEFAULT_BORDER_WIDTH;
|
||||
layout->border_height = DEFAULT_BORDER_HEIGHT;
|
||||
layout->tileset_primary_label = layoutSettings.tileset_primary_label;
|
||||
layout->tileset_secondary_label = layoutSettings.tileset_secondary_label;
|
||||
layout->border_path = QString("%1%2/border.bin").arg(basePath, layoutSettings.name);
|
||||
layout->blockdata_path = QString("%1%2/map.bin").arg(basePath, layoutSettings.name);
|
||||
|
||||
setNewLayoutBlockdata(layout);
|
||||
setNewLayoutBorder(layout);
|
||||
}
|
||||
|
||||
// Create a new directory for the layout
|
||||
QString newLayoutDir = QString(root + "/%1%2").arg(projectConfig.getFilePath(ProjectFilePath::data_layouts_folders), layout->name);
|
||||
if (!QDir::root().mkdir(newLayoutDir)) {
|
||||
logError(QString("Error: failed to create directory for new layout: '%1'").arg(newLayoutDir));
|
||||
delete layout;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mapLayouts.insert(layout->id, layout);
|
||||
mapLayoutsMaster.insert(layout->id, layout->copy());
|
||||
mapLayoutsTable.append(layout->id);
|
||||
mapLayoutsTableMaster.append(layout->id);
|
||||
layoutIdsToNames.insert(layout->id, layout->name);
|
||||
|
||||
saveLayout(layout);
|
||||
|
||||
this->loadLayout(layout);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
bool Project::loadLayout(Layout *layout) {
|
||||
if (!layout->loaded) {
|
||||
// Force these to run even if one fails
|
||||
bool loadedTilesets = loadLayoutTilesets(layout);
|
||||
bool loadedBlockdata = loadBlockdata(layout);
|
||||
bool loadedBorder = loadLayoutBorder(layout);
|
||||
|
||||
if (loadedTilesets && loadedBlockdata && loadedBorder) {
|
||||
layout->loaded = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Layout *Project::loadLayout(QString layoutId) {
|
||||
if (mapLayouts.contains(layoutId)) {
|
||||
Layout *layout = mapLayouts[layoutId];
|
||||
if (loadLayout(layout)) {
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
|
||||
logError(QString("Error: Failed to load layout '%1'").arg(layoutId));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Project::loadMapLayout(Map* map) {
|
||||
@@ -455,9 +491,17 @@ bool Project::loadMapLayout(Map* map) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Project::readMapLayouts() {
|
||||
void Project::clearMapLayouts() {
|
||||
qDeleteAll(mapLayouts);
|
||||
mapLayouts.clear();
|
||||
qDeleteAll(mapLayoutsMaster);
|
||||
mapLayoutsMaster.clear();
|
||||
mapLayoutsTable.clear();
|
||||
layoutIdsToNames.clear();
|
||||
}
|
||||
|
||||
bool Project::readMapLayouts() {
|
||||
clearMapLayouts();
|
||||
|
||||
QString layoutsFilepath = projectConfig.getFilePath(ProjectFilePath::json_layouts);
|
||||
QString fullFilepath = QString("%1/%2").arg(root).arg(layoutsFilepath);
|
||||
@@ -483,7 +527,7 @@ bool Project::readMapLayouts() {
|
||||
.arg(layoutsLabel));
|
||||
}
|
||||
|
||||
QList<QString> requiredFields = QList<QString>{
|
||||
static const QList<QString> requiredFields = QList<QString>{
|
||||
"id",
|
||||
"name",
|
||||
"width",
|
||||
@@ -501,7 +545,7 @@ bool Project::readMapLayouts() {
|
||||
logError(QString("Layout %1 is missing field(s) in %2.").arg(i).arg(layoutsFilepath));
|
||||
return false;
|
||||
}
|
||||
MapLayout *layout = new MapLayout();
|
||||
Layout *layout = new Layout();
|
||||
layout->id = ParseUtil::jsonToQString(layoutObj["id"]);
|
||||
if (layout->id.isEmpty()) {
|
||||
logError(QString("Missing 'id' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
|
||||
@@ -577,14 +621,12 @@ bool Project::readMapLayouts() {
|
||||
return false;
|
||||
}
|
||||
mapLayouts.insert(layout->id, layout);
|
||||
mapLayoutsMaster.insert(layout->id, layout->copy());
|
||||
mapLayoutsTable.append(layout->id);
|
||||
mapLayoutsTableMaster.append(layout->id);
|
||||
layoutIdsToNames.insert(layout->id, layout->name);
|
||||
}
|
||||
|
||||
// Deep copy
|
||||
mapLayoutsMaster = mapLayouts;
|
||||
mapLayoutsMaster.detach();
|
||||
mapLayoutsTableMaster = mapLayoutsTable;
|
||||
mapLayoutsTableMaster.detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -601,7 +643,7 @@ void Project::saveMapLayouts() {
|
||||
|
||||
OrderedJson::array layoutsArr;
|
||||
for (QString layoutId : mapLayoutsTableMaster) {
|
||||
MapLayout *layout = mapLayouts.value(layoutId);
|
||||
Layout *layout = mapLayoutsMaster.value(layoutId);
|
||||
OrderedJson::object layoutObj;
|
||||
layoutObj["id"] = layout->id;
|
||||
layoutObj["name"] = layout->name;
|
||||
@@ -666,6 +708,47 @@ void Project::saveMapGroups() {
|
||||
mapGroupsFile.close();
|
||||
}
|
||||
|
||||
void Project::saveRegionMapSections() {
|
||||
const QString filepath = QString("%1/%2").arg(this->root).arg(projectConfig.getFilePath(ProjectFilePath::json_region_map_entries));
|
||||
QFile file(filepath);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
logError(QString("Could not open '%1' for writing").arg(filepath));
|
||||
return;
|
||||
}
|
||||
|
||||
const QString emptyMapsecName = getEmptyMapsecName();
|
||||
OrderedJson::array mapSectionArray;
|
||||
for (const auto &idName : this->mapSectionIdNames) {
|
||||
// The 'empty' map section (MAPSEC_NONE) isn't normally present in the region map sections data file.
|
||||
// We append this name to mapSectionIdNames ourselves if it isn't present, in which case we don't want to output data for it here.
|
||||
if (!this->saveEmptyMapsec && idName == emptyMapsecName)
|
||||
continue;
|
||||
|
||||
OrderedJson::object mapSectionObj;
|
||||
mapSectionObj["id"] = idName;
|
||||
|
||||
if (this->regionMapEntries.contains(idName)) {
|
||||
MapSectionEntry entry = this->regionMapEntries.value(idName);
|
||||
mapSectionObj["name"] = entry.name;
|
||||
mapSectionObj["x"] = entry.x;
|
||||
mapSectionObj["y"] = entry.y;
|
||||
mapSectionObj["width"] = entry.width;
|
||||
mapSectionObj["height"] = entry.height;
|
||||
}
|
||||
|
||||
mapSectionArray.append(mapSectionObj);
|
||||
}
|
||||
|
||||
OrderedJson::object object;
|
||||
object["map_sections"] = mapSectionArray;
|
||||
|
||||
ignoreWatchedFileTemporarily(filepath);
|
||||
OrderedJson json(object);
|
||||
OrderedJsonDoc jsonDoc(&json);
|
||||
jsonDoc.dump(&file);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void Project::saveWildMonData() {
|
||||
if (!this->wildEncountersLoaded) return;
|
||||
|
||||
@@ -1004,7 +1087,7 @@ void Project::saveTilesetMetatileAttributes(Tileset *tileset) {
|
||||
QFile attrs_file(tileset->metatile_attrs_path);
|
||||
if (attrs_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
QByteArray data;
|
||||
for (Metatile *metatile : tileset->metatiles) {
|
||||
for (const auto &metatile : tileset->metatiles()) {
|
||||
uint32_t attributes = metatile->getAttributes();
|
||||
for (int i = 0; i < projectConfig.metatileAttributesSize; i++)
|
||||
data.append(static_cast<char>(attributes >> (8 * i)));
|
||||
@@ -1020,7 +1103,7 @@ void Project::saveTilesetMetatiles(Tileset *tileset) {
|
||||
if (metatiles_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
QByteArray data;
|
||||
int numTiles = projectConfig.getNumTilesInMetatile();
|
||||
for (Metatile *metatile : tileset->metatiles) {
|
||||
for (const auto &metatile : tileset->metatiles()) {
|
||||
for (int i = 0; i < numTiles; i++) {
|
||||
uint16_t tile = metatile->tiles.at(i).rawValue();
|
||||
data.append(static_cast<char>(tile));
|
||||
@@ -1029,7 +1112,7 @@ void Project::saveTilesetMetatiles(Tileset *tileset) {
|
||||
}
|
||||
metatiles_file.write(data);
|
||||
} else {
|
||||
tileset->metatiles.clear();
|
||||
tileset->clearMetatiles();
|
||||
logError(QString("Could not open tileset metatiles file '%1'").arg(tileset->metatiles_path));
|
||||
}
|
||||
}
|
||||
@@ -1047,13 +1130,14 @@ void Project::saveTilesetTilesImage(Tileset *tileset) {
|
||||
}
|
||||
|
||||
void Project::saveTilesetPalettes(Tileset *tileset) {
|
||||
for (int i = 0; i < Project::getNumPalettesTotal(); i++) {
|
||||
int numPalettes = qMin(tileset->palettePaths.length(), tileset->palettes.length());
|
||||
for (int i = 0; i < numPalettes; i++) {
|
||||
QString filepath = tileset->palettePaths.at(i);
|
||||
PaletteUtil::writeJASC(filepath, tileset->palettes.at(i).toVector(), 0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
bool Project::loadLayoutTilesets(MapLayout *layout) {
|
||||
bool Project::loadLayoutTilesets(Layout *layout) {
|
||||
layout->tileset_primary = getTileset(layout->tileset_primary_label);
|
||||
if (!layout->tileset_primary) {
|
||||
QString defaultTileset = this->getDefaultPrimaryTilesetLabel();
|
||||
@@ -1121,11 +1205,11 @@ Tileset* Project::loadTileset(QString label, Tileset *tileset) {
|
||||
return tileset;
|
||||
}
|
||||
|
||||
bool Project::loadBlockdata(MapLayout *layout) {
|
||||
bool Project::loadBlockdata(Layout *layout) {
|
||||
QString path = QString("%1/%2").arg(root).arg(layout->blockdata_path);
|
||||
layout->blockdata = readBlockdata(path);
|
||||
layout->lastCommitBlocks.blocks = layout->blockdata;
|
||||
layout->lastCommitBlocks.mapDimensions = QSize(layout->getWidth(), layout->getHeight());
|
||||
layout->lastCommitBlocks.layoutDimensions = QSize(layout->getWidth(), layout->getHeight());
|
||||
|
||||
if (layout->blockdata.count() != layout->getWidth() * layout->getHeight()) {
|
||||
logWarn(QString("Layout blockdata length %1 does not match dimensions %2x%3 (should be %4). Resizing blockdata.")
|
||||
@@ -1138,19 +1222,19 @@ bool Project::loadBlockdata(MapLayout *layout) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::setNewMapBlockdata(Map *map) {
|
||||
map->layout->blockdata.clear();
|
||||
int width = map->getWidth();
|
||||
int height = map->getHeight();
|
||||
void Project::setNewLayoutBlockdata(Layout *layout) {
|
||||
layout->blockdata.clear();
|
||||
int width = layout->getWidth();
|
||||
int height = layout->getHeight();
|
||||
Block block(projectConfig.defaultMetatileId, projectConfig.defaultCollision, projectConfig.defaultElevation);
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
map->layout->blockdata.append(block);
|
||||
layout->blockdata.append(block);
|
||||
}
|
||||
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
|
||||
map->layout->lastCommitBlocks.mapDimensions = QSize(width, height);
|
||||
layout->lastCommitBlocks.blocks = layout->blockdata;
|
||||
layout->lastCommitBlocks.layoutDimensions = QSize(width, height);
|
||||
}
|
||||
|
||||
bool Project::loadLayoutBorder(MapLayout *layout) {
|
||||
bool Project::loadLayoutBorder(Layout *layout) {
|
||||
QString path = QString("%1/%2").arg(root).arg(layout->border_path);
|
||||
layout->border = readBlockdata(path);
|
||||
layout->lastCommitBlocks.border = layout->border;
|
||||
@@ -1166,36 +1250,36 @@ bool Project::loadLayoutBorder(MapLayout *layout) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Project::setNewMapBorder(Map *map) {
|
||||
map->layout->border.clear();
|
||||
int width = map->getBorderWidth();
|
||||
int height = map->getBorderHeight();
|
||||
void Project::setNewLayoutBorder(Layout *layout) {
|
||||
layout->border.clear();
|
||||
int width = layout->getBorderWidth();
|
||||
int height = layout->getBorderHeight();
|
||||
|
||||
if (projectConfig.newMapBorderMetatileIds.length() != width * height) {
|
||||
// Border size doesn't match the number of default border metatiles.
|
||||
// Fill the border with empty metatiles.
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
map->layout->border.append(0);
|
||||
layout->border.append(0);
|
||||
}
|
||||
} else {
|
||||
// Fill the border with the default metatiles from the config.
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
map->layout->border.append(projectConfig.newMapBorderMetatileIds.at(i));
|
||||
layout->border.append(projectConfig.newMapBorderMetatileIds.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
map->layout->lastCommitBlocks.border = map->layout->border;
|
||||
map->layout->lastCommitBlocks.borderDimensions = QSize(width, height);
|
||||
layout->lastCommitBlocks.border = layout->border;
|
||||
layout->lastCommitBlocks.borderDimensions = QSize(width, height);
|
||||
}
|
||||
|
||||
void Project::saveLayoutBorder(Map *map) {
|
||||
QString path = QString("%1/%2").arg(root).arg(map->layout->border_path);
|
||||
writeBlockdata(path, map->layout->border);
|
||||
void Project::saveLayoutBorder(Layout *layout) {
|
||||
QString path = QString("%1/%2").arg(root).arg(layout->border_path);
|
||||
writeBlockdata(path, layout->border);
|
||||
}
|
||||
|
||||
void Project::saveLayoutBlockdata(Map* map) {
|
||||
QString path = QString("%1/%2").arg(root).arg(map->layout->blockdata_path);
|
||||
writeBlockdata(path, map->layout->blockdata);
|
||||
void Project::saveLayoutBlockdata(Layout *layout) {
|
||||
QString path = QString("%1/%2").arg(root).arg(layout->blockdata_path);
|
||||
writeBlockdata(path, layout->blockdata);
|
||||
}
|
||||
|
||||
void Project::writeBlockdata(QString path, const Blockdata &blockdata) {
|
||||
@@ -1350,36 +1434,46 @@ void Project::saveMap(Map *map) {
|
||||
jsonDoc.dump(&mapFile);
|
||||
mapFile.close();
|
||||
|
||||
saveLayoutBorder(map);
|
||||
saveLayoutBlockdata(map);
|
||||
saveLayout(map->layout);
|
||||
saveHealLocations(map);
|
||||
|
||||
// Update global data structures with current map data.
|
||||
updateMapLayout(map);
|
||||
|
||||
map->isPersistedToFile = true;
|
||||
map->hasUnsavedDataChanges = false;
|
||||
map->editHistory.setClean();
|
||||
}
|
||||
|
||||
void Project::updateMapLayout(Map* map) {
|
||||
if (!mapLayoutsTableMaster.contains(map->layoutId)) {
|
||||
mapLayoutsTableMaster.append(map->layoutId);
|
||||
void Project::saveLayout(Layout *layout) {
|
||||
//
|
||||
saveLayoutBorder(layout);
|
||||
saveLayoutBlockdata(layout);
|
||||
|
||||
// Update global data structures with current map data.
|
||||
updateLayout(layout);
|
||||
|
||||
layout->editHistory.setClean();
|
||||
}
|
||||
|
||||
void Project::updateLayout(Layout *layout) {
|
||||
if (!mapLayoutsTableMaster.contains(layout->id)) {
|
||||
mapLayoutsTableMaster.append(layout->id);
|
||||
}
|
||||
|
||||
// Deep copy
|
||||
MapLayout *layout = mapLayouts.value(map->layoutId);
|
||||
MapLayout *newLayout = new MapLayout();
|
||||
*newLayout = *layout;
|
||||
mapLayoutsMaster.insert(map->layoutId, newLayout);
|
||||
if (mapLayoutsMaster.contains(layout->id)) {
|
||||
mapLayoutsMaster[layout->id]->copyFrom(layout);
|
||||
}
|
||||
else {
|
||||
mapLayoutsMaster.insert(layout->id, layout->copy());
|
||||
}
|
||||
}
|
||||
|
||||
void Project::saveAllDataStructures() {
|
||||
saveMapLayouts();
|
||||
saveMapGroups();
|
||||
saveRegionMapSections();
|
||||
saveMapConstantsHeader();
|
||||
saveWildMonData();
|
||||
saveConfig();
|
||||
this->hasUnsavedDataChanges = false;
|
||||
}
|
||||
|
||||
void Project::saveConfig() {
|
||||
@@ -1513,16 +1607,16 @@ void Project::loadTilesetMetatiles(Tileset* tileset) {
|
||||
}
|
||||
metatiles.append(metatile);
|
||||
}
|
||||
tileset->metatiles = metatiles;
|
||||
tileset->setMetatiles(metatiles);
|
||||
} else {
|
||||
tileset->metatiles.clear();
|
||||
tileset->clearMetatiles();
|
||||
logError(QString("Could not open tileset metatiles file '%1'").arg(tileset->metatiles_path));
|
||||
}
|
||||
|
||||
QFile attrs_file(tileset->metatile_attrs_path);
|
||||
if (attrs_file.open(QIODevice::ReadOnly)) {
|
||||
QByteArray data = attrs_file.readAll();
|
||||
int num_metatiles = tileset->metatiles.count();
|
||||
int num_metatiles = tileset->numMetatiles();
|
||||
int attrSize = projectConfig.metatileAttributesSize;
|
||||
int num_metatileAttrs = data.length() / attrSize;
|
||||
if (num_metatiles != num_metatileAttrs) {
|
||||
@@ -1535,7 +1629,7 @@ void Project::loadTilesetMetatiles(Tileset* tileset) {
|
||||
uint32_t attributes = 0;
|
||||
for (int j = 0; j < attrSize; j++)
|
||||
attributes |= static_cast<unsigned char>(data.at(i * attrSize + j)) << (8 * j);
|
||||
tileset->metatiles.at(i)->setAttributes(attributes);
|
||||
tileset->metatileAt(i)->setAttributes(attributes);
|
||||
}
|
||||
} else {
|
||||
logError(QString("Could not open tileset metatile attributes file '%1'").arg(tileset->metatile_attrs_path));
|
||||
@@ -1863,11 +1957,12 @@ Map* Project::addNewMapToGroup(QString mapName, int groupNum, Map *newMap, bool
|
||||
if (!existingLayout) {
|
||||
this->mapLayouts.insert(newMap->layoutId, newMap->layout);
|
||||
this->mapLayoutsTable.append(newMap->layoutId);
|
||||
this->layoutIdsToNames.insert(newMap->layout->id, newMap->layout->name);
|
||||
if (!importedMap) {
|
||||
setNewMapBlockdata(newMap);
|
||||
setNewLayoutBlockdata(newMap->layout);
|
||||
}
|
||||
if (newMap->layout->border.isEmpty()) {
|
||||
setNewMapBorder(newMap);
|
||||
setNewLayoutBorder(newMap->layout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1933,8 +2028,6 @@ void Project::appendTilesetLabel(QString label, QString isSecondaryStr) {
|
||||
}
|
||||
|
||||
bool Project::readTilesetLabels() {
|
||||
QStringList primaryTilesets;
|
||||
QStringList secondaryTilesets;
|
||||
this->primaryTilesetLabels.clear();
|
||||
this->secondaryTilesetLabels.clear();
|
||||
this->tilesetLabelsOrdered.clear();
|
||||
@@ -1963,9 +2056,9 @@ bool Project::readTilesetLabels() {
|
||||
} else {
|
||||
this->usingAsmTilesets = false;
|
||||
const auto structs = parser.readCStructs(filename, "", Tileset::getHeaderMemberMap(this->usingAsmTilesets));
|
||||
QStringList labels = structs.keys();
|
||||
const QStringList labels = structs.keys();
|
||||
// TODO: This is alphabetical, AdvanceMap import wants the vanilla order in tilesetLabelsOrdered
|
||||
for (const auto tilesetLabel : labels){
|
||||
for (const auto &tilesetLabel : labels){
|
||||
appendTilesetLabel(tilesetLabel, structs[tilesetLabel].value("isSecondary"));
|
||||
}
|
||||
}
|
||||
@@ -2159,24 +2252,99 @@ bool Project::readFieldmapMasks() {
|
||||
}
|
||||
|
||||
bool Project::readRegionMapSections() {
|
||||
this->mapSectionNameToValue.clear();
|
||||
this->mapSectionValueToName.clear();
|
||||
this->mapSectionIdNames.clear();
|
||||
this->regionMapEntries.clear();
|
||||
this->saveEmptyMapsec = false;
|
||||
const QString defaultName = getEmptyMapsecName();
|
||||
const QString requiredPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix);
|
||||
|
||||
const QStringList regexList = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix))};
|
||||
QString filename = projectConfig.getFilePath(ProjectFilePath::constants_region_map_sections);
|
||||
fileWatcher.addPath(root + "/" + filename);
|
||||
this->mapSectionNameToValue = parser.readCDefinesByRegex(filename, regexList);
|
||||
if (this->mapSectionNameToValue.isEmpty()) {
|
||||
logError(QString("Failed to read region map sections from %1.").arg(filename));
|
||||
QJsonDocument doc;
|
||||
const QString filepath = QString("%1/%2").arg(this->root).arg(projectConfig.getFilePath(ProjectFilePath::json_region_map_entries));
|
||||
if (!parser.tryParseJsonFile(&doc, filepath)) {
|
||||
logError(QString("Failed to read region map sections from '%1'").arg(filepath));
|
||||
return false;
|
||||
}
|
||||
fileWatcher.addPath(filepath);
|
||||
|
||||
for (QString defineName : this->mapSectionNameToValue.keys()) {
|
||||
this->mapSectionValueToName.insert(this->mapSectionNameToValue[defineName], defineName);
|
||||
QJsonArray mapSections = doc.object()["map_sections"].toArray();
|
||||
for (int i = 0; i < mapSections.size(); i++) {
|
||||
QJsonObject mapSectionObj = mapSections.at(i).toObject();
|
||||
|
||||
// For each map section, "id" is the only required field. This is the field we use to display the location names in various drop-downs.
|
||||
const QString idField = "id";
|
||||
if (!mapSectionObj.contains(idField)) {
|
||||
logWarn(QString("Ignoring data for map section %1. Missing required field \"%2\"").arg(i).arg(idField));
|
||||
continue;
|
||||
}
|
||||
const QString idName = ParseUtil::jsonToQString(mapSectionObj[idField]);
|
||||
if (!idName.startsWith(requiredPrefix)) {
|
||||
logWarn(QString("Ignoring data for map section '%1'. IDs must start with the prefix '%2'").arg(idName).arg(requiredPrefix));
|
||||
continue;
|
||||
}
|
||||
|
||||
this->mapSectionIdNames.append(idName);
|
||||
if (idName == defaultName) {
|
||||
// If the user has data for the 'empty' MAPSEC we need to know to output it later,
|
||||
// because we will otherwise add a dummy entry for this value.
|
||||
this->saveEmptyMapsec = true;
|
||||
}
|
||||
|
||||
// Map sections may have additional data indicating their position on the region map.
|
||||
// If they have this data, we can add them to the region map entry list.
|
||||
bool hasRegionMapData = true;
|
||||
static const QSet<QString> regionMapFieldNames = { "name", "x", "y", "width", "height" };
|
||||
for (auto fieldName : regionMapFieldNames) {
|
||||
if (!mapSectionObj.contains(fieldName)) {
|
||||
hasRegionMapData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasRegionMapData)
|
||||
continue;
|
||||
|
||||
MapSectionEntry entry;
|
||||
entry.name = ParseUtil::jsonToQString(mapSectionObj["name"]);
|
||||
entry.x = ParseUtil::jsonToInt(mapSectionObj["x"]);
|
||||
entry.y = ParseUtil::jsonToInt(mapSectionObj["y"]);
|
||||
entry.width = ParseUtil::jsonToInt(mapSectionObj["width"]);
|
||||
entry.height = ParseUtil::jsonToInt(mapSectionObj["height"]);
|
||||
entry.valid = true;
|
||||
this->regionMapEntries[idName] = entry;
|
||||
}
|
||||
|
||||
// Make sure the default name is present in the list.
|
||||
if (!this->mapSectionIdNames.contains(defaultName)) {
|
||||
this->mapSectionIdNames.append(defaultName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString Project::getEmptyMapsecName() {
|
||||
return projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix) + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_empty);
|
||||
}
|
||||
|
||||
// This function assumes a valid and unique name
|
||||
void Project::addNewMapsec(const QString &name) {
|
||||
if (!this->mapSectionIdNames.isEmpty() && this->mapSectionIdNames.last() == getEmptyMapsecName()) {
|
||||
// If the default map section name (MAPSEC_NONE) is last in the list we'll keep it last in the list.
|
||||
this->mapSectionIdNames.insert(this->mapSectionIdNames.length() - 1, name);
|
||||
} else {
|
||||
this->mapSectionIdNames.append(name);
|
||||
}
|
||||
this->hasUnsavedDataChanges = true;
|
||||
emit mapSectionIdNamesChanged();
|
||||
}
|
||||
|
||||
void Project::removeMapsec(const QString &name) {
|
||||
if (!this->mapSectionIdNames.contains(name) || name == getEmptyMapsecName())
|
||||
return;
|
||||
|
||||
this->mapSectionIdNames.removeOne(name);
|
||||
this->hasUnsavedDataChanges = true;
|
||||
emit mapSectionIdNamesChanged();
|
||||
}
|
||||
|
||||
// Read the constants to preserve any "unused" heal locations when writing the file later
|
||||
bool Project::readHealLocationConstants() {
|
||||
this->healLocationNameToValue.clear();
|
||||
@@ -2242,7 +2410,7 @@ bool Project::readHealLocations() {
|
||||
// Pattern for an x, y number pair
|
||||
const QString coordPattern = "\\s*(?<x>[0-9A-Fa-fx]+),\\s*(?<y>[0-9A-Fa-fx]+)";
|
||||
|
||||
for (const auto idName : constants) {
|
||||
for (const auto &idName : constants) {
|
||||
// Create regex pattern for e.g. "SPAWN_PALLET_TOWN - 1] = "
|
||||
const QString initializerPattern = QString("%1\\s*-\\s*1\\s*\\]\\s*=\\s*").arg(idName);
|
||||
|
||||
@@ -2556,7 +2724,14 @@ void Project::setEventPixmap(Event *event, bool forceLoad) {
|
||||
event->loadPixmap(this);
|
||||
}
|
||||
|
||||
void Project::clearEventGraphics() {
|
||||
qDeleteAll(eventGraphicsMap);
|
||||
eventGraphicsMap.clear();
|
||||
}
|
||||
|
||||
bool Project::readEventGraphics() {
|
||||
clearEventGraphics();
|
||||
|
||||
fileWatcher.addPaths(QStringList() << root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_pointers)
|
||||
<< root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_info)
|
||||
<< root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_pic_tables)
|
||||
@@ -2566,8 +2741,6 @@ bool Project::readEventGraphics() {
|
||||
const QString pointersName = projectConfig.getIdentifier(ProjectIdentifier::symbol_obj_event_gfx_pointers);
|
||||
QMap<QString, QString> pointerHash = parser.readNamedIndexCArray(pointersFilepath, pointersName);
|
||||
|
||||
qDeleteAll(eventGraphicsMap);
|
||||
eventGraphicsMap.clear();
|
||||
QStringList gfxNames = gfxDefines.keys();
|
||||
|
||||
// The positions of each of the required members for the gfx info struct.
|
||||
@@ -2586,14 +2759,13 @@ bool Project::readEventGraphics() {
|
||||
QMap<QString, QString> graphicIncbins = parser.readCIncbinMulti(projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx));
|
||||
|
||||
for (QString gfxName : gfxNames) {
|
||||
EventGraphics * eventGraphics = new EventGraphics;
|
||||
|
||||
QString info_label = pointerHash[gfxName].replace("&", "");
|
||||
if (!gfxInfos.contains(info_label))
|
||||
continue;
|
||||
|
||||
const auto gfxInfoAttributes = gfxInfos[info_label];
|
||||
|
||||
auto eventGraphics = new EventGraphics;
|
||||
eventGraphics->inanimate = ParseUtil::gameStringToBool(gfxInfoAttributes.value("inanimate"));
|
||||
QString pic_label = gfxInfoAttributes.value("images");
|
||||
QString dimensions_label = gfxInfoAttributes.value("oam");
|
||||
@@ -2819,11 +2991,6 @@ QString Project::getDynamicMapDefineName() {
|
||||
return prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_dynamic);
|
||||
}
|
||||
|
||||
void Project::setImportExportPath(QString filename)
|
||||
{
|
||||
this->importExportPath = QFileInfo(filename).absolutePath();
|
||||
}
|
||||
|
||||
// If the provided filepath is an absolute path to an existing file, return filepath.
|
||||
// If not, and the provided filepath is a relative path from the project dir to an existing file, return the relative path.
|
||||
// Otherwise return empty string.
|
||||
@@ -2860,3 +3027,23 @@ void Project::applyParsedLimits() {
|
||||
projectConfig.collisionSheetHeight = qMin(projectConfig.collisionSheetHeight, Block::getMaxElevation() + 1);
|
||||
projectConfig.collisionSheetWidth = qMin(projectConfig.collisionSheetWidth, Block::getMaxCollision() + 1);
|
||||
}
|
||||
|
||||
bool Project::hasUnsavedChanges() {
|
||||
if (this->hasUnsavedDataChanges)
|
||||
return true;
|
||||
|
||||
// Check layouts for unsaved changes
|
||||
for (auto i = this->mapLayouts.constBegin(); i != this->mapLayouts.constEnd(); i++) {
|
||||
auto layout = i.value();
|
||||
if (layout && layout->hasUnsavedChanges())
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check loaded maps for unsaved changes
|
||||
for (auto i = this->mapCache.constBegin(); i != this->mapCache.constEnd(); i++) {
|
||||
auto map = i.value();
|
||||
if (map && map->hasUnsavedChanges())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ void MainWindow::tryRedrawMapArea(bool forceRedraw) {
|
||||
this->editor->updateMapBorder();
|
||||
this->editor->updateMapConnections();
|
||||
if (this->tilesetEditor)
|
||||
this->tilesetEditor->updateTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label);
|
||||
this->tilesetEditor->updateTilesets(this->editor->layout->tileset_primary_label, this->editor->layout->tileset_secondary_label);
|
||||
if (this->editor->metatile_selector_item)
|
||||
this->editor->metatile_selector_item->draw();
|
||||
if (this->editor->selected_border_metatiles_item)
|
||||
@@ -42,13 +42,13 @@ void MainWindow::tryRedrawMapArea(bool forceRedraw) {
|
||||
|
||||
void MainWindow::tryCommitMapChanges(bool commitChanges) {
|
||||
if (commitChanges) {
|
||||
Map *map = this->editor->map;
|
||||
if (map) {
|
||||
map->editHistory.push(new ScriptEditMap(map,
|
||||
map->layout->lastCommitBlocks.mapDimensions, QSize(map->getWidth(), map->getHeight()),
|
||||
map->layout->lastCommitBlocks.blocks, map->layout->blockdata,
|
||||
map->layout->lastCommitBlocks.borderDimensions, QSize(map->getBorderWidth(), map->getBorderHeight()),
|
||||
map->layout->lastCommitBlocks.border, map->layout->border
|
||||
Layout *layout = this->editor->layout;
|
||||
if (layout) {
|
||||
layout->editHistory.push(new ScriptEditLayout(layout,
|
||||
layout->lastCommitBlocks.layoutDimensions, QSize(layout->getWidth(), layout->getHeight()),
|
||||
layout->lastCommitBlocks.blocks, layout->blockdata,
|
||||
layout->lastCommitBlocks.borderDimensions, QSize(layout->getBorderWidth(), layout->getBorderHeight()),
|
||||
layout->lastCommitBlocks.border, layout->border
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -59,27 +59,27 @@ void MainWindow::tryCommitMapChanges(bool commitChanges) {
|
||||
//=====================
|
||||
|
||||
QJSValue MainWindow::getBlock(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return QJSValue();
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
if (!this->editor->layout->getBlock(x, y, &block)) {
|
||||
return Scripting::fromBlock(Block());
|
||||
}
|
||||
return Scripting::fromBlock(block);
|
||||
}
|
||||
|
||||
void MainWindow::setBlock(int x, int y, int metatileId, int collision, int elevation, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
this->editor->map->setBlock(x, y, Block(metatileId, collision, elevation));
|
||||
this->editor->layout->setBlock(x, y, Block(metatileId, collision, elevation));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::setBlock(int x, int y, int rawValue, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
this->editor->map->setBlock(x, y, Block(static_cast<uint16_t>(rawValue)));
|
||||
this->editor->layout->setBlock(x, y, Block(static_cast<uint16_t>(rawValue)));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
@@ -93,73 +93,73 @@ void MainWindow::setBlocksFromSelection(int x, int y, bool forceRedraw, bool com
|
||||
}
|
||||
|
||||
int MainWindow::getMetatileId(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return 0;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
if (!this->editor->layout->getBlock(x, y, &block)) {
|
||||
return 0;
|
||||
}
|
||||
return block.metatileId();
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileId(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
if (!this->editor->layout->getBlock(x, y, &block)) {
|
||||
return;
|
||||
}
|
||||
this->editor->map->setBlock(x, y, Block(metatileId, block.collision(), block.elevation()));
|
||||
this->editor->layout->setBlock(x, y, Block(metatileId, block.collision(), block.elevation()));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
int MainWindow::getCollision(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return 0;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
if (!this->editor->layout->getBlock(x, y, &block)) {
|
||||
return 0;
|
||||
}
|
||||
return block.collision();
|
||||
}
|
||||
|
||||
void MainWindow::setCollision(int x, int y, int collision, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
if (!this->editor->layout->getBlock(x, y, &block)) {
|
||||
return;
|
||||
}
|
||||
this->editor->map->setBlock(x, y, Block(block.metatileId(), collision, block.elevation()));
|
||||
this->editor->layout->setBlock(x, y, Block(block.metatileId(), collision, block.elevation()));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
int MainWindow::getElevation(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return 0;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
if (!this->editor->layout->getBlock(x, y, &block)) {
|
||||
return 0;
|
||||
}
|
||||
return block.elevation();
|
||||
}
|
||||
|
||||
void MainWindow::setElevation(int x, int y, int elevation, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
if (!this->editor->layout->getBlock(x, y, &block)) {
|
||||
return;
|
||||
}
|
||||
this->editor->map->setBlock(x, y, Block(block.metatileId(), block.collision(), elevation));
|
||||
this->editor->layout->setBlock(x, y, Block(block.metatileId(), block.collision(), elevation));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::bucketFill(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
this->editor->map_item->floodFill(x, y, metatileId, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
@@ -167,7 +167,7 @@ void MainWindow::bucketFill(int x, int y, int metatileId, bool forceRedraw, bool
|
||||
}
|
||||
|
||||
void MainWindow::bucketFillFromSelection(int x, int y, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
this->editor->map_item->floodFill(x, y, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
@@ -175,7 +175,7 @@ void MainWindow::bucketFillFromSelection(int x, int y, bool forceRedraw, bool co
|
||||
}
|
||||
|
||||
void MainWindow::magicFill(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
this->editor->map_item->magicFill(x, y, metatileId, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
@@ -183,7 +183,7 @@ void MainWindow::magicFill(int x, int y, int metatileId, bool forceRedraw, bool
|
||||
}
|
||||
|
||||
void MainWindow::magicFillFromSelection(int x, int y, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
this->editor->map_item->magicFill(x, y, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
@@ -191,7 +191,7 @@ void MainWindow::magicFillFromSelection(int x, int y, bool forceRedraw, bool com
|
||||
}
|
||||
|
||||
void MainWindow::shift(int xDelta, int yDelta, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
this->editor->map_item->shift(xDelta, yDelta, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
@@ -207,51 +207,51 @@ void MainWindow::commit() {
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getDimensions() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return QJSValue();
|
||||
return Scripting::dimensions(this->editor->map->getWidth(), this->editor->map->getHeight());
|
||||
return Scripting::dimensions(this->editor->layout->getWidth(), this->editor->layout->getHeight());
|
||||
}
|
||||
|
||||
int MainWindow::getWidth() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return 0;
|
||||
return this->editor->map->getWidth();
|
||||
return this->editor->layout->getWidth();
|
||||
}
|
||||
|
||||
int MainWindow::getHeight() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return 0;
|
||||
return this->editor->map->getHeight();
|
||||
return this->editor->layout->getHeight();
|
||||
}
|
||||
|
||||
void MainWindow::setDimensions(int width, int height) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
if (!Project::mapDimensionsValid(width, height))
|
||||
return;
|
||||
this->editor->map->setDimensions(width, height);
|
||||
this->editor->layout->setDimensions(width, height);
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
this->redrawMapScene();
|
||||
}
|
||||
|
||||
void MainWindow::setWidth(int width) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
if (!Project::mapDimensionsValid(width, this->editor->map->getHeight()))
|
||||
if (!Project::mapDimensionsValid(width, this->editor->layout->getHeight()))
|
||||
return;
|
||||
this->editor->map->setDimensions(width, this->editor->map->getHeight());
|
||||
this->editor->layout->setDimensions(width, this->editor->layout->getHeight());
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
this->redrawMapScene();
|
||||
}
|
||||
|
||||
void MainWindow::setHeight(int height) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
if (!Project::mapDimensionsValid(this->editor->map->getWidth(), height))
|
||||
if (!Project::mapDimensionsValid(this->editor->layout->getWidth(), height))
|
||||
return;
|
||||
this->editor->map->setDimensions(this->editor->map->getWidth(), height);
|
||||
this->editor->layout->setDimensions(this->editor->layout->getWidth(), height);
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
this->redrawMapScene();
|
||||
}
|
||||
|
||||
//=====================
|
||||
@@ -259,69 +259,69 @@ void MainWindow::setHeight(int height) {
|
||||
//=====================
|
||||
|
||||
int MainWindow::getBorderMetatileId(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return 0;
|
||||
if (!this->editor->map->isWithinBorderBounds(x, y))
|
||||
if (!this->editor->layout->isWithinBorderBounds(x, y))
|
||||
return 0;
|
||||
return this->editor->map->getBorderMetatileId(x, y);
|
||||
return this->editor->layout->getBorderMetatileId(x, y);
|
||||
}
|
||||
|
||||
void MainWindow::setBorderMetatileId(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
if (!this->editor->map->isWithinBorderBounds(x, y))
|
||||
if (!this->editor->layout->isWithinBorderBounds(x, y))
|
||||
return;
|
||||
this->editor->map->setBorderMetatileId(x, y, metatileId);
|
||||
this->editor->layout->setBorderMetatileId(x, y, metatileId);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getBorderDimensions() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return QJSValue();
|
||||
return Scripting::dimensions(this->editor->map->getBorderWidth(), this->editor->map->getBorderHeight());
|
||||
return Scripting::dimensions(this->editor->layout->getBorderWidth(), this->editor->layout->getBorderHeight());
|
||||
}
|
||||
|
||||
int MainWindow::getBorderWidth() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return 0;
|
||||
return this->editor->map->getBorderWidth();
|
||||
return this->editor->layout->getBorderWidth();
|
||||
}
|
||||
|
||||
int MainWindow::getBorderHeight() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return 0;
|
||||
return this->editor->map->getBorderHeight();
|
||||
return this->editor->layout->getBorderHeight();
|
||||
}
|
||||
|
||||
void MainWindow::setBorderDimensions(int width, int height) {
|
||||
if (!this->editor || !this->editor->map || !projectConfig.useCustomBorderSize)
|
||||
if (!this->editor || !this->editor->layout || !projectConfig.useCustomBorderSize)
|
||||
return;
|
||||
if (width < 1 || height < 1 || width > MAX_BORDER_WIDTH || height > MAX_BORDER_HEIGHT)
|
||||
return;
|
||||
this->editor->map->setBorderDimensions(width, height);
|
||||
this->editor->layout->setBorderDimensions(width, height);
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
this->redrawMapScene();
|
||||
}
|
||||
|
||||
void MainWindow::setBorderWidth(int width) {
|
||||
if (!this->editor || !this->editor->map || !projectConfig.useCustomBorderSize)
|
||||
if (!this->editor || !this->editor->layout || !projectConfig.useCustomBorderSize)
|
||||
return;
|
||||
if (width < 1 || width > MAX_BORDER_WIDTH)
|
||||
return;
|
||||
this->editor->map->setBorderDimensions(width, this->editor->map->getBorderHeight());
|
||||
this->editor->layout->setBorderDimensions(width, this->editor->layout->getBorderHeight());
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
this->redrawMapScene();
|
||||
}
|
||||
|
||||
void MainWindow::setBorderHeight(int height) {
|
||||
if (!this->editor || !this->editor->map || !projectConfig.useCustomBorderSize)
|
||||
if (!this->editor || !this->editor->layout || !projectConfig.useCustomBorderSize)
|
||||
return;
|
||||
if (height < 1 || height > MAX_BORDER_HEIGHT)
|
||||
return;
|
||||
this->editor->map->setBorderDimensions(this->editor->map->getBorderWidth(), height);
|
||||
this->editor->layout->setBorderDimensions(this->editor->layout->getBorderWidth(), height);
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
this->redrawMapScene();
|
||||
}
|
||||
|
||||
//======================
|
||||
@@ -330,7 +330,7 @@ void MainWindow::setBorderHeight(int height) {
|
||||
|
||||
void MainWindow::refreshAfterPaletteChange(Tileset *tileset) {
|
||||
if (this->tilesetEditor) {
|
||||
this->tilesetEditor->updateTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label);
|
||||
this->tilesetEditor->updateTilesets(this->editor->layout->tileset_primary_label, this->editor->layout->tileset_secondary_label);
|
||||
}
|
||||
this->editor->metatile_selector_item->draw();
|
||||
this->editor->selected_border_metatiles_item->draw();
|
||||
@@ -341,7 +341,7 @@ void MainWindow::refreshAfterPaletteChange(Tileset *tileset) {
|
||||
}
|
||||
|
||||
void MainWindow::setTilesetPalette(Tileset *tileset, int paletteIndex, QList<QList<int>> colors) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
if (paletteIndex >= tileset->palettes.size())
|
||||
return;
|
||||
@@ -357,42 +357,42 @@ void MainWindow::setTilesetPalette(Tileset *tileset, int paletteIndex, QList<QLi
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTilesetPalette(int paletteIndex, QList<QList<int>> colors, bool forceRedraw) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return;
|
||||
this->setTilesetPalette(this->editor->map->layout->tileset_primary, paletteIndex, colors);
|
||||
this->setTilesetPalette(this->editor->layout->tileset_primary, paletteIndex, colors);
|
||||
if (forceRedraw) {
|
||||
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_primary);
|
||||
this->refreshAfterPaletteChange(this->editor->layout->tileset_primary);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTilesetPalettes(QList<QList<QList<int>>> palettes, bool forceRedraw) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
this->setTilesetPalette(this->editor->map->layout->tileset_primary, i, palettes[i]);
|
||||
this->setTilesetPalette(this->editor->layout->tileset_primary, i, palettes[i]);
|
||||
}
|
||||
if (forceRedraw) {
|
||||
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_primary);
|
||||
this->refreshAfterPaletteChange(this->editor->layout->tileset_primary);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTilesetPalette(int paletteIndex, QList<QList<int>> colors, bool forceRedraw) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return;
|
||||
this->setTilesetPalette(this->editor->map->layout->tileset_secondary, paletteIndex, colors);
|
||||
this->setTilesetPalette(this->editor->layout->tileset_secondary, paletteIndex, colors);
|
||||
if (forceRedraw) {
|
||||
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_secondary);
|
||||
this->refreshAfterPaletteChange(this->editor->layout->tileset_secondary);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTilesetPalettes(QList<QList<QList<int>>> palettes, bool forceRedraw) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
this->setTilesetPalette(this->editor->map->layout->tileset_secondary, i, palettes[i]);
|
||||
this->setTilesetPalette(this->editor->layout->tileset_secondary, i, palettes[i]);
|
||||
}
|
||||
if (forceRedraw) {
|
||||
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_secondary);
|
||||
this->refreshAfterPaletteChange(this->editor->layout->tileset_secondary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,27 +420,27 @@ QJSValue MainWindow::getTilesetPalettes(const QList<QList<QRgb>> &palettes) {
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getPrimaryTilesetPalette(int paletteIndex) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalette(this->editor->map->layout->tileset_primary->palettes, paletteIndex);
|
||||
return this->getTilesetPalette(this->editor->layout->tileset_primary->palettes, paletteIndex);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getPrimaryTilesetPalettes() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalettes(this->editor->map->layout->tileset_primary->palettes);
|
||||
return this->getTilesetPalettes(this->editor->layout->tileset_primary->palettes);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getSecondaryTilesetPalette(int paletteIndex) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalette(this->editor->map->layout->tileset_secondary->palettes, paletteIndex);
|
||||
return this->getTilesetPalette(this->editor->layout->tileset_secondary->palettes, paletteIndex);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getSecondaryTilesetPalettes() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalettes(this->editor->map->layout->tileset_secondary->palettes);
|
||||
return this->getTilesetPalettes(this->editor->layout->tileset_secondary->palettes);
|
||||
}
|
||||
|
||||
void MainWindow::refreshAfterPalettePreviewChange() {
|
||||
@@ -452,7 +452,7 @@ void MainWindow::refreshAfterPalettePreviewChange() {
|
||||
}
|
||||
|
||||
void MainWindow::setTilesetPalettePreview(Tileset *tileset, int paletteIndex, QList<QList<int>> colors) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
if (paletteIndex >= tileset->palettePreviews.size())
|
||||
return;
|
||||
@@ -467,19 +467,19 @@ void MainWindow::setTilesetPalettePreview(Tileset *tileset, int paletteIndex, QL
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTilesetPalettePreview(int paletteIndex, QList<QList<int>> colors, bool forceRedraw) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return;
|
||||
this->setTilesetPalettePreview(this->editor->map->layout->tileset_primary, paletteIndex, colors);
|
||||
this->setTilesetPalettePreview(this->editor->layout->tileset_primary, paletteIndex, colors);
|
||||
if (forceRedraw) {
|
||||
this->refreshAfterPalettePreviewChange();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTilesetPalettesPreview(QList<QList<QList<int>>> palettes, bool forceRedraw) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
this->setTilesetPalettePreview(this->editor->map->layout->tileset_primary, i, palettes[i]);
|
||||
this->setTilesetPalettePreview(this->editor->layout->tileset_primary, i, palettes[i]);
|
||||
}
|
||||
if (forceRedraw) {
|
||||
this->refreshAfterPalettePreviewChange();
|
||||
@@ -487,19 +487,19 @@ void MainWindow::setPrimaryTilesetPalettesPreview(QList<QList<QList<int>>> palet
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTilesetPalettePreview(int paletteIndex, QList<QList<int>> colors, bool forceRedraw) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return;
|
||||
this->setTilesetPalettePreview(this->editor->map->layout->tileset_secondary, paletteIndex, colors);
|
||||
this->setTilesetPalettePreview(this->editor->layout->tileset_secondary, paletteIndex, colors);
|
||||
if (forceRedraw) {
|
||||
this->refreshAfterPalettePreviewChange();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTilesetPalettesPreview(QList<QList<QList<int>>> palettes, bool forceRedraw) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
this->setTilesetPalettePreview(this->editor->map->layout->tileset_secondary, i, palettes[i]);
|
||||
this->setTilesetPalettePreview(this->editor->layout->tileset_secondary, i, palettes[i]);
|
||||
}
|
||||
if (forceRedraw) {
|
||||
this->refreshAfterPalettePreviewChange();
|
||||
@@ -507,63 +507,63 @@ void MainWindow::setSecondaryTilesetPalettesPreview(QList<QList<QList<int>>> pal
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getPrimaryTilesetPalettePreview(int paletteIndex) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalette(this->editor->map->layout->tileset_primary->palettePreviews, paletteIndex);
|
||||
return this->getTilesetPalette(this->editor->layout->tileset_primary->palettePreviews, paletteIndex);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getPrimaryTilesetPalettesPreview() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalettes(this->editor->map->layout->tileset_primary->palettePreviews);
|
||||
return this->getTilesetPalettes(this->editor->layout->tileset_primary->palettePreviews);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getSecondaryTilesetPalettePreview(int paletteIndex) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalette(this->editor->map->layout->tileset_secondary->palettePreviews, paletteIndex);
|
||||
return this->getTilesetPalette(this->editor->layout->tileset_secondary->palettePreviews, paletteIndex);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getSecondaryTilesetPalettesPreview() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalettes(this->editor->map->layout->tileset_secondary->palettePreviews);
|
||||
return this->getTilesetPalettes(this->editor->layout->tileset_secondary->palettePreviews);
|
||||
}
|
||||
|
||||
int MainWindow::getNumPrimaryTilesetMetatiles() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return 0;
|
||||
return this->editor->map->layout->tileset_primary->metatiles.length();
|
||||
return this->editor->layout->tileset_primary->numMetatiles();
|
||||
}
|
||||
|
||||
int MainWindow::getNumSecondaryTilesetMetatiles() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return 0;
|
||||
return this->editor->map->layout->tileset_secondary->metatiles.length();
|
||||
return this->editor->layout->tileset_secondary->numMetatiles();
|
||||
}
|
||||
|
||||
int MainWindow::getNumPrimaryTilesetTiles() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return 0;
|
||||
return this->editor->map->layout->tileset_primary->tiles.length();
|
||||
return this->editor->layout->tileset_primary->tiles.length();
|
||||
}
|
||||
|
||||
int MainWindow::getNumSecondaryTilesetTiles() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return 0;
|
||||
return this->editor->map->layout->tileset_secondary->tiles.length();
|
||||
return this->editor->layout->tileset_secondary->tiles.length();
|
||||
}
|
||||
|
||||
QString MainWindow::getPrimaryTileset() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary)
|
||||
return QString();
|
||||
return this->editor->map->layout->tileset_primary->name;
|
||||
return this->editor->layout->tileset_primary->name;
|
||||
}
|
||||
|
||||
QString MainWindow::getSecondaryTileset() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_secondary)
|
||||
return QString();
|
||||
return this->editor->map->layout->tileset_secondary->name;
|
||||
return this->editor->layout->tileset_secondary->name;
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTileset(QString tileset) {
|
||||
@@ -575,13 +575,13 @@ void MainWindow::setSecondaryTileset(QString tileset) {
|
||||
}
|
||||
|
||||
void MainWindow::saveMetatilesByMetatileId(int metatileId) {
|
||||
Tileset * tileset = Tileset::getMetatileTileset(metatileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
Tileset * tileset = Tileset::getMetatileTileset(metatileId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
|
||||
if (this->editor->project && tileset)
|
||||
this->editor->project->saveTilesetMetatiles(tileset);
|
||||
}
|
||||
|
||||
void MainWindow::saveMetatileAttributesByMetatileId(int metatileId) {
|
||||
Tileset * tileset = Tileset::getMetatileTileset(metatileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
Tileset * tileset = Tileset::getMetatileTileset(metatileId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
|
||||
if (this->editor->project && tileset)
|
||||
this->editor->project->saveTilesetMetatileAttributes(tileset);
|
||||
|
||||
@@ -597,19 +597,19 @@ void MainWindow::saveMetatileAttributesByMetatileId(int metatileId) {
|
||||
}
|
||||
|
||||
Metatile * MainWindow::getMetatile(int metatileId) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return nullptr;
|
||||
return Tileset::getMetatile(metatileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
return Tileset::getMetatile(metatileId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
|
||||
}
|
||||
|
||||
QString MainWindow::getMetatileLabel(int metatileId) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return QString();
|
||||
return Tileset::getMetatileLabel(metatileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
return Tileset::getMetatileLabel(metatileId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileLabel(int metatileId, QString label) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout)
|
||||
if (!this->editor || !this->editor->layout)
|
||||
return;
|
||||
|
||||
// If the Tileset Editor is opened on this metatile we need to update the text box
|
||||
@@ -618,13 +618,13 @@ void MainWindow::setMetatileLabel(int metatileId, QString label) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Tileset::setMetatileLabel(metatileId, label, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary)) {
|
||||
if (!Tileset::setMetatileLabel(metatileId, label, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary)) {
|
||||
logError("Failed to set metatile label. Must be a valid metatile id and a label containing only letters, numbers, and underscores.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->editor->project)
|
||||
this->editor->project->saveTilesetMetatileLabels(this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
this->editor->project->saveTilesetMetatileLabels(this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
|
||||
}
|
||||
|
||||
int MainWindow::getMetatileLayerType(int metatileId) {
|
||||
@@ -794,9 +794,9 @@ void MainWindow::setMetatileTile(int metatileId, int tileIndex, QJSValue tileObj
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getTilePixels(int tileId) {
|
||||
if (tileId < 0 || !this->editor || !this->editor->project || !this->editor->map || !this->editor->map->layout)
|
||||
if (tileId < 0 || !this->editor || !this->editor->project || !this->editor->map || !this->editor->layout)
|
||||
return QJSValue();
|
||||
QImage tileImage = getTileImage(tileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
QImage tileImage = getTileImage(tileId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
|
||||
if (tileImage.isNull() || tileImage.sizeInBytes() < 64)
|
||||
return QJSValue();
|
||||
const uchar * pixels = tileImage.constBits();
|
||||
@@ -836,7 +836,7 @@ QString MainWindow::getLocation() {
|
||||
void MainWindow::setLocation(QString location) {
|
||||
if (!this->ui || !this->editor || !this->editor->project)
|
||||
return;
|
||||
if (!this->editor->project->mapSectionNameToValue.contains(location)) {
|
||||
if (!this->editor->project->mapSectionIdNames.contains(location)) {
|
||||
logError(QString("Unknown location '%1'").arg(location));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -254,23 +254,21 @@ void MapView::addImage(int x, int y, QString filepath, int layer, bool useCache)
|
||||
}
|
||||
|
||||
void MapView::createImage(int x, int y, QString filepath, int width, int height, int xOffset, int yOffset, qreal hScale, qreal vScale, int paletteId, bool setTransparency, int layer, bool useCache) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout
|
||||
|| !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary || !this->editor->layout->tileset_secondary)
|
||||
return;
|
||||
QList<QRgb> palette;
|
||||
if (paletteId != -1)
|
||||
palette = Tileset::getPalette(paletteId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
palette = Tileset::getPalette(paletteId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
|
||||
if (this->getOverlay(layer)->addImage(x, y, filepath, useCache, width, height, xOffset, yOffset, hScale, vScale, palette, setTransparency))
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::addTileImage(int x, int y, int tileId, bool xflip, bool yflip, int paletteId, bool setTransparency, int layer) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout
|
||||
|| !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary || !this->editor->layout->tileset_secondary)
|
||||
return;
|
||||
QImage image = getPalettedTileImage(tileId,
|
||||
this->editor->map->layout->tileset_primary,
|
||||
this->editor->map->layout->tileset_secondary,
|
||||
this->editor->layout->tileset_primary,
|
||||
this->editor->layout->tileset_secondary,
|
||||
paletteId)
|
||||
.mirrored(xflip, yflip);
|
||||
if (setTransparency)
|
||||
@@ -285,14 +283,13 @@ void MapView::addTileImage(int x, int y, QJSValue tileObj, bool setTransparency,
|
||||
}
|
||||
|
||||
void MapView::addMetatileImage(int x, int y, int metatileId, bool setTransparency, int layer) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout
|
||||
|| !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary)
|
||||
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary || !this->editor->layout->tileset_secondary)
|
||||
return;
|
||||
QImage image = getMetatileImage(static_cast<uint16_t>(metatileId),
|
||||
this->editor->map->layout->tileset_primary,
|
||||
this->editor->map->layout->tileset_secondary,
|
||||
this->editor->map->metatileLayerOrder,
|
||||
this->editor->map->metatileLayerOpacity);
|
||||
this->editor->layout->tileset_primary,
|
||||
this->editor->layout->tileset_secondary,
|
||||
this->editor->layout->metatileLayerOrder,
|
||||
this->editor->layout->metatileLayerOpacity);
|
||||
if (setTransparency)
|
||||
image.setColor(0, qRgba(0, 0, 0, 0));
|
||||
if (this->getOverlay(layer)->addImage(x, y, image))
|
||||
|
||||