1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Handles viewport editing in console mode */
19 
20 #ifndef INC_C4EditCursor
21 #define INC_C4EditCursor
22 
23 #include "control/C4Control.h"
24 #include "lib/C4Rect.h"
25 #include "object/C4DefGraphics.h"
26 #include "object/C4ObjectList.h"
27 #include "script/C4Value.h"
28 
29 
30 // Currently selected elements in editcursor. May be objects and other prop lists.
31 class C4EditCursorSelection : public std::list<C4Value>
32 {
33 public:
34 	StdStrBuf GetDataString() const; // Return a string like "n objects".
35 	C4Object *GetObject(int32_t index=0) const; // Get indexed C4Object * in list
36 	C4Object *GetLastObject() const;
37 	void ConsolidateEmpty(); // remove nullptred entries that may happen because objects got deleted
38 	bool ClearPointers(C4Object *obj);
39 	bool IsContained(C4PropList *obj) const;
40 	int32_t ObjectCount() const; // count only C4Object *
41 };
42 
43 class C4EditCursor
44 {
45 public:
46 	C4EditCursor();
47 	~C4EditCursor();
48 
49 protected:
50 	bool fAltWasDown;
51 	bool fShiftWasDown;
52 	bool has_mouse_hover;
53 	bool selection_invalid; // if true, the property list should be updated on next execution
54 	int32_t Mode;
55 	float X,Y,X2,Y2,Zoom;
56 	bool Hold,DragFrame,DragLine,DragShape,DragTransform;
57 	int32_t DragRot0, DragCon0, DragRotLast, DragConLast;
58 	C4Object *Target,*DropTarget;
59 	C4Value highlighted_object;
60 	class C4Def *creator_def;
61 	std::unique_ptr<C4GraphicsOverlay> creator_overlay;
62 	struct ObjselItemDt {
63 		C4EditCursor* EditCursor;
64 		C4Object* Object;
65 		StdCopyStrBuf Command;
66 #if defined(USE_WIN32_WINDOWS)
67 		UINT_PTR ItemId;
68 #endif
69 	};
70 	std::vector<ObjselItemDt> itemsObjselect;
71 #ifdef USE_WIN32_WINDOWS
72 	HMENU hMenu;
73 #endif
74 	// Selection may either be any number of objects or a single non-object prop list
75 	C4EditCursorSelection selection;
76 #ifdef WITH_QT_EDITOR
77 	std::unique_ptr<class C4ConsoleQtShapes> shapes;
78 #endif
79 public:
80 	void Default();
81 	void Clear();
82 	void Execute();
83 	void ClearPointers(C4Object *pObj);
84 	bool ToggleMode();
85 	void Draw(C4TargetFacet &cgo);
86 	int32_t GetMode();
87 	C4Object* GetTarget();
88 	bool SetMode(int32_t iMode);
89 	bool In(const char *szText);
90 	bool Duplicate();
91 	bool OpenPropTools();
92 	bool Delete();
93 	void GrabContents();
94 	bool LeftButtonUp(DWORD dwKeyState);
95 	bool LeftButtonDown(DWORD dwKeyState);
96 	bool RightButtonUp(DWORD dwKeyState);
97 	bool RightButtonDown(DWORD dwKeyState);
98 	bool KeyDown(C4KeyCode KeyCode, DWORD dwKeyState);
99 	bool KeyUp(C4KeyCode KeyCode, DWORD dwKeyState);
100 	bool Move(float iX, float iY, float zoom, DWORD dwKeyState);
101 	bool Move(DWORD new_key_state);
102 	bool Init();
103 	bool EditingOK(bool for_landscape_drawing=false);
GetSelection()104 	C4EditCursorSelection &GetSelection() { return selection; }
SetHold(bool fToState)105 	void SetHold(bool fToState) { Hold = fToState; }
106 	void OnSelectionChanged(bool by_objectlist=false);
107 	bool AltDown();
108 	bool AltUp();
SetMouseHover(bool h)109 	void SetMouseHover(bool h) { has_mouse_hover = h; }
110 #ifdef WITH_QT_EDITOR
GetShapes()111 	class C4ConsoleQtShapes *GetShapes() const { return shapes.get(); }
112 #endif
HasTransformCursor()113 	bool HasTransformCursor() const { return DragTransform || IsHoveringTransformMarker(); }
114 	bool IsHoveringTransformMarker() const;
115 protected:
116 	void UpdateStatusBar();
117 	void ApplyCreateObject(bool contained);
118 	void ApplyToolPicker();
119 	void ToolFailure();
120 	void PutContents();
121 	void UpdateDropTarget(DWORD dwKeyState);
122 	bool DoContextMenu(DWORD dwKeyState);
123 	void AppendMenuItem(int num, const StdStrBuf & label);
124 	void ApplyToolFill();
125 	void ApplyToolRect();
126 	void ApplyToolLine();
127 	void ApplyToolBrush();
128 	void DrawObject(C4TargetFacet &cgo, C4Object *cobj, uint32_t select_mark_color, bool highlight, bool draw_transform_marker);
129 	void DrawSelectMark(C4Facet &cgo, FLOAT_RECT r, float width, uint32_t color = 0xffffffff);
130 	bool HasTransformMarker(float *x, float *y, float zoom) const;
131 	void FrameSelection();
132 	void MoveSelection(C4Real iXOff, C4Real iYOff, bool drag_finished);
133 	void EMMoveObject(enum C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj, const C4EditCursorSelection *pObjs = nullptr, const char *szScript = nullptr, bool drag_finished = false);
134 	void DoContextObjCommand(C4Object *, const char *cmd);
135 	void ObjselectDelItems();
136 
137 public:
138 	void DoContextObjsel(C4Object *, bool clear);
139 	void PerformDuplication(int32_t *object_numbers, int32_t object_count, bool local_call);
140 	void PerformDuplicationLegacy(int32_t *pObjects, int32_t iObjectNum, bool fLocalCall);
141 
142 protected:
143 public:
144 	void AddToSelection(C4PropList *add_obj);         // add object to selection and do script callback. Doesn't do OnSelectionChanged().
145 	bool RemoveFromSelection(C4PropList *remove_obj); // remove object from selection and do script callback. return true if object was in selection before. Doesn't do OnSelectionChanged().
146 	void ClearSelection(C4PropList *next_selection=nullptr);  // remove all objects from selection and do script callback. if next_selection is non-null, passes that to the deselection callbacks. Doesn't do OnSelectionChanged().
147 	// Type of object to create in object creation mode
SetCreatorDef(C4Def * new_def)148 	void SetCreatorDef(C4Def *new_def) { creator_def = new_def; creator_overlay.reset(nullptr); }
GetCreatorDef()149 	C4Def *GetCreatorDef() { return creator_def; }
150 
151 	void EMControl(enum C4PacketType eCtrlType, class C4ControlPacket *pCtrl);
InvalidateSelection()152 	void InvalidateSelection() { selection_invalid = true; }
ValidateSelection()153 	void ValidateSelection() { selection_invalid = false; }
IsSelectionInvalidated()154 	bool IsSelectionInvalidated() const { return selection_invalid; }
155 	bool GetCurrentSelectionPosition(int32_t *x, int32_t *y); // return center of first selected object
156 	void SetHighlightedObject(C4Object *new_highlight);
157 };
158 
159 #endif
160