guiEditCtrl.h
Engine/source/gui/editor/guiEditCtrl.h
Classes:
class
Native side of the GUI editor.
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _GUIEDITCTRL_H_ 25#define _GUIEDITCTRL_H_ 26 27#ifndef _GUICONTROL_H_ 28 #include "gui/core/guiControl.h" 29#endif 30#ifndef _UNDO_H_ 31 #include "util/undo.h" 32#endif 33#ifndef _GFX_GFXDRAWER_H_ 34 #include "gfx/gfxDrawUtil.h" 35#endif 36 37 38/// Native side of the GUI editor. 39class GuiEditCtrl : public GuiControl 40{ 41 public: 42 43 typedef GuiControl Parent; 44 friend class GuiEditorRuler; 45 46 enum Justification 47 { 48 JUSTIFY_LEFT, 49 JUSTIFY_CENTER_VERTICAL, 50 JUSTIFY_RIGHT, 51 JUSTIFY_TOP, 52 JUSTIFY_BOTTOM, 53 SPACING_VERTICAL, 54 SPACING_HORIZONTAL, 55 JUSTIFY_CENTER_HORIZONTAL, 56 }; 57 58 enum guideAxis { GuideVertical, GuideHorizontal }; 59 60 enum mouseModes { Selecting, MovingSelection, SizingSelection, DragSelecting, DragGuide, DragClone }; 61 enum sizingModes { sizingNone = 0, sizingLeft = 1, sizingRight = 2, sizingTop = 4, sizingBottom = 8 }; 62 63 enum snappingAxis { SnapVertical, SnapHorizontal }; 64 enum snappingEdges { SnapEdgeMin, SnapEdgeMid, SnapEdgeMax }; 65 66 protected: 67 68 enum 69 { 70 NUT_SIZE = 4, 71 MIN_GRID_SIZE = 3 72 }; 73 74 typedef Vector< GuiControl*> GuiControlVector; 75 typedef SimObjectPtr< GuiControl> GuiControlPtr; 76 77 bool mDrawBorderLines; 78 bool mDrawGuides; 79 bool mFullBoxSelection; 80 GuiControlVector mSelectedControls; 81 GuiControlPtr mCurrentAddSet; 82 GuiControlPtr mContentControl; 83 Point2I mLastMousePos; 84 Point2I mLastDragPos; 85 Point2I mSelectionAnchor; 86 Point2I mGridSnap; 87 Point2I mDragBeginPoint; 88 Vector<Point2I> mDragBeginPoints; 89 bool mDragAddSelection; 90 bool mDragMoveUndo; 91 92 // Guides. 93 94 bool mSnapToGuides; ///< If true, edge and center snapping will work against guides. 95 bool mDragGuide[ 2 ]; 96 U32 mDragGuideIndex[ 2 ];///< Indices of the guide's being dragged in DragGuide mouse mode. 97 Vector< U32> mGuides[ 2 ]; ///< The guides defined on the current content control. 98 99 // Snapping 100 101 bool mSnapToControls; ///< If true, edge and center snapping will work against controls. 102 bool mSnapToCanvas; ///< If true, edge and center snapping will work against canvas (= content control). 103 bool mSnapToEdges; ///< If true, selection edges will snap to other control edges. 104 bool mSnapToCenters; ///< If true, selection centers will snap to other control centers. 105 S32 mSnapSensitivity; ///< Snap distance in pixels. 106 107 bool mSnapped[ 2 ]; ///< Snap flag for each axis. If true, we are currently snapped in a drag. 108 S32 mSnapOffset[ 2 ]; ///< Reference point on snap line for each axis. 109 GuiControlVector mSnapHits[ 2 ]; ///< Hit testing lists for each axis. 110 snappingEdges mSnapEdge[ 2 ]; ///< Identification of edge being snapped for each axis. 111 GuiControlPtr mSnapTargets[ 2 ]; ///< Controls providing the snap reference lines on each axis. 112 113 // Undo 114 SimGroup* mTrash; 115 SimSet* mSelectedSet; 116 117 // grid drawing 118 GFXVertexBufferHandle<GFXVertexPCT> mDots; 119 GFXStateBlockRef mDotSB; 120 121 mouseModes mMouseDownMode; 122 sizingModes mSizingMode; 123 124 static StringTableEntry smGuidesPropertyName[ 2 ]; 125 126 // private methods 127 void updateSelectedSet(); 128 129 S32 findGuide( guideAxis axis, const Point2I& point, U32 tolerance = 0 ); 130 131 RectI getSnapRegion( snappingAxis axis, const Point2I& center ) const; 132 void findSnaps( snappingAxis axis, const Point2I& mousePoint, const RectI& minRegion, const RectI& midRegion, const RectI& maxRegion ); 133 void registerSnap( snappingAxis axis, const Point2I& mousePoint, const Point2I& point, snappingEdges edge, GuiControl* ctrl = NULL ); 134 135 void doSnapping( const GuiEvent& event, const RectI& selectionBounds, Point2I& delta ); 136 void doGuideSnap( const GuiEvent& event, const RectI& selectionBounds, const RectI& selectionBoundsGlobal, Point2I& delta ); 137 void doControlSnap( const GuiEvent& event, const RectI& selectionBounds, const RectI& selectionBoundsGlobal, Point2I& delta ); 138 void doGridSnap( const GuiEvent& event, const RectI& selectionBounds, const RectI& selectionBoundsGlobal, Point2I& delta ); 139 void snapToGrid( Point2I& point ); 140 141 void startDragMove( const Point2I& startPoint ); 142 void startDragRectangle( const Point2I& startPoint ); 143 void startDragClone( const Point2I& startPoint ); 144 void startMouseGuideDrag( guideAxis axis, U32 index, bool lockMouse = true ); 145 146 void setMouseMode( mouseModes mode ); 147 148 /// @name Callbacks 149 /// @{ 150 151 DECLARE_CALLBACK( void, onHierarchyChanged, () ); 152 DECLARE_CALLBACK( void, onDelete, () ); 153 DECLARE_CALLBACK( void, onPreEdit, ( SimSet* selection ) ); 154 DECLARE_CALLBACK( void, onPostEdit, ( SimSet* selection ) ); 155 DECLARE_CALLBACK( void, onClearSelected, () ); 156 DECLARE_CALLBACK( void, onSelect, ( GuiControl* control ) ); 157 DECLARE_CALLBACK( void, onAddSelected, ( GuiControl* control ) ); 158 DECLARE_CALLBACK( void, onRemoveSelected, ( GuiControl* control ) ); 159 DECLARE_CALLBACK( void, onPreSelectionNudged, ( SimSet* selection ) ); 160 DECLARE_CALLBACK( void, onPostSelectionNudged, ( SimSet* selection ) ); 161 DECLARE_CALLBACK( void, onSelectionMoved, ( GuiControl* control ) ); //FIXME: this should be a selection SimSet 162 DECLARE_CALLBACK( void, onSelectionCloned, ( SimSet* selection ) ); 163 DECLARE_CALLBACK( void, onTrashSelection, ( SimSet* selection ) ); 164 DECLARE_CALLBACK( void, onAddNewCtrl, ( GuiControl* control ) ); 165 DECLARE_CALLBACK( void, onAddNewCtrlSet, ( SimSet* set ) ); 166 DECLARE_CALLBACK( void, onSelectionResized, ( GuiControl* control ) ); 167 DECLARE_CALLBACK( void, onFitIntoParent, ( bool width, bool height ) ); 168 DECLARE_CALLBACK( void, onMouseModeChange, () ); 169 DECLARE_CALLBACK( void, onControlInspectPreApply, ( GuiControl* control ) ); 170 DECLARE_CALLBACK( void, onControlInspectPostApply, ( GuiControl* control ) ); 171 172 /// @} 173 174 static bool inNut( const Point2I &pt, S32 x, S32 y ) 175 { 176 S32 dx = pt.x - x; 177 S32 dy = pt.y - y; 178 return dx <= NUT_SIZE && dx >= -NUT_SIZE && dy <= NUT_SIZE && dy >= -NUT_SIZE; 179 } 180 181 static void drawCrossSection( U32 axis, S32 offset, const RectI& bounds, ColorI color, GFXDrawUtil* drawer ) 182 { 183 Point2I start; 184 Point2I end; 185 186 if( axis == 0 ) 187 { 188 start.x = end.x = offset; 189 start.y = bounds.point.y; 190 end.y = bounds.point.y + bounds.extent.y - 1; 191 } 192 else 193 { 194 start.y = end.y = offset; 195 start.x = bounds.point.x; 196 end.x = bounds.point.x + bounds.extent.x - 1; 197 } 198 199 drawer->drawLine( start, end, color ); 200 } 201 202 static void snapDelta( snappingAxis axis, snappingEdges edge, S32 offset, const RectI& bounds, Point2I& delta ) 203 { 204 switch( axis ) 205 { 206 case SnapVertical: 207 switch( edge ) 208 { 209 case SnapEdgeMin: 210 delta.x = offset - bounds.point.x; 211 break; 212 213 case SnapEdgeMid: 214 delta.x = offset - bounds.point.x - bounds.extent.x / 2; 215 break; 216 217 case SnapEdgeMax: 218 delta.x = offset - bounds.point.x - bounds.extent.x + 1; 219 break; 220 } 221 break; 222 223 case SnapHorizontal: 224 switch( edge ) 225 { 226 case SnapEdgeMin: 227 delta.y = offset - bounds.point.y; 228 break; 229 230 case SnapEdgeMid: 231 delta.y = offset - bounds.point.y - bounds.extent.y / 2; 232 break; 233 234 case SnapEdgeMax: 235 delta.y = offset - bounds.point.y - bounds.extent.y + 1; 236 break; 237 } 238 break; 239 } 240 } 241 242 public: 243 244 GuiEditCtrl(); 245 246 DECLARE_CONOBJECT(GuiEditCtrl); 247 DECLARE_CATEGORY( "Gui Editor" ); 248 DECLARE_DESCRIPTION( "Implements the framework for the GUI editor." ); 249 250 bool onWake(); 251 void onSleep(); 252 253 static void initPersistFields(); 254 255 GuiControl* getContentControl() const { return mContentControl; } 256 void setContentControl(GuiControl *ctrl); 257 void setEditMode(bool value); 258 S32 getSizingHitKnobs(const Point2I &pt, const RectI &box); 259 void getDragRect(RectI &b); 260 void drawNut(const Point2I &nut, ColorI &outlineColor, ColorI &nutColor); 261 void drawNuts(RectI &box, ColorI &outlineColor, ColorI &nutColor); 262 void onPreRender(); 263 void onRender(Point2I offset, const RectI &updateRect); 264 void addNewControl(GuiControl *ctrl); 265 void setCurrentAddSet(GuiControl *ctrl, bool clearSelection = true); 266 GuiControl* getCurrentAddSet(); 267 268 // Selections. 269 270 void select( GuiControl *ctrl ); 271 bool selectionContains( GuiControl *ctrl ); 272 bool selectionContainsParentOf( GuiControl* ctrl ); 273 void setSelection( GuiControl *ctrl, bool inclusive = false ); 274 RectI getSelectionBounds() const; 275 RectI getSelectionGlobalBounds() const; 276 void canHitSelectedControls( bool state = true ); 277 void justifySelection( Justification j ); 278 void moveSelection( const Point2I &delta, bool callback = true ); 279 void moveAndSnapSelection( const Point2I &delta, bool callback = true ); 280 void saveSelection( const char *filename ); 281 void loadSelection( const char *filename ); 282 void addSelection( S32 id ); 283 void addSelection( GuiControl* ctrl ); 284 void removeSelection( S32 id ); 285 void removeSelection( GuiControl* ctrl ); 286 void deleteSelection(); 287 void clearSelection(); 288 void selectAll(); 289 void bringToFront(); 290 void pushToBack(); 291 void moveSelectionToCtrl( GuiControl* ctrl, bool callback = true ); 292 void addSelectControlsInRegion( const RectI& rect, U32 hitTestFlags = 0 ); 293 void addSelectControlAt( const Point2I& pos ); 294 void resizeControlsInSelectionBy( const Point2I& delta, U32 mode ); 295 void fitIntoParents( bool width = true, bool height = true ); 296 void selectParents( bool addToSelection = false ); 297 void selectChildren( bool addToSelection = false ); 298 void cloneSelection(); 299 U32 getNumSelected() const { return mSelectedControls.size(); } 300 301 // Guides. 302 303 U32 addGuide( guideAxis axis, U32 offset ) { U32 index = mGuides[ axis ].size(); mGuides[ axis ].push_back( offset ); return index; } 304 void readGuides( guideAxis axis, GuiControl* ctrl ); 305 void writeGuides( guideAxis axis, GuiControl* ctrl ); 306 void clearGuides( guideAxis axis ) { mGuides[ axis ].clear(); } 307 308 // Undo Access. 309 310 void undo(); 311 void redo(); 312 313 // When a control is changed by the inspector 314 void controlInspectPreApply(GuiControl* object); 315 void controlInspectPostApply(GuiControl* object); 316 317 // Sizing Cursors 318 void getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent); 319 320 U32 getSelectionSize() const { return mSelectedControls.size(); } 321 const Vector<GuiControl*>& getSelected() const { return mSelectedControls; } 322 SimSet* getSelectedSet() { updateSelectedSet(); return mSelectedSet; } 323 SimGroup* getTrash() { return mTrash; } 324 GuiControl* getAddSet() const { return mCurrentAddSet; }; //JDD 325 326 bool onKeyDown(const GuiEvent &event); 327 void onMouseDown(const GuiEvent &event); 328 void onMouseUp(const GuiEvent &event); 329 void onMouseDragged(const GuiEvent &event); 330 void onRightMouseDown(const GuiEvent &event); 331 332 mouseModes getMouseMode() const { return mMouseDownMode; } 333 334 virtual bool onAdd(); 335 virtual void onRemove(); 336 337 void setSnapToGrid(U32 gridsize); 338}; 339 340#endif //_GUI_EDIT_CTRL_H 341