1 #pragma once
2 
3 #include "lc_context.h"
4 #include "lc_math.h"
5 #include "lc_commands.h"
6 
7 enum class lcDragState
8 {
9 	None,
10 	Piece,
11 	Color
12 };
13 
14 enum class lcCursor
15 {
16 	First,
17 	Hidden = First,
18 	Default,
19 	Brick,
20 	Light,
21 	Spotlight,
22 	Camera,
23 	Select,
24 	SelectAdd,
25 	SelectRemove,
26 	Move,
27 	Rotate,
28 	RotateX,
29 	RotateY,
30 	Delete,
31 	Paint,
32 	ColorPicker,
33 	Zoom,
34 	ZoomRegion,
35 	Pan,
36 	Roll,
37 	RotateView,
38 	Count
39 };
40 
41 enum class lcTrackButton
42 {
43 	None,
44 	Left,
45 	Middle,
46 	Right
47 };
48 
49 enum class lcTrackTool
50 {
51 	None,
52 	Insert,
53 	PointLight,
54 	SpotLight,
55 	Camera,
56 	Select,
57 	MoveX,
58 	MoveY,
59 	MoveZ,
60 	MoveXY,
61 	MoveXZ,
62 	MoveYZ,
63 	MoveXYZ,
64 	RotateX,
65 	RotateY,
66 	RotateZ,
67 	RotateXY,
68 	RotateXYZ,
69 	ScalePlus,
70 	ScaleMinus,
71 	Eraser,
72 	Paint,
73 	ColorPicker,
74 	Zoom,
75 	Pan,
76 	OrbitX,
77 	OrbitY,
78 	OrbitXY,
79 	Roll,
80 	ZoomRegion,
81 	Count
82 };
83 
84 enum class lcViewType
85 {
86 	View,
87 	Preview,
88 	Minifig,
89 	PartsList,
90 	Count
91 };
92 
93 struct lcFindReplaceParams
94 {
95 	PieceInfo* FindInfo = nullptr;
96 	QString FindString;
97 	int FindColorIndex = 0;
98 	PieceInfo* ReplacePieceInfo = nullptr;
99 	int ReplaceColorIndex = 0;
100 };
101 
102 class lcView : public QObject
103 {
104 	Q_OBJECT
105 
106 public:
107 	lcView(lcViewType ViewType, lcModel* Model);
108 	~lcView();
109 
110 	lcView(const lcView&) = delete;
111 	lcView& operator=(const lcView&) = delete;
112 
GetFindReplaceParams()113 	static lcFindReplaceParams& GetFindReplaceParams()
114 	{
115 		return mFindReplaceParams;
116 	}
117 
GetModel()118 	lcModel* GetModel() const
119 	{
120 		return mModel;
121 	}
122 
GetViewType()123 	lcViewType GetViewType() const
124 	{
125 		return mViewType;
126 	}
127 
GetCamera()128 	lcCamera* GetCamera() const
129 	{
130 		return mCamera;
131 	}
132 
IsLastFocused()133 	bool IsLastFocused() const
134 	{
135 		return mLastFocusedView == this;
136 	}
137 
IsTracking()138 	bool IsTracking() const
139 	{
140 		return mTrackButton != lcTrackButton::None;
141 	}
142 
GetWidth()143 	int GetWidth() const
144 	{
145 		return mWidth;
146 	}
147 
GetHeight()148 	int GetHeight() const
149 	{
150 		return mHeight;
151 	}
152 
SetSize(int Width,int Height)153 	void SetSize(int Width, int Height)
154 	{
155 		mWidth = Width;
156 		mHeight = Height;
157 	}
158 
GetWidget()159 	lcViewWidget* GetWidget() const
160 	{
161 		return mWidget;
162 	}
163 
SetWidget(lcViewWidget * Widget)164 	void SetWidget(lcViewWidget* Widget)
165 	{
166 		mWidget = Widget;
167 	}
168 
GetMouseX()169 	int GetMouseX() const
170 	{
171 		return mMouseX;
172 	}
173 
GetMouseY()174 	int GetMouseY() const
175 	{
176 		return mMouseY;
177 	}
178 
SetBackgroundColorOverride(quint32 BackgroundColor)179 	void SetBackgroundColorOverride(quint32 BackgroundColor)
180 	{
181 		mOverrideBackgroundColor = true;
182 		mBackgroundColor = BackgroundColor;
183 	}
184 
185 	static std::vector<lcView*> GetModelViews(const lcModel* Model);
186 	static void UpdateProjectViews(const Project* Project);
187 	static void UpdateAllViews();
188 
189 	static void CreateResources(lcContext* Context);
190 	static void DestroyResources(lcContext* Context);
191 
192 	void MakeCurrent();
193 	void Redraw();
194 
195 	void SetOffscreenContext();
196 
197 	void SetFocus(bool Focus);
198 	void SetMousePosition(int MouseX, int MouseY);
199 	void SetMouseModifiers(Qt::KeyboardModifiers MouseModifiers);
200 
201 	lcModel* GetActiveModel() const;
202 	void SetTopSubmodelActive();
203 	void SetSelectedSubmodelActive();
204 
205 	void OnDraw();
206 	void OnLeftButtonDown();
207 	void OnLeftButtonUp();
208 	void OnLeftButtonDoubleClick();
209 	void OnMiddleButtonDown();
210 	void OnMiddleButtonUp();
211 	void OnRightButtonDown();
212 	void OnRightButtonUp();
213 	void OnBackButtonDown();
214 	void OnBackButtonUp();
215 	void OnForwardButtonDown();
216 	void OnForwardButtonUp();
217 	void OnMouseMove();
218 	void OnMouseWheel(float Direction);
219 	void BeginDrag(lcDragState DragState);
220 	void EndDrag(bool Accept);
221 
222 	void UpdateCursor();
223 	void StartOrbitTracking();
224 	void CancelTrackingOrClearSelection();
225 
226 	void SetViewpoint(lcViewpoint Viewpoint);
227 	void SetViewpoint(const lcVector3& Position);
228 	void SetViewpoint(const lcVector3& Position, const lcVector3& Target, const lcVector3& Up);
229 	void SetCameraAngles(float Latitude, float Longitude);
230 	void SetDefaultCamera();
231 	void SetCamera(lcCamera* Camera, bool ForceCopy);
232 	void SetCamera(const QString& CameraName);
233 	void SetCameraIndex(int Index);
234 
235 	void SetProjection(bool Ortho);
236 	void LookAt();
237 	void MoveCamera(const lcVector3& Direction);
238 	void Zoom(float Amount);
239 	void ZoomExtents();
240 
241 	void RemoveCamera();
242 	void ShowContextMenu() const;
243 	bool CloseFindReplaceDialog();
244 	void ShowFindReplaceWidget(bool Replace);
245 
246 	lcVector3 GetMoveDirection(const lcVector3& Direction) const;
247 	lcMatrix44 GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) const;
248 	lcVector3 GetCameraLightInsertPosition() const;
249 	void GetRayUnderPointer(lcVector3& Start, lcVector3& End) const;
250 	lcObjectSection FindObjectUnderPointer(bool PiecesOnly, bool IgnoreSelected) const;
251 	lcArray<lcObject*> FindObjectsInBox(float x1, float y1, float x2, float y2) const;
252 
253 	bool BeginRenderToImage(int Width, int Height);
254 	void EndRenderToImage();
255 	QImage GetRenderImage() const;
256 	void BindRenderFramebuffer();
257 	void UnbindRenderFramebuffer();
258 	QImage GetRenderFramebufferImage() const;
259 	std::vector<QImage> GetStepImages(lcStep Start, lcStep End);
260 	void SaveStepImages(const QString& BaseName, bool AddStepSuffix, lcStep Start, lcStep End, std::function<void(const QString&)> ProgressCallback);
261 
262 	lcContext* mContext = nullptr;
263 
264 signals:
265 	void FocusReceived();
266 	void CameraChanged();
267 
268 protected:
269 	static void CreateSelectMoveOverlayMesh(lcContext* Context);
270 
271 	void DrawBackground() const;
272 	void DrawViewport() const;
273 	void DrawAxes() const;
274 
275 	void DrawSelectMoveOverlay();
276 	void DrawRotateOverlay();
277 	void DrawSelectZoomRegionOverlay();
278 	void DrawRotateViewOverlay();
279 	void DrawGrid();
280 
281 	lcVector3 ProjectPoint(const lcVector3& Point) const;
282 	lcVector3 UnprojectPoint(const lcVector3& Point) const;
283 	void UnprojectPoints(lcVector3* Points, int NumPoints) const;
284 	lcMatrix44 GetProjectionMatrix() const;
285 	lcMatrix44 GetTileProjectionMatrix(int CurrentRow, int CurrentColumn, int CurrentTileWidth, int CurrentTileHeight) const;
286 
287 	lcCursor GetCursor() const;
288 	void SetCursor(lcCursor Cursor);
289 	lcTool GetCurrentTool() const;
290 	void UpdateTrackTool();
291 	bool IsTrackToolAllowed(lcTrackTool TrackTool, quint32 AllowedTransforms) const;
292 	lcTrackTool GetOverrideTrackTool(Qt::MouseButton Button) const;
293 	float GetOverlayScale() const;
294 	void StartTracking(lcTrackButton TrackButton);
295 	void StopTracking(bool Accept);
296 	void OnButtonDown(lcTrackButton TrackButton);
297 
298 	lcViewWidget* mWidget = nullptr;
299 	int mWidth = 1;
300 	int mHeight = 1;
301 	bool mDeleteContext = true;
302 	lcViewType mViewType;
303 
304 	int mMouseX = 0;
305 	int mMouseY = 0;
306 	int mMouseDownX = 0;
307 	int mMouseDownY = 0;
308 	Qt::KeyboardModifiers mMouseModifiers = Qt::NoModifier;
309 
310 	bool mTrackUpdated = false;
311 	bool mToolClicked = false;
312 	lcTrackTool mTrackTool = lcTrackTool::None;
313 	lcTrackButton mTrackButton = lcTrackButton::None;
314 	lcCursor mCursor = lcCursor::Default;
315 
316 	lcDragState mDragState;
317 	bool mTrackToolFromOverlay;
318 	lcVector3 mMouseDownPosition;
319 	PieceInfo* mMouseDownPiece;
320 
321 	QImage mRenderImage;
322 	std::unique_ptr<QOpenGLFramebufferObject> mRenderFramebuffer;
323 	bool mOverrideBackgroundColor = false;
324 	quint32 mBackgroundColor = 0;
325 
326 	std::unique_ptr<lcScene> mScene;
327 	std::unique_ptr<lcViewSphere> mViewSphere;
328 
329 	lcModel* mModel = nullptr;
330 	lcPiece* mActiveSubmodelInstance = nullptr;
331 	lcMatrix44 mActiveSubmodelTransform;
332 
333 	lcCamera* mCamera = nullptr;
334 
335 	lcVertexBuffer mGridBuffer;
336 	int mGridSettings[7];
337 
338 	static lcFindReplaceWidget* mFindWidget;
339 	static lcFindReplaceParams mFindReplaceParams;
340 
341 	static lcView* mLastFocusedView;
342 	static std::vector<lcView*> mViews;
343 
344 	static lcVertexBuffer mRotateMoveVertexBuffer;
345 	static lcIndexBuffer mRotateMoveIndexBuffer;
346 };
347