Ticket #96: copypaste.diff
File copypaste.diff, 17.4 KB (added by , 10 years ago) |
---|
-
source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp index 57b4734..8f1d507 100644
a b 19 19 20 20 #include "ScenarioEditor.h" 21 21 22 #include <vector> 23 22 24 #include "wx/busyinfo.h" 23 25 #include "wx/config.h" 24 26 #include "wx/dir.h" … … 28 30 #include "wx/image.h" 29 31 #include "wx/sysopt.h" 30 32 #include "wx/tooltip.h" 33 #include <sstream> 31 34 32 35 #include "General/AtlasEventLoop.h" 33 36 #include "General/Datafile.h" … … 44 47 45 48 #include "Misc/KeyMap.h" 46 49 47 #include "Tools/Common/Tools.h"48 50 #include "Tools/Common/Brushes.h" 49 51 #include "Tools/Common/MiscState.h" 52 #include "Tools/Common/PasteObjectSettings.h" 53 #include "Tools/Common/Tools.h" 50 54 51 55 static HighResTimer g_Timer; 52 56 … … BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame) 340 344 EVT_MENU(ID_Quit, ScenarioEditor::OnQuit) 341 345 EVT_MENU(wxID_UNDO, ScenarioEditor::OnUndo) 342 346 EVT_MENU(wxID_REDO, ScenarioEditor::OnRedo) 347 EVT_MENU(wxID_COPY, ScenarioEditor::OnCopy) 348 EVT_MENU(wxID_CUT, ScenarioEditor::OnCut) 349 EVT_MENU(wxID_PASTE, ScenarioEditor::OnPaste) 343 350 344 351 EVT_MENU(ID_Wireframe, ScenarioEditor::OnWireframe) 345 352 EVT_MENU(ID_MessageTrace, ScenarioEditor::OnMessageTrace) … … ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac 436 443 { 437 444 menuEdit->Append(wxID_UNDO, _("&Undo")); 438 445 menuEdit->Append(wxID_REDO, _("&Redo")); 446 menuEdit->AppendSeparator(); 447 menuEdit->Append(wxID_COPY, _("&Copy")); 448 menuEdit->Append(wxID_CUT, _("Cut")); 449 menuEdit->Append(wxID_PASTE, _("&Paste")); 439 450 } 440 451 441 452 GetCommandProc().SetEditMenu(menuEdit); … … void ScenarioEditor::OnRedo(wxCommandEvent&) 622 633 GetCommandProc().Redo(); 623 634 } 624 635 636 637 void ScenarioEditor::OnCopy(wxCommandEvent& event) 638 { 639 if (g_SelectedObjects.empty()) 640 { 641 wxLogWarning(_("Nothing to copy!")); 642 return; 643 } 644 645 AtlasMessage::qGetXmlForObjects qry(g_SelectedObjects); 646 qry.Post(); 647 648 wxLogWarning(wxString(qry.xml.c_str())); 649 } 650 651 void ScenarioEditor::OnCut(wxCommandEvent& event) 652 { 653 } 654 655 void ScenarioEditor::OnPaste(wxCommandEvent& event) 656 { 657 std::vector<PasteObjectSettings> objects; 658 659 PasteObjectSettings object1; 660 object1.templateName = L"gaia/fauna_bear"; 661 object1.atlasSettings.player = 1; 662 object1.pasteRelativePosition.type1.x = 100; 663 object1.pasteRelativePosition.type1.y = 0; 664 objects.push_back(object1); 665 666 PasteObjectSettings object2; 667 object2.templateName = L"gaia/fauna_bear"; 668 object2.atlasSettings.player = 1; 669 object2.pasteRelativePosition.type1.x = 0; 670 object2.pasteRelativePosition.type1.y = 0; 671 objects.push_back(object2); 672 673 GetToolManager().SetCurrentTool(_T("PasteObjects"), &objects); 674 } 675 625 676 ////////////////////////////////////////////////////////////////////////// 626 677 627 678 void ScenarioEditor::OnNew(wxCommandEvent& WXUNUSED(event)) -
source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h index c3a6b38..ae054e4 100644
a b public: 48 48 void OnQuit(wxCommandEvent& event); 49 49 void OnUndo(wxCommandEvent& event); 50 50 void OnRedo(wxCommandEvent& event); 51 void OnCopy(wxCommandEvent& event); 52 void OnCut(wxCommandEvent& event); 53 void OnPaste(wxCommandEvent& event); 51 54 52 55 void OnWireframe(wxCommandEvent& event); 53 56 void OnMessageTrace(wxCommandEvent& event); -
new file source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/PasteObjectSettings.h
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/PasteObjectSettings.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/PasteObjectSettings.h new file mode 100644 index 0000000..1a4cabc
- + 1 /* Copyright (C) 2012 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_PASTEOBJECTSETTINGS 19 #define INCLUDED_PASTEOBJECTSETTINGS 20 21 #include <string> 22 23 #include "GameInterface/Messages.h" 24 25 namespace AtlasMessage 26 { 27 struct sObjectSettings; 28 } 29 30 struct PasteObjectSettings 31 { 32 AtlasMessage::Position pasteRelativePosition; 33 AtlasMessage::Position position; 34 AtlasMessage::Position target; 35 unsigned int actorSeed; 36 std::wstring templateName; 37 AtlasMessage::sObjectSettings atlasSettings; 38 }; 39 40 #endif // INCLUDED_PASTEOBJECTSETTINGS 41 -
new file source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PasteObjects.cpp
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PasteObjects.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PasteObjects.cpp new file mode 100644 index 0000000..dbc5919
- + 1 /* Copyright (C) 2013 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "precompiled.h" 19 20 #include <vector> 21 22 #include "ScenarioEditor/ScenarioEditor.h" 23 #include "Common/Tools.h" 24 #include "Common/Brushes.h" 25 #include "Common/MiscState.h" 26 #include "Common/ObjectSettings.h" 27 #include "Common/PasteObjectSettings.h" 28 #include "GameInterface/Messages.h" 29 30 using AtlasMessage::Position; 31 32 static float g_DefaultAngle = (float)(M_PI*3.0/4.0); 33 34 35 class PasteObjects : public StateDrivenTool<PasteObjects> 36 { 37 DECLARE_DYNAMIC_CLASS(PasteObjects); 38 39 Position m_ScreenPos, m_ObjPos, m_Target; 40 wxString m_ObjectID; 41 unsigned int m_ActorSeed; 42 43 std::vector<PasteObjectSettings> m_objectsToPaste; 44 45 public: 46 PasteObjects() 47 { 48 SetState(&Waiting); 49 } 50 51 void SendObjectMsg(bool preview) 52 { 53 int dragDistSq = 54 (m_ScreenPos.type1.x-m_Target.type1.x)*(m_ScreenPos.type1.x-m_Target.type1.x) 55 + (m_ScreenPos.type1.y-m_Target.type1.y)*(m_ScreenPos.type1.y-m_Target.type1.y); 56 bool useTarget = (dragDistSq >= 16*16); 57 58 for (std::vector<PasteObjectSettings>::iterator it = m_objectsToPaste.begin(); it != m_objectsToPaste.end(); ++it) 59 { 60 PasteObjectSettings & object = *it; 61 if (preview) 62 { 63 POST_MESSAGE(ObjectPreview, (object.templateName, object.atlasSettings, object.position, 64 useTarget, object.target, g_DefaultAngle, object.actorSeed)); 65 } 66 else 67 { 68 POST_COMMAND(CreateObject, (object.templateName, object.atlasSettings, object.position, 69 useTarget, object.target, g_DefaultAngle, object.actorSeed)); 70 RandomizeActorSeed(); 71 } 72 } 73 } 74 75 virtual void Init(void* initData, ScenarioEditor* scenarioEditor) 76 { 77 StateDrivenTool<PasteObjects>::Init(initData, scenarioEditor); 78 79 wxASSERT(initData); 80 m_objectsToPaste = *static_cast<std::vector<PasteObjectSettings>*>(initData); 81 SendObjectMsg(true); 82 } 83 84 void OnEnable() 85 { 86 RandomizeActorSeed(); 87 } 88 89 void OnDisable() 90 { 91 m_ObjectID = _T(""); 92 SendObjectMsg(true); 93 } 94 95 /* 96 Object placement: 97 * Select unit from list 98 * Move mouse around screen; preview of unit follows mouse 99 * Left mouse down -> remember position, fix preview to point 100 * Mouse move -> if moved > [limit], rotate unit to face mouse; else default orientation 101 * Left mouse release -> finalise placement of object on map 102 103 * Page up/down -> rotate default orientation 104 105 * Escape -> cancel placement tool 106 107 TOOD: what happens if somebody saves while the preview is active? 108 */ 109 110 bool OnMouseOverride(wxMouseEvent& WXUNUSED(evt)) 111 { 112 // This used to let the scroll-wheel rotate units, but that overrides 113 // the camera zoom and makes navigation very awkward, so it doesn't 114 // any more. 115 return false; 116 } 117 118 bool OnKeyOverride(wxKeyEvent& evt, KeyEventType type) 119 { 120 if (type == KEY_CHAR && evt.GetKeyCode() == WXK_ESCAPE) 121 { 122 SetState(&Disabled); 123 return true; 124 } 125 else 126 return false; 127 } 128 129 void RotateTick(float dt) 130 { 131 int dir = 0; 132 if (wxGetKeyState(WXK_PAGEDOWN)) ++dir; // page-down key 133 if (wxGetKeyState(WXK_PAGEUP)) --dir; // page-up key 134 if (dir) 135 { 136 float speed = M_PI/2.f * ScenarioEditor::GetSpeedModifier(); // radians per second 137 g_DefaultAngle += (dir * dt * speed); 138 SendObjectMsg(true); 139 } 140 } 141 142 void RandomizeActorSeed() 143 { 144 m_ActorSeed = (unsigned int)floor((rand() / (float)RAND_MAX) * 65535.f); 145 } 146 147 struct sWaiting : public State 148 { 149 bool OnMouse(PasteObjects* obj, wxMouseEvent& evt) 150 { 151 if (obj->OnMouseOverride(evt)) 152 { 153 return true; 154 } 155 else if (evt.LeftDown()) 156 { 157 obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target = Position(evt.GetPosition()); 158 obj->SendObjectMsg(true); 159 obj->m_ObjPos = Position::Unchanged(); // make sure object is stationary even if the camera moves 160 SET_STATE(Placing); 161 return true; 162 } 163 else if (evt.Moving()) 164 { 165 for (std::vector<PasteObjectSettings>::iterator it = obj->m_objectsToPaste.begin(); it != obj->m_objectsToPaste.end(); ++it) 166 { 167 (*it).position = Position(evt.GetPosition()); 168 (*it).position.type1.x += (*it).pasteRelativePosition.type1.x; 169 (*it).position.type1.y += (*it).pasteRelativePosition.type1.y; 170 (*it).target = (*it).position; 171 obj->SendObjectMsg(true); 172 } 173 return true; 174 } 175 else 176 { 177 return false; 178 } 179 } 180 181 bool OnKey(PasteObjects* obj, wxKeyEvent& evt, KeyEventType type) 182 { 183 if (type == KEY_CHAR && (evt.GetKeyCode() >= '0' && evt.GetKeyCode() <= '9')) 184 { 185 int playerID = evt.GetKeyCode() - '0'; 186 obj->GetScenarioEditor().GetObjectSettings().SetPlayerID(playerID); 187 obj->GetScenarioEditor().GetObjectSettings().NotifyObservers(); 188 obj->SendObjectMsg(true); 189 return true; 190 } 191 else 192 return obj->OnKeyOverride(evt, type); 193 } 194 void OnTick(PasteObjects* obj, float dt) 195 { 196 obj->RotateTick(dt); 197 } 198 } 199 Waiting; 200 201 struct sPlacing : public State 202 { 203 bool OnMouse(PasteObjects* obj, wxMouseEvent& evt) 204 { 205 if (obj->OnMouseOverride(evt)) 206 return true; 207 else if (evt.LeftUp()) 208 { 209 obj->m_Target = Position(evt.GetPosition()); 210 // Create the actual object 211 obj->SendObjectMsg(false); 212 // Go back to preview mode 213 SET_STATE(Waiting); 214 obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target; 215 obj->SendObjectMsg(true); 216 return true; 217 } 218 else if (evt.Dragging()) 219 { 220 obj->m_Target = Position(evt.GetPosition()); 221 obj->SendObjectMsg(true); 222 return true; 223 } 224 else 225 return false; 226 } 227 bool OnKey(PasteObjects* obj, wxKeyEvent& evt, KeyEventType type) 228 { 229 return obj->OnKeyOverride(evt, type); 230 } 231 void OnTick(PasteObjects* obj, float dt) 232 { 233 obj->RotateTick(dt); 234 } 235 } 236 Placing; 237 }; 238 239 IMPLEMENT_DYNAMIC_CLASS(PasteObjects, StateDrivenTool<PasteObjects>); -
source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
diff --git a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp index ea36267..12eba27 100644
a b 38 38 #include "ps/CLogger.h" 39 39 #include "ps/Game.h" 40 40 #include "ps/World.h" 41 #include "ps/XML/XMLWriter.h" 41 42 #include "renderer/Renderer.h" 42 43 #include "renderer/WaterManager.h" 43 44 #include "simulation2/Simulation2.h" … … QUERYHANDLER(GetObjectsList) 95 96 } 96 97 97 98 99 QUERYHANDLER(GetXmlForObjects) 100 { 101 std::string xml; 102 103 std::vector<AtlasMessage::ObjectID> objects = *msg->objects; 104 105 CSimulation2 & simulation = *g_Game->GetSimulation2(); 106 107 XML_Start(); 108 XML_Element("Entities"); 109 110 CSimulation2::InterfaceList ents = simulation.GetEntitiesWithInterface(IID_Position); 111 for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it) 112 { 113 entity_id_t uid = it->first; 114 if (objects.end() != std::find(objects.begin(), objects.end(), uid)) 115 { 116 XML_Element("Entity"); 117 XML_Attribute("uid", uid); 118 119 objects.erase(std::remove(objects.begin(), objects.end(), uid), objects.end()); 120 } 121 } 122 123 xml = XML_GetOutput().EscapeToPrintableASCII(); 124 125 std::wstring wxml(xml.begin(), xml.end()); 126 127 msg->xml = wxml; 128 } 129 98 130 static std::vector<entity_id_t> g_Selection; 99 131 typedef std::map<player_id_t, CColor> PlayerColorMap; 100 132 … … MESSAGEHANDLER(ObjectPreview) 366 398 } 367 399 } 368 400 401 MESSAGEHANDLER(PasteObjectPreview) 402 { 403 if (g_PreviewEntityID != INVALID_ENTITY) 404 { 405 // Update the unit's position and orientation: 406 407 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), g_PreviewEntityID); 408 if (cmpPosition) 409 { 410 CVector3D pos = GetUnitPos(msg->pos, cmpPosition->IsFloating()); 411 cmpPosition->JumpTo(entity_pos_t::FromFloat(pos.X), entity_pos_t::FromFloat(pos.Z)); 412 413 float angle; 414 if (msg->usetarget) 415 { 416 // Aim from pos towards msg->target 417 CVector3D target = msg->target->GetWorldSpace(pos.Y); 418 angle = atan2(target.X-pos.X, target.Z-pos.Z); 419 } 420 else 421 { 422 angle = msg->angle; 423 } 424 425 cmpPosition->SetYRotation(entity_angle_t::FromFloat(angle)); 426 } 427 428 // TODO: handle random variations somehow 429 430 CmpPtr<ICmpVisual> cmpVisual(*g_Game->GetSimulation2(), g_PreviewEntityID); 431 if (cmpVisual) 432 cmpVisual->SetActorSeed(msg->actorseed); 433 434 CmpPtr<ICmpOwnership> cmpOwnership(*g_Game->GetSimulation2(), g_PreviewEntityID); 435 if (cmpOwnership) 436 cmpOwnership->SetOwner((player_id_t)msg->settings->player); 437 } 438 } 439 369 440 BEGIN_COMMAND(CreateObject) 370 441 { 371 442 CVector3D m_Pos; -
source/tools/atlas/GameInterface/Messages.h
diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index 48ce280..2a1431b 100644
a b QUERY(GetObjectsList, 320 320 ((std::vector<sObjectsListItem>, objects)) // sorted by .name 321 321 ); 322 322 323 QUERY(GetXmlForObjects, 324 ((std::vector<AtlasMessage::ObjectID>, objects)) 325 , 326 ((std::wstring, xml)) 327 ); 328 323 329 #ifndef MESSAGES_SKIP_STRUCTS 324 330 struct sObjectSettings 325 331 { … … MESSAGE(ObjectPreview, 346 352 ((unsigned int, actorseed)) 347 353 ); 348 354 355 MESSAGE(PasteObjectPreview, 356 ((std::wstring, id)) // or empty string => disable 357 ((sObjectSettings, settings)) 358 ((Position, pos)) 359 ((bool, usetarget)) // true => use 'target' for orientation; false => use 'angle' 360 ((Position, target)) 361 ((float, angle)) 362 ((unsigned int, actorseed)) 363 ); 364 349 365 COMMAND(CreateObject, NOMERGE, 350 366 ((std::wstring, id)) 351 367 ((sObjectSettings, settings)) … … MESSAGE(SetActorViewer, 366 382 ((bool, flushcache)) // true => unload all actor files before starting the preview (because we don't have proper hotloading yet) 367 383 ); 368 384 385 369 386 ////////////////////////////////////////////////////////////////////////// 370 387 371 388 QUERY(Exit,,); // no inputs nor outputs