mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-17 20:58:07 +02:00
Object picker implemented
This commit is contained in:
parent
082e1194ff
commit
19407954ed
@ -30,9 +30,9 @@ public:
|
||||
virtual void initialize(const CMap & map) = 0;
|
||||
virtual void update(CMap & map) = 0;
|
||||
|
||||
std::string getTownName(const CMap & map, int objectIdx);
|
||||
std::string getHeroName(const CMap & map, int objectIdx);
|
||||
std::string getMonsterName(const CMap & map, int objectIdx);
|
||||
static std::string getTownName(const CMap & map, int objectIdx);
|
||||
static std::string getHeroName(const CMap & map, int objectIdx);
|
||||
static std::string getMonsterName(const CMap & map, int objectIdx);
|
||||
|
||||
static JsonNode conditionToJson(const EventCondition & event);
|
||||
|
||||
|
@ -198,6 +198,9 @@ void MapView::mousePressEvent(QMouseEvent *event)
|
||||
auto * sc = static_cast<MapScene*>(scene());
|
||||
if(!sc || !controller->map())
|
||||
return;
|
||||
|
||||
if(sc->objectPickerView.isVisible())
|
||||
return;
|
||||
|
||||
mouseStart = mapToScene(event->pos());
|
||||
tileStart = tilePrev = int3(mouseStart.x() / 32, mouseStart.y() / 32, sc->level);
|
||||
@ -338,6 +341,22 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
||||
if(rubberBand)
|
||||
rubberBand->hide();
|
||||
|
||||
if(sc->objectPickerView.isVisible())
|
||||
{
|
||||
if(event->button() == Qt::RightButton)
|
||||
sc->objectPickerView.discard();
|
||||
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
mouseStart = mapToScene(event->pos());
|
||||
tileStart = tilePrev = int3(mouseStart.x() / 32, mouseStart.y() / 32, sc->level);
|
||||
if(auto * pickedObject = sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y))
|
||||
sc->objectPickerView.select(pickedObject);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch(selectionTool)
|
||||
{
|
||||
@ -547,6 +566,7 @@ MapScene::MapScene(int lvl):
|
||||
terrainView(this),
|
||||
objectsView(this),
|
||||
selectionObjectsView(this),
|
||||
objectPickerView(this),
|
||||
isTerrainSelected(false),
|
||||
isObjectSelected(false)
|
||||
{
|
||||
@ -562,6 +582,7 @@ std::list<AbstractLayer *> MapScene::getAbstractLayers()
|
||||
&objectsView,
|
||||
&gridView,
|
||||
&passabilityView,
|
||||
&objectPickerView,
|
||||
&selectionTerrainView,
|
||||
&selectionObjectsView
|
||||
};
|
||||
@ -575,6 +596,7 @@ void MapScene::updateViews()
|
||||
objectsView.show(true);
|
||||
selectionTerrainView.show(true);
|
||||
selectionObjectsView.show(true);
|
||||
objectPickerView.show(true);
|
||||
}
|
||||
|
||||
void MapScene::terrainSelected(bool anythingSelected)
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
TerrainLayer terrainView;
|
||||
ObjectsLayer objectsView;
|
||||
SelectionObjectsLayer selectionObjectsView;
|
||||
ObjectPickerLayer objectPickerView;
|
||||
|
||||
signals:
|
||||
void selected(bool anything);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "StdInc.h"
|
||||
#include "playerparams.h"
|
||||
#include "ui_playerparams.h"
|
||||
#include "mapsettings/abstractsettings.h"
|
||||
#include "../lib/CTownHandler.h"
|
||||
#include "../lib/constants/StringConstants.h"
|
||||
|
||||
@ -87,7 +88,8 @@ PlayerParams::PlayerParams(MapController & ctrl, int playerId, QWidget *parent)
|
||||
{
|
||||
if(playerInfo.hasMainTown && playerInfo.posOfMainTown == town->pos)
|
||||
foundMainTown = townIndex;
|
||||
const auto name = ctown->faction ? town->getObjectName() : town->getNameTranslated() + ", (random)";
|
||||
|
||||
const auto name = AbstractSettings::getTownName(*controller.map(), i);
|
||||
ui->mainTown->addItem(tr(name.c_str()), QVariant::fromValue(i));
|
||||
++townIndex;
|
||||
}
|
||||
@ -186,3 +188,49 @@ void PlayerParams::on_playerColorCombo_activated(int index)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PlayerParams::on_townSelect_clicked()
|
||||
{
|
||||
auto pred = [this](const CGObjectInstance * obj) -> bool
|
||||
{
|
||||
if(auto town = dynamic_cast<const CGTownInstance*>(obj))
|
||||
return town->getOwner().getNum() == playerColor;
|
||||
return false;
|
||||
};
|
||||
|
||||
std::vector<std::reference_wrapper<ObjectPickerLayer>> pickers;
|
||||
pickers.emplace_back(controller.scene(0)->objectPickerView);
|
||||
if(controller.map()->twoLevel)
|
||||
pickers.emplace_back(controller.scene(1)->objectPickerView);
|
||||
|
||||
for(auto l : pickers)
|
||||
{
|
||||
l.get().highlight(pred);
|
||||
l.get().update();
|
||||
QObject::connect(&l.get(), &ObjectPickerLayer::selectionMade, this, &PlayerParams::onTownPicked);
|
||||
}
|
||||
|
||||
dynamic_cast<QWidget*>(parent()->parent()->parent()->parent())->hide();
|
||||
}
|
||||
|
||||
void PlayerParams::onTownPicked(const CGObjectInstance * obj)
|
||||
{
|
||||
dynamic_cast<QWidget*>(parent()->parent()->parent()->parent())->show();
|
||||
|
||||
std::vector<std::reference_wrapper<ObjectPickerLayer>> pickers;
|
||||
pickers.emplace_back(controller.scene(0)->objectPickerView);
|
||||
if(controller.map()->twoLevel)
|
||||
pickers.emplace_back(controller.scene(1)->objectPickerView);
|
||||
|
||||
for(auto l : pickers)
|
||||
{
|
||||
l.get().clear();
|
||||
l.get().update();
|
||||
QObject::disconnect(&l.get(), &ObjectPickerLayer::selectionMade, this, &PlayerParams::onTownPicked);
|
||||
}
|
||||
|
||||
if(!obj) //discarded
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ public:
|
||||
|
||||
PlayerInfo playerInfo;
|
||||
int playerColor;
|
||||
|
||||
void onTownPicked(const CGObjectInstance *);
|
||||
|
||||
private slots:
|
||||
void on_radioHuman_toggled(bool checked);
|
||||
@ -46,6 +48,8 @@ private slots:
|
||||
|
||||
void on_playerColorCombo_activated(int index);
|
||||
|
||||
void on_townSelect_clicked();
|
||||
|
||||
private:
|
||||
Ui::PlayerParams *ui;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>505</width>
|
||||
<width>614</width>
|
||||
<height>160</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -25,7 +25,7 @@
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -49,136 +49,180 @@
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="4" column="0">
|
||||
<widget class="QComboBox" name="teamId">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioCpu">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CPU only</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioHuman">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Human/CPU</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Team</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="teamId">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="generateHero">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Generate hero at main</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="playerColorCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Main town</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="mainTown">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>(default)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="townSelect">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="generateHero">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Generate hero at main</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QCheckBox" name="randomFaction">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Random faction</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Team</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="radioCpu">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CPU only</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="radioHuman">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Human/CPU</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="4">
|
||||
<widget class="QListWidget" name="allowedFactions">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="mainTown">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>(default)</string>
|
||||
</property>
|
||||
<widget class="QListWidget" name="allowedFactions">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Main town</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="playerColorCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="randomFaction">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Random faction</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -112,6 +112,83 @@ void PassabilityLayer::update()
|
||||
redraw();
|
||||
}
|
||||
|
||||
ObjectPickerLayer::ObjectPickerLayer(MapSceneBase * s): AbstractLayer(s)
|
||||
{
|
||||
}
|
||||
|
||||
void ObjectPickerLayer::highlight(std::function<bool(const CGObjectInstance *)> predicate)
|
||||
{
|
||||
if(!map)
|
||||
return;
|
||||
|
||||
for(int j = 0; j < map->height; ++j)
|
||||
{
|
||||
for(int i = 0; i < map->width; ++i)
|
||||
{
|
||||
auto tl = map->getTile(int3(i, j, scene->level));
|
||||
auto * obj = tl.topVisitableObj();
|
||||
if(!obj && !tl.blockingObjects.empty())
|
||||
obj = tl.blockingObjects.front();
|
||||
|
||||
if(obj && predicate(obj))
|
||||
possibleObjects.insert(obj);
|
||||
}
|
||||
}
|
||||
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
bool ObjectPickerLayer::isVisible() const
|
||||
{
|
||||
return isShown && isActive;
|
||||
}
|
||||
|
||||
void ObjectPickerLayer::clear()
|
||||
{
|
||||
possibleObjects.clear();
|
||||
isActive = false;
|
||||
}
|
||||
|
||||
void ObjectPickerLayer::update()
|
||||
{
|
||||
if(!map)
|
||||
return;
|
||||
|
||||
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
|
||||
pixmap->fill(Qt::transparent);
|
||||
if(isActive)
|
||||
pixmap->fill(QColor(255, 255, 255, 128));
|
||||
|
||||
|
||||
QPainter painter(pixmap.get());
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
for(auto * obj : possibleObjects)
|
||||
{
|
||||
if(obj->pos.z != scene->level)
|
||||
continue;
|
||||
|
||||
for(auto & pos : obj->getBlockedPos())
|
||||
painter.fillRect(pos.x * 32, pos.y * 32, 32, 32, QColor(255, 211, 0, 64));
|
||||
}
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void ObjectPickerLayer::select(const CGObjectInstance * obj)
|
||||
{
|
||||
if(obj && possibleObjects.count(obj))
|
||||
{
|
||||
clear();
|
||||
emit selectionMade(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPickerLayer::discard()
|
||||
{
|
||||
clear();
|
||||
emit selectionMade(nullptr);
|
||||
}
|
||||
|
||||
SelectionTerrainLayer::SelectionTerrainLayer(MapSceneBase * s): AbstractLayer(s)
|
||||
{
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ public:
|
||||
|
||||
void update() override;
|
||||
|
||||
void draw(bool onlyDirty = true); //TODO: implement dirty
|
||||
void draw(bool onlyDirty = true);
|
||||
|
||||
void setDirty(int x, int y);
|
||||
void setDirty(const CGObjectInstance * object);
|
||||
@ -127,6 +127,37 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class ObjectPickerLayer: public AbstractLayer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ObjectPickerLayer(MapSceneBase * s);
|
||||
|
||||
void update() override;
|
||||
bool isVisible() const;
|
||||
|
||||
template<class T>
|
||||
void highlight()
|
||||
{
|
||||
highlight([](const CGObjectInstance * o){ return dynamic_cast<T*>(o); });
|
||||
}
|
||||
|
||||
void highlight(std::function<bool(const CGObjectInstance *)> predicate);
|
||||
|
||||
void clear();
|
||||
|
||||
void select(const CGObjectInstance *);
|
||||
void discard();
|
||||
|
||||
signals:
|
||||
void selectionMade(const CGObjectInstance *);
|
||||
|
||||
private:
|
||||
bool isActive = false;
|
||||
std::set<const CGObjectInstance *> possibleObjects;
|
||||
};
|
||||
|
||||
|
||||
class SelectionObjectsLayer: public AbstractLayer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
Loading…
x
Reference in New Issue
Block a user