From efc53a25e6a5e2344f2abde191639e9cfa76ff38 Mon Sep 17 00:00:00 2001 From: T1ti <40864460+T1ti@users.noreply.github.com> Date: Sat, 23 Dec 2023 00:59:26 +0100 Subject: [PATCH] context menu update --- src/noggit/MapView.cpp | 354 ++++++++++++++++++++++++++- src/noggit/MapView.h | 4 +- src/noggit/Model.h | 1 + src/noggit/Selection.h | 17 ++ src/noggit/WMO.h | 2 + src/noggit/World.cpp | 19 +- src/noggit/World.h | 8 +- src/noggit/rendering/WorldRender.cpp | 4 +- src/noggit/ui/ObjectEditor.cpp | 65 +++-- src/noggit/ui/ObjectEditor.h | 10 +- src/noggit/ui/object_palette.cpp | 4 +- src/noggit/ui/object_palette.hpp | 2 +- 12 files changed, 437 insertions(+), 53 deletions(-) diff --git a/src/noggit/MapView.cpp b/src/noggit/MapView.cpp index 1e759e9e..0c050013 100755 --- a/src/noggit/MapView.cpp +++ b/src/noggit/MapView.cpp @@ -398,7 +398,7 @@ void MapView::snap_selected_models_to_the_ground() } -void MapView::DeleteSelectedObject() +void MapView::DeleteSelectedObjects() { if (terrainMode != editing_mode::object) { @@ -1218,7 +1218,7 @@ void MapView::setupEditMenu() ADD_ACTION (edit_menu, "Delete", Qt::Key_Delete, [this] { NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED); - DeleteSelectedObject(); + DeleteSelectedObjects(); NOGGIT_ACTION_MGR->endAction(); }); @@ -2201,6 +2201,7 @@ void MapView::setupHotkeys() } , [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; } ); + /* addHotkey ( Qt::Key_C , MOD_none , [this] @@ -2208,7 +2209,7 @@ void MapView::setupHotkeys() objectEditor->copy_current_selection(_world.get()); } , [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; } - ); + );*/ addHotkey ( Qt::Key_V , MOD_ctrl @@ -2221,6 +2222,7 @@ void MapView::setupHotkeys() } , [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; } ); + /* addHotkey ( Qt::Key_V , MOD_none , [this] @@ -2230,7 +2232,7 @@ void MapView::setupHotkeys() NOGGIT_ACTION_MGR->endAction(); } , [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; } - ); + );*/ addHotkey ( Qt::Key_V , MOD_shift , [this] { objectEditor->import_last_model_from_wmv(eMODEL); } @@ -2768,6 +2770,11 @@ MapView::MapView( math::degrees camera_yaw0 , [=] { _main_window->statusBar()->removeWidget(_status_database); } ); + setContextMenuPolicy(Qt::CustomContextMenu); + + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), + this, SLOT(ShowContextMenu(const QPoint&))); + moving = strafing = updown = lookat = turn = 0.0f; freelook = false; @@ -4337,8 +4344,7 @@ void MapView::doSelection (bool selectTerrainOnly, bool mouseMove) } _rotation_editor_need_update = true; - objectEditor->update_selection(_world.get()); - + objectEditor->update_selection_ui(_world.get()); } void MapView::update_cursor_pos() @@ -5229,6 +5235,7 @@ void MapView::mousePressEvent(QMouseEvent* event) if (rightMouse) { + _right_click_pos = event->pos(); look = true; } } @@ -5353,6 +5360,13 @@ void MapView::mouseReleaseEvent (QMouseEvent* event) if (_display_mode == display_mode::in_2D) updown = 0; + // // may need to be done in constructor of widget + // this->setContextMenuPolicy(Qt::CustomContextMenu); + // connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), + // this, SLOT(ShowContextMenu(const QPoint&))); + + + break; case Qt::MiddleButton: @@ -5581,3 +5595,331 @@ void MapView::onSettingsSave() _world->renderer()->markTerrainParamsUniformBlockDirty(); } + +void MapView::ShowContextMenu(QPoint pos) +{ + // QApplication::startDragDistance() is 10 + auto mouse_moved = QApplication::startDragDistance() < (_right_click_pos - pos).manhattanLength();; + + // don't show context menu if dragging mouse + if (mouse_moved || ImGuizmo::IsUsing()) + return; + + // TODO : build the menu only once, store it and instead use setVisible ? + + QMenu* menu = new QMenu(this); + + // Undo + QAction action_undo("Undo", this); + menu->addAction(&action_undo); + action_undo.setShortcut(QKeySequence::Undo); + QObject::connect(&action_undo, &QAction::triggered, [=]() + { + NOGGIT_ACTION_MGR->undo(); + }); + // Redo + QAction action_redo("Redo", this); + menu->addAction(&action_redo); + action_redo.setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Z)); + QObject::connect(&action_redo, &QAction::triggered, [=]() + { + NOGGIT_ACTION_MGR->redo(); + }); + + menu->addSeparator(); + + if (terrainMode == editing_mode::object) + { + bool has_selected_objects = _world->get_selected_model_count(); + bool has_copied_objects = objectEditor->clipboardSize(); + + // Copy + QAction action_8("Copy Object(s)", this); + menu->addAction(&action_8); + action_8.setEnabled(has_selected_objects); + action_8.setShortcut(QKeySequence::Copy); + QObject::connect(&action_8, &QAction::triggered, [=]() + { + if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION) + objectEditor->copy_current_selection(_world.get()); + }); + + // Paste + QAction action_9("Paste Object(s)", this); + menu->addAction(&action_9); + action_9.setEnabled(has_copied_objects); + action_9.setShortcut(QKeySequence::Paste); // (Qt::CTRL | Qt::Key_P) + QObject::connect(&action_9, &QAction::triggered, [=]() + { + if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION) + { + NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED); + objectEditor->pasteObject(_cursor_pos, _camera.position, _world.get(), &_object_paste_params); + NOGGIT_ACTION_MGR->endAction(); + } + }); + + // Delete + QAction action_10("Delete Object(s)", this); + menu->addAction(&action_10); + action_10.setEnabled(has_selected_objects); + action_10.setShortcut(QKeySequence::Delete); // (Qt::CTRL | Qt::Key_P) + QObject::connect(&action_10, &QAction::triggered, [=]() + { + if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION) + { + NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED); + DeleteSelectedObjects(); + NOGGIT_ACTION_MGR->endAction(); + } + }); + + // Duplicate + QAction action_11("Duplicate Object(s)", this); + menu->addAction(&action_11); + action_11.setEnabled(has_copied_objects); + action_11.setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B)); // (Qt::CTRL | Qt::Key_P) + QObject::connect(&action_11, &QAction::triggered, [=]() + { + if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION) + { + NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED); + objectEditor->copy_current_selection(_world.get()); + objectEditor->pasteObject(_cursor_pos, _camera.position, _world.get(), &_object_paste_params); + NOGGIT_ACTION_MGR->endAction(); + } + }); + + menu->addSeparator(); + + // selection stuff + QAction action_1("Select all Like Selected", this); // select all objects with the same model + action_1.setToolTip("Warning : Doing actions on models overlapping unloaded tiles can cause crash"); + menu->addAction(&action_1); + action_1.setEnabled(_world->get_selected_model_count() == 1); + QObject::connect(&action_1, &QAction::triggered, [=]() + { + auto last_entry = _world->get_last_selected_model(); + if (last_entry) + { + if (!last_entry.value().index() == eEntry_Object) + return; + + // Only works with m2 doodads + auto obj = std::get(last_entry.value()); + auto model_name = obj->instance_model()->file_key().filepath(); + // auto models = _world->get_models_by_filename()[model_name]; + // std::vector< uint32_t> objects_to_select; + + //makeCurrent(); + //OpenGL::context::scoped_setter const _(::gl, context()); + + _world->reset_selection(); + + if (obj->which() == eMODEL) + { + _world->getModelInstanceStorage().for_each_m2_instance([&](ModelInstance& model_instance) + { + if (model_instance.instance_model()->file_key().filepath() == model_name) + { + // objects_to_select.push_back(model_instance.uid); + _world->add_to_selection(&model_instance); + } + }); + } + else if (obj->which() == eWMO) + _world->getModelInstanceStorage().for_each_wmo_instance([&](WMOInstance& wmo_instance) + { + if (wmo_instance.instance_model()->file_key().filepath() == model_name) + { + // objects_to_select.push_back(wmo_instance.uid); + _world->add_to_selection(&wmo_instance); + } + }); + + // for (auto uid_it = objects_to_select.begin(); uid_it != objects_to_select.end(); uid_it++) + // { + // auto instance = _world->getObjectInstance(*uid_it); + // // if (!_world->is_selected(instance)) + // _world->add_to_selection(instance); + // } + } + }); + + QAction action_2("Hide Selected Objects", this); + menu->addAction(&action_2); + action_2.setEnabled(has_selected_objects); + action_2.setShortcut(Qt::Key_H); + QObject::connect(&action_2, &QAction::triggered, [=]() + { + if (_world->has_selection()) + { + for (auto& selection : _world->current_selection()) + { + if (selection.index() != eEntry_Object) + continue; + + auto obj = std::get(selection); + + if (obj->which() == eMODEL) + { + static_cast(obj)->model->hide(); + } + else if (obj->which() == eWMO) + { + static_cast(obj)->wmo->hide(); + } + } + } + }); + + QAction action_3("Hide Unselected Objects", this); + + + // QAction action_2("Show Hidden", this); + + QAction action_palette_add("Add Object To Palette", this); + menu->addAction(&action_palette_add); + action_palette_add.setEnabled(_world->get_selected_model_count() == 1); + QObject::connect(&action_palette_add, &QAction::triggered, [=]() + { + + + auto last_entry = _world->get_last_selected_model(); + if (last_entry) + { + if (!last_entry.value().index() == eEntry_Object) + return; + + getObjectPalette()->setVisible(true); + auto obj = std::get(last_entry.value()); + auto model_name = obj->instance_model()->file_key().filepath(); + _object_palette->addObjectByFilename(model_name.c_str()); + } + + }); + + menu->addSeparator(); + + // allow replacing all selected? + QAction action_replace("Replace Models (By Clipboard)", this); + menu->addAction(&action_replace); + // auto model_path = objectEditor->getFilename(); + action_replace.setEnabled(has_selected_objects && objectEditor->clipboardSize() == 1); + action_replace.setToolTip("Replace the currently selected objects by the object in the clipboard (There must only be one!). M2s can only be replaced by m2s"); + QObject::connect(&action_replace, &QAction::triggered, [=]() + { + if (terrainMode != editing_mode::object && NOGGIT_CUR_ACTION) + return; + + // verify this + NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED | Noggit::ActionFlags::eOBJECTS_REMOVED); // Noggit::ActionFlags::eOBJECTS_TRANSFORMED + // NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_TRANSFORMED); + + // get the model to replace by + auto replace_select = objectEditor->getClipboard().front(); + auto replace_obj = std::get(replace_select); + // bool replace_is_wmo = replace_obj->which() == eWMO; + auto replace_path = replace_obj->instance_model()->file_key(); + + // iterate selection (objects to replace) + for (auto& entry : _world->current_selection()) + { + if (entry.index() == eEntry_Object) + { + auto source_obj = std::get(entry); + + //SceneObject* source_scene_obj = source_obj; + + math::degrees::vec3 source_rot(math::degrees(0)._, math::degrees(0)._, math::degrees(0)._); + source_rot = source_obj->dir; + float source_scale = source_obj->scale; + auto source_pos = source_obj->pos; + + if (source_obj->instance_model()->file_key().filepath() == replace_path) + continue; + + // TODO : Test if this breaks if clipboard is empty + + if (replace_obj->which() == eWMO) + { + // if (!replace_is_wmo) + // continue; + + // auto replace_wmo = static_cast(replace_obj); + // auto source_wmo = static_cast(source_obj); + + auto new_obj = _world->addWMOAndGetInstance(replace_path, source_pos, source_rot); + new_obj->wmo->wait_until_loaded(); + new_obj->wmo->waitForChildrenLoaded(); + new_obj->recalcExtents(); + + } + else if (replace_obj->which() == eMODEL) + { + // if (replace_is_wmo) + // continue; + + // auto replace_m2 = static_cast(replace_obj); + // auto source_m2 = static_cast(source_obj); + + // Just swapping model + // Issue : doesn't work with actions + // _world->updateTilesEntry(entry, model_update::remove); + // source_m2->model = scoped_model_reference(replace_path, _context); + // source_m2->recalcExtents(); + // _world->updateTilesEntry(entry, model_update::add); + + + auto new_obj = _world->addM2AndGetInstance(replace_path + , source_pos + , source_scale + , source_rot + , &_object_paste_params + , true + ); + new_obj->model->wait_until_loaded(); + new_obj->model->waitForChildrenLoaded(); + new_obj->recalcExtents(); + } + } + + } + // can cause the usual crash of deleting models overlapping unloaded tiles. + DeleteSelectedObjects(); + // NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED); + NOGGIT_ACTION_MGR->endAction(); + }); + + QAction action_snap("Snap Selected To Ground", this); + menu->addAction(&action_snap); + action_snap.setEnabled(has_selected_objects); + action_snap.setShortcut(Qt::Key_PageDown); // (Qt::CTRL | Qt::Key_P) + QObject::connect(&action_snap, &QAction::triggered, [=]() + { + if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION) + { + NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_TRANSFORMED); + snap_selected_models_to_the_ground(); + NOGGIT_ACTION_MGR->endAction(); + } + }); + + + menu->addSeparator(); + // TODO + QAction action_6("Group Selected Objects TODO", this); + menu->addAction(&action_6); + action_6.setEnabled(_world->has_multiple_model_selected() && false); // TODO, some "notgrouped" condition + + QAction action_7("Ungroup Selected Objects TODO", this); + + menu->addSeparator(); + + menu->exec(mapToGlobal(pos)); // synch + // menu->popup(mapToGlobal(pos)); // asynch + }; + + + +} \ No newline at end of file diff --git a/src/noggit/MapView.h b/src/noggit/MapView.h index b265268a..c5e5e7f2 100755 --- a/src/noggit/MapView.h +++ b/src/noggit/MapView.h @@ -127,6 +127,7 @@ private: CursorType _cursorType; glm::vec3 _cursor_pos; QPoint _drag_start_pos; + QPoint _right_click_pos; float _cursorRotation; bool look, freelook; bool ui_hidden = false; @@ -188,7 +189,7 @@ private: void ResetSelectedObjectRotation(); void snap_selected_models_to_the_ground(); - void DeleteSelectedObject(); + void DeleteSelectedObjects(); void changeZoneIDValue (int set); QPointF _last_mouse_pos; @@ -252,6 +253,7 @@ signals: void updateProgress(int value); public slots: void on_exit_prompt(); + void ShowContextMenu(QPoint pos); public: glm::vec4 cursor_color; diff --git a/src/noggit/Model.h b/src/noggit/Model.h index e6556e32..1d51c832 100755 --- a/src/noggit/Model.h +++ b/src/noggit/Model.h @@ -151,6 +151,7 @@ public: void toggle_visibility() { _hidden = !_hidden; } void show() { _hidden = false ; } + void hide() { _hidden = true; } [[nodiscard]] bool use_fake_geometry() const { return !!_fake_geometry; } diff --git a/src/noggit/Selection.h b/src/noggit/Selection.h index 2f018526..f56bb400 100755 --- a/src/noggit/Selection.h +++ b/src/noggit/Selection.h @@ -50,3 +50,20 @@ enum eSelectionEntryTypes using selection_entry = std::pair; using selection_result = std::vector; + +struct selection_group +{ + selection_group() + { + }; + + void add_member(selected_object_type); + + void set_selected_as_group(std::vector selection); + + void copy_group(); // create and save a new selection group from copied objects + + std::vector object_members; // uids + + std::array extents; +}; \ No newline at end of file diff --git a/src/noggit/WMO.h b/src/noggit/WMO.h index a417deae..17e1d49d 100755 --- a/src/noggit/WMO.h +++ b/src/noggit/WMO.h @@ -347,6 +347,8 @@ public: void toggle_visibility() { _hidden = !_hidden; } void show() { _hidden = false ; } + void hide() { _hidden = true; } + [[nodiscard]] bool is_required_when_saving() const override diff --git a/src/noggit/World.cpp b/src/noggit/World.cpp index dca85e63..a78f4069 100755 --- a/src/noggit/World.cpp +++ b/src/noggit/World.cpp @@ -1012,7 +1012,7 @@ void World::clearAllModelsOnADT(TileIndex const& tile) { ZoneScoped; _model_instance_storage.delete_instances_from_tile(tile); - update_models_by_filename(); + // update_models_by_filename(); } void World::CropWaterADT(const TileIndex& pos) @@ -1638,7 +1638,7 @@ void World::unload_every_model_and_wmo_instance() _model_instance_storage.clear(); - _models_by_filename.clear(); + // _models_by_filename.clear(); } void World::addM2 ( BlizzardArchive::Listfile::FileKey const& file_key @@ -1687,7 +1687,7 @@ void World::addM2 ( BlizzardArchive::Listfile::FileKey const& file_key std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true); - _models_by_filename[file_key.filepath()].push_back(_model_instance_storage.get_model_instance(uid).value()); + // _models_by_filename[file_key.filepath()].push_back(_model_instance_storage.get_model_instance(uid).value()); } ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key @@ -1695,6 +1695,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c , float scale , math::degrees::vec3 rotation , Noggit::object_paste_params* paste_params + , bool ignore_params ) { ZoneScoped; @@ -1705,7 +1706,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c model_instance.scale = scale; model_instance.dir = rotation; - if (paste_params) + if (paste_params && !ignore_params) { if (_settings->value("model/random_rotation", false).toBool()) { @@ -1737,7 +1738,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true); auto instance = _model_instance_storage.get_model_instance(uid).value(); - _models_by_filename[file_key.filepath()].push_back(instance); + // _models_by_filename[file_key.filepath()].push_back(instance); return instance; } @@ -1823,11 +1824,11 @@ void World::remove_models_if_needed(std::vector const& uids) { reset_selection(); } - + /* if (uids.size()) { update_models_by_filename(); - } + }*/ } void World::reload_tile(TileIndex const& tile) @@ -2715,7 +2716,7 @@ std::unordered_set& World::vertexBorderChunks() } return _vertex_border_chunks; } - +/* void World::update_models_by_filename() { ZoneScoped; @@ -2730,7 +2731,7 @@ void World::update_models_by_filename() need_model_updates = false; } - +*/ void World::range_add_to_selection(glm::vec3 const& pos, float radius, bool remove) { ZoneScoped; diff --git a/src/noggit/World.h b/src/noggit/World.h index 5cee621c..426caaf5 100755 --- a/src/noggit/World.h +++ b/src/noggit/World.h @@ -58,9 +58,10 @@ class World protected: std::vector _current_selection; - std::unordered_map> _models_by_filename; + // std::unordered_map> _models_by_filename; Noggit::world_model_instances_storage _model_instance_storage; Noggit::world_tile_update_queue _tile_update_queue; + std::vector< selection_group> _selection_groups; public: MapIndex mapIndex; @@ -126,6 +127,8 @@ public: bool has_selection() const { return !_current_selection.empty(); } bool has_multiple_model_selected() const { return _selected_model_count > 1; } int get_selected_model_count() const { return _selected_model_count; } + // Unused in Red, models are now iterated by adt because of the occlusion check + // std::unordered_map> get_models_by_filename() const& { return _models_by_filename; } void set_current_selection(selection_type entry); void add_to_selection(selection_type entry); void remove_from_selection(selection_type entry); @@ -279,6 +282,7 @@ public: , glm::vec3 newPos , float scale, math::degrees::vec3 rotation , Noggit::object_paste_params* + , bool ignore_params = false ); WMOInstance* addWMOAndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key @@ -386,7 +390,7 @@ public: ); protected: - void update_models_by_filename(); + // void update_models_by_filename(); std::unordered_set& vertexBorderChunks(); diff --git a/src/noggit/rendering/WorldRender.cpp b/src/noggit/rendering/WorldRender.cpp index 921f4711..97716c32 100755 --- a/src/noggit/rendering/WorldRender.cpp +++ b/src/noggit/rendering/WorldRender.cpp @@ -613,11 +613,11 @@ void WorldRender::draw (glm::mat4x4 const& model_view { ModelManager::resetAnim(); } - + /* if (_world->need_model_updates) { _world->update_models_by_filename(); - } + }*/ std::unordered_map model_boxes_to_draw; diff --git a/src/noggit/ui/ObjectEditor.cpp b/src/noggit/ui/ObjectEditor.cpp index 70fc857a..9a9dc87e 100755 --- a/src/noggit/ui/ObjectEditor.cpp +++ b/src/noggit/ui/ObjectEditor.cpp @@ -55,7 +55,7 @@ namespace Noggit , helper_models_widget(new helper_models(this)) , _settings (new QSettings (this)) , _copy_model_stats (true) - , selected() + , _model_instance_created() , pasteMode(PASTE_ON_TERRAIN) , _map_view(mapView) { @@ -104,7 +104,7 @@ namespace Noggit QPushButton* object_palette_btn = new QPushButton("Object palette", this); layout->addWidget(object_palette_btn); - _wmo_group = new QGroupBox("WMO Options"); + _wmo_group = new QGroupBox("Selected WMO Options"); auto wmo_layout = new QFormLayout(_wmo_group); _doodadSetSelector = new QComboBox(this); @@ -114,6 +114,16 @@ namespace Noggit wmo_layout->addRow("Doodad Set:", _doodadSetSelector); wmo_layout->addRow("Name Set:", _nameSetSelector); + auto clipboard_box = new QGroupBox("Clipboard"); + auto clipboard_layout = new QVBoxLayout(clipboard_box); + + _filename = new QLabel(this); + _filename->setWordWrap(true); + _filename->setText("Empty (0 objects copied)"); + layout->addWidget(clipboard_box); + + clipboard_layout->addWidget(_filename); + auto *copyBox = new ExpanderWidget( this); copyBox->setExpanderTitle("Copy options"); copyBox->setExpanded(_settings->value ("object_editor/copy_options", false).toBool()); @@ -146,9 +156,6 @@ namespace Noggit QDoubleSpinBox *scaleRangeStart = new QDoubleSpinBox(this); QDoubleSpinBox *scaleRangeEnd = new QDoubleSpinBox(this); - _filename = new QLabel (this); - _filename->setWordWrap (true); - rotRangeStart->setMaximumWidth(85); rotRangeEnd->setMaximumWidth(85); tiltRangeStart->setMaximumWidth(85); @@ -281,7 +288,8 @@ namespace Noggit selectionOptions_layout->addWidget(multi_select_movement_box); QPushButton *rotEditorButton = new QPushButton("Pos/Rotation Editor", this); - QPushButton *visToggleButton = new QPushButton("Toggle Hidden Models Visibility", this); + // replaced by a button + // QPushButton *visToggleButton = new QPushButton("Toggle Hidden Models Visibility", this); QPushButton *clearListButton = new QPushButton("Clear Hidden Models List", this); auto importBox = new ExpanderWidget(this); @@ -309,10 +317,10 @@ namespace Noggit layout->addWidget(pasteBox); layout->addWidget(selectionOptionsBox); layout->addWidget(rotEditorButton); - layout->addWidget(visToggleButton); + // layout->addWidget(visToggleButton); layout->addWidget(clearListButton); layout->addWidget(importBox); - layout->addWidget(_filename); + // layout->addWidget(_filename); rotationEditor->use_median_pivot_point = &_use_median_pivot_point; @@ -469,11 +477,12 @@ namespace Noggit connect(rotEditorButton, &QPushButton::clicked, [=]() { rotationEditor->show(); }); - + /* connect(visToggleButton, &QPushButton::clicked, [=]() { mapView->_draw_hidden_models.set (!mapView->_draw_hidden_models.get()); }); + */ connect(clearListButton, &QPushButton::clicked, [=]() { ModelManager::clear_hidden_models(); @@ -574,7 +583,7 @@ namespace Noggit { auto last_entry = world->get_last_selected_model(); - for (auto& selection : selected) + for (auto& selection : _model_instance_created) { glm::vec3 pos; @@ -676,23 +685,23 @@ namespace Noggit pasteModeGroup->button ((pasteMode + 1) % PASTE_MODE_COUNT)->setChecked (true); } - void object_editor::replace_selection(std::vector new_selection) + void object_editor::update_clipboard() { - selected = new_selection; + // _model_instance_created = new_selection; std::stringstream ss; - if (selected.empty()) + if (_model_instance_created.empty()) { - _filename->setText(""); + _filename->setText("Empty (0 objects copied)"); return; } - if (selected.size() == 1) + if (_model_instance_created.size() == 1) { ss << "Model: "; - auto selectedObject = new_selection.front(); + auto selectedObject = _model_instance_created.front(); if (selectedObject.index() == eEntry_Object) { ss << std::get(selectedObject)->instance_model()->file_key().filepath(); @@ -705,7 +714,7 @@ namespace Noggit } else { - ss << "Multiple objects selected"; + ss << _model_instance_created.size() << " objects selected"; } _filename->setText(ss.str().c_str()); @@ -724,7 +733,8 @@ namespace Noggit return; } - std::vector selected_model; + // std::vector selected_model; + _model_instance_created.clear(); if (filename.ends_with(".m2")) { @@ -732,8 +742,8 @@ namespace Noggit _model_instance_created.push_back(mi); - selected_model.push_back(mi); - replace_selection(selected_model); + // selected_model.push_back(mi); + update_clipboard(); } else if (filename.ends_with(".wmo")) { @@ -741,8 +751,8 @@ namespace Noggit _model_instance_created.push_back(wi); - selected_model.push_back(wi); - replace_selection(selected_model); + // selected_model.push_back(wi); + update_clipboard(); } } @@ -756,7 +766,8 @@ namespace Noggit return; } - std::vector selected_model; + // std::vector selected_model; + _model_instance_created.clear(); for (auto& selection : current_selection) { @@ -776,7 +787,7 @@ namespace Noggit clone->dir = original->dir; clone->pos = pivot ? original->pos - pivot.value() : glm::vec3(); - selected_model.push_back(clone); + // selected_model.push_back(clone); _model_instance_created.push_back(clone); } else if (obj->which() == eWMO) @@ -786,11 +797,11 @@ namespace Noggit clone->dir = original->dir; clone->pos = pivot ? original->pos - pivot.value() : glm::vec3(); - selected_model.push_back(clone); + // selected_model.push_back(clone); _model_instance_created.push_back(clone); } } - replace_selection(selected_model); + update_clipboard(); } void object_editor::SaveObjecttoTXT (World* world) @@ -875,7 +886,7 @@ namespace Noggit return QSize(215, height()); } - void object_editor::update_selection(World* world) + void object_editor::update_selection_ui(World* world) { _wmo_group->setDisabled(true); _wmo_group->hide(); diff --git a/src/noggit/ui/ObjectEditor.h b/src/noggit/ui/ObjectEditor.h index ac0f6a29..b4f2c0c4 100755 --- a/src/noggit/ui/ObjectEditor.h +++ b/src/noggit/ui/ObjectEditor.h @@ -82,12 +82,16 @@ namespace Noggit float drag_selection_depth() const { return _drag_selection_depth; } + int clipboardSize() const { return _model_instance_created.size(); } + + std::vector getClipboard() const& { return _model_instance_created; } + model_import *modelImport; rotation_editor* rotationEditor; helper_models* helper_models_widget; QSize sizeHint() const override; - void update_selection(World* world); + void update_selection_ui(World* world); private: float _radius = 0.01f; @@ -112,10 +116,10 @@ namespace Noggit bool _copy_model_stats; bool _use_median_pivot_point; - std::vector selected; + // std::vector selected; std::vector _model_instance_created; - void replace_selection(std::vector new_selection); + void update_clipboard(); void showImportModels(); void SaveObjecttoTXT (World*); diff --git a/src/noggit/ui/object_palette.cpp b/src/noggit/ui/object_palette.cpp index b9b86ea1..4960d4ae 100755 --- a/src/noggit/ui/object_palette.cpp +++ b/src/noggit/ui/object_palette.cpp @@ -111,7 +111,7 @@ namespace Noggit _add_button = new QPushButton(this); _add_button->setIcon(FontAwesomeIcon(FontAwesome::plus)); button_layout->addWidget(_add_button); - connect(_add_button, &QAbstractButton::clicked, this, &ObjectPalette::addObject); + connect(_add_button, &QAbstractButton::clicked, this, &ObjectPalette::addObjectFromAssetBrowser); _remove_button = new QPushButton(this); _remove_button->setIcon(FontAwesomeIcon(FontAwesome::times)); @@ -125,7 +125,7 @@ namespace Noggit } - void ObjectPalette::addObject() + void ObjectPalette::addObjectFromAssetBrowser() { std::string const& display_name = reinterpret_cast( diff --git a/src/noggit/ui/object_palette.hpp b/src/noggit/ui/object_palette.hpp index 554f925e..fafee085 100755 --- a/src/noggit/ui/object_palette.hpp +++ b/src/noggit/ui/object_palette.hpp @@ -48,7 +48,7 @@ namespace Noggit ObjectPalette(MapView* map_view, QWidget* parent); ~ObjectPalette(); - void addObject(); + void addObjectFromAssetBrowser(); void addObjectByFilename(QString const& filename); void removeObject(QString filename);