Torque3D Documentation / _generateds / guiRectHandles.cpp

guiRectHandles.cpp

Engine/source/gui/editor/guiRectHandles.cpp

More...

Public Functions

ConsoleDocClass(GuiRectHandles , "@brief Draws <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> box with handles <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the user <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">manipulate.\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )

Detailed Description

Public Functions

ConsoleDocClass(GuiRectHandles , "@brief Draws <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> box with handles <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the user <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">manipulate.\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )

IMPLEMENT_CONOBJECT(GuiRectHandles )

  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#include "console/console.h"
 25#include "console/consoleTypes.h"
 26#include "console/engineAPI.h"
 27#include "gfx/gfxDevice.h"
 28#include "gfx/gfxDrawUtil.h"
 29
 30#include "gui/editor/guiRectHandles.h"
 31
 32IMPLEMENT_CONOBJECT(GuiRectHandles);
 33
 34ConsoleDocClass( GuiRectHandles,
 35   "@brief Draws a box with handles for the user to manipulate.\n\n"
 36   "Editor use only.\n\n"
 37   "@internal"
 38);
 39
 40//--------------------------------------------------------------------------
 41GuiRectHandles::GuiRectHandles() : GuiControl()
 42{
 43   mHandleRect.set(0.0f, 0.0f, 1.0f, 1.0f);
 44   mHandleSize = 10;
 45   mUseCustomColor = false;
 46   mHandleColor.set(100,100,100);
 47   mHitHandle = 0;
 48}
 49
 50GuiRectHandles::~GuiRectHandles()
 51{
 52}
 53
 54//--------------------------------------------------------------------------
 55void GuiRectHandles::initPersistFields()
 56{
 57   addField("handleRect",     TypeRectF,  Offset(mHandleRect,  GuiRectHandles),     "RectF of handle's box." );
 58   addField("handleSize",     TypeS32,    Offset(mHandleSize,  GuiRectHandles),     "Size of handles in pixels." );
 59   addField("useCustomColor", TypeBool,   Offset(mUseCustomColor,  GuiRectHandles), "Use given custom color for handles." );
 60   addField("handleColor",    TypeColorI, Offset(mHandleColor,  GuiRectHandles),    "Use given custom color for handles." );
 61
 62   Parent::initPersistFields();
 63}
 64
 65//--------------------------------------------------------------------------
 66
 67void GuiRectHandles::onMouseUp(const GuiEvent &event)
 68{
 69   mHitHandle = 0;
 70}
 71
 72void GuiRectHandles::onMouseDown(const GuiEvent &event)
 73{
 74   // The handles range from 0-1, so scale to fit within the
 75   // control's bounds.
 76   const Point2I& extent = getExtent();
 77   Point2I pos(extent.x*mHandleRect.point.x, extent.y*mHandleRect.point.y);
 78   Point2I size(extent.x*mHandleRect.extent.x, extent.y*mHandleRect.extent.y);
 79   RectI box(pos, size);
 80
 81   Point2I localMousePoint = globalToLocalCoord(event.mousePoint);
 82
 83   // Check if mouse is within handle rect
 84   if(!box.pointInRect(localMousePoint))
 85   {
 86      mHitHandle = 0;
 87      return;
 88   }
 89
 90   Point2I normalizedMouse = localMousePoint - pos;
 91   Point2I halfSize = size / 2;
 92   S32 halfHandleSize = mHandleSize / 2;
 93   if(normalizedMouse.y < mHandleSize)
 94   {
 95      // Top handles
 96      if(normalizedMouse.x < mHandleSize)
 97         mHitHandle = 1;
 98      else if(normalizedMouse.x >= (size.x-mHandleSize))
 99         mHitHandle = 3;
100      else if(normalizedMouse.x >= (halfSize.x-halfHandleSize) && normalizedMouse.x < (halfSize.x+halfHandleSize))
101         mHitHandle = 2;
102   }
103   else if(normalizedMouse.y >= (size.y-mHandleSize))
104   {
105      // Bottom handles
106      if(normalizedMouse.x < mHandleSize)
107         mHitHandle = 7;
108      else if(normalizedMouse.x >= (size.x-mHandleSize))
109         mHitHandle = 5;
110      else if(normalizedMouse.x >= (halfSize.x-halfHandleSize) && normalizedMouse.x < (halfSize.x+halfHandleSize))
111         mHitHandle = 6;
112   }
113   else if(normalizedMouse.y >= (halfSize.y-halfHandleSize) && normalizedMouse.y < (halfSize.y+halfHandleSize))
114   {
115      // Middle handles
116      if(normalizedMouse.x < mHandleSize)
117         mHitHandle = 8;
118      else if(normalizedMouse.x >= (size.x-mHandleSize))
119         mHitHandle = 4;
120      else if(normalizedMouse.x >= (halfSize.x-halfHandleSize) && normalizedMouse.x < (halfSize.x+halfHandleSize))
121         mHitHandle = 9;
122   }
123
124   mHitPoint = localMousePoint;
125}
126
127void GuiRectHandles::onMouseDragged(const GuiEvent &event)
128{
129   if(mHitHandle == 0)
130      return;
131
132   // The handles range from 0-1, so scale to fit within the
133   // control's bounds.
134   const Point2I& extent = getExtent();
135
136   Point2I localMousePoint = globalToLocalCoord(event.mousePoint);
137
138   Point2I diffI = localMousePoint - mHitPoint;
139   Point2F diffF(diffI.x/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(extent.x), diffI.y/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(extent.y));
140
141   RectF box(mHandleRect);
142   bool postMoveExtentX = false;
143   bool postMoveExtentY = false;
144   bool keepExtent = false;
145
146   switch(mHitHandle)
147   {
148      case 1:
149      {
150         // Top left
151         box.point += diffF;
152         postMoveExtentX = true;
153         postMoveExtentY = true;
154         break;
155      }
156
157      case 2:
158      {
159         // Top middle
160         box.point.y += diffF.y;
161         postMoveExtentY = true;
162         break;
163      }
164
165      case 3:
166      {
167         // Top right
168         box.point.y += diffF.y;
169         box.extent.x += diffF.x;
170         postMoveExtentY = true;
171         break;
172      }
173
174      case 4:
175      {
176         // Middle right
177         box.extent.x += diffF.x;
178         break;
179      }
180
181      case 5:
182      {
183         // Bottom right
184         box.extent += diffF;
185         break;
186      }
187
188      case 6:
189      {
190         // Bottom middle
191         box.extent.y += diffF.y;
192         break;
193      }
194
195      case 7:
196      {
197         // Bottom left
198         box.point.x += diffF.x;
199         box.extent.y += diffF.y;
200         postMoveExtentX = true;
201         break;
202      }
203
204      case 8:
205      {
206         // Middle left
207         box.point.x += diffF.x;
208         postMoveExtentX = true;
209         break;
210      }
211
212      case 9:
213      {
214         // Centre
215         box.point += diffF;
216         keepExtent = true;
217         break;
218      }
219
220      default:
221         break;
222   }
223
224   // Position limits
225   if(box.point.x < 0.0f)
226      box.point.x = 0.0f;
227   else if(box.point.x > 1.0f)
228      box.point.x = 1.0f;
229
230   if(box.point.y < 0.0f)
231      box.point.y = 0.0f;
232   else if(box.point.y > 1.0f)
233      box.point.y = 1.0f;
234
235   // Move any extent to counter a change in handle position.  Do this
236   // after the limits above to make sure the extent doesn't accidentally
237   // grow when the position is clamped.
238   if(postMoveExtentX)
239      box.extent.x += mHandleRect.point.x - box.point.x;
240   if(postMoveExtentY)
241      box.extent.y += mHandleRect.point.y - box.point.y;
242
243   // Extent limits
244   if(box.extent.x < 0.0f)
245      box.extent.x = 0.0f;
246   else if(box.extent.x > 1.0f)
247      box.extent.x = 1.0f;
248   if(box.point.x+box.extent.x > 1.0f)
249   {
250      if(keepExtent)
251         box.point.x = 1.0f-box.extent.x;
252      else
253         box.extent.x = 1.0f-box.point.x;
254   }
255
256   if(box.extent.y < 0.0f)
257      box.extent.y = 0.0f;
258   else if(box.extent.y > 1.0f)
259      box.extent.y = 1.0f;
260   if(box.point.y+box.extent.y > 1.0f)
261   {
262      if(keepExtent)
263         box.point.y = 1.0f-box.extent.y;
264      else
265         box.extent.y = 1.0f-box.point.y;
266   }
267
268   mHandleRect = box;
269   mHitPoint = localMousePoint;
270
271   if( isMethod( "onHandleRectChange" ) )
272      Con::executef(this, "onHandleRectChange" );
273}
274
275//--------------------------------------------------------------------------
276void GuiRectHandles::onRender(Point2I offset, const RectI &updateRect)
277{
278   Parent::onRender( offset, updateRect );
279
280   ColorI handleColor = mProfile->mBorderColor;
281   if(mUseCustomColor)
282      handleColor = mHandleColor;
283
284   // The handles range from 0-1, so scale to fit within the
285   // control's bounds.
286   const Point2I& extent = getExtent();
287   Point2I pos(extent.x*mHandleRect.point.x, extent.y*mHandleRect.point.y);
288   Point2I size(extent.x*mHandleRect.extent.x, extent.y*mHandleRect.extent.y);
289   RectI box(offset+pos, size);
290
291   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
292
293   // Draw border
294   drawUtil->drawRect(box, handleColor);
295
296   // Draw each handle
297   Point2I handleSize(mHandleSize, mHandleSize);
298   RectI handleRect(box.point, handleSize);
299   drawUtil->drawRectFill(handleRect, handleColor);      // Upper left
300   handleRect.point = Point2I(box.point.x+size.x-handleSize.x, box.point.y);
301   drawUtil->drawRectFill(handleRect, handleColor);      // Upper right
302   handleRect.point = Point2I(box.point.x, box.point.y+size.y-handleSize.y);
303   drawUtil->drawRectFill(handleRect, handleColor);      // Lower left
304   handleRect.point = Point2I(box.point.x+size.x-handleSize.x, box.point.y+size.y-handleSize.y);
305   drawUtil->drawRectFill(handleRect, handleColor);      // Lower right
306
307   Point2I halfSize = size / 2;
308   Point2I halfHandleSize = handleSize / 2;
309   handleRect.point = Point2I(box.point.x+halfSize.x-halfHandleSize.x, box.point.y);
310   drawUtil->drawRectFill(handleRect, handleColor);      // Upper middle
311   handleRect.point = Point2I(box.point.x+halfSize.x-halfHandleSize.x, box.point.y+size.y-handleSize.y);
312   drawUtil->drawRectFill(handleRect, handleColor);      // Lower middle
313   handleRect.point = Point2I(box.point.x, box.point.y+halfSize.y-halfHandleSize.y);
314   drawUtil->drawRectFill(handleRect, handleColor);      // Left middle
315   handleRect.point = Point2I(box.point.x+size.x-handleSize.x, box.point.y+halfSize.y-halfHandleSize.y);
316   drawUtil->drawRectFill(handleRect, handleColor);      // Right middle
317
318   handleRect.point = Point2I(box.point.x+halfSize.x-halfHandleSize.x, box.point.y+halfSize.y-halfHandleSize.y);
319   drawUtil->drawRectFill(handleRect, handleColor);      // Middle
320
321   renderChildControls(offset, updateRect);
322}
323