00001
00009 #ifndef OglGui_SizableWindow_h
00010 #define OglGui_SizableWindow_h
00011
00012 #ifndef OglGui_Window_h
00013 #include "OglGui/Window.h"
00014 #endif
00015
00016
00017
00018 namespace OglGui
00019 {
00020
00021 class SizableWindow : public Window
00022 {
00023 public:
00024
00025 SizableWindow(Window *parent, int w, int h, bool is2D=true) :
00026 Window(parent, w, h, is2D)
00027 {
00028 Init();
00029 }
00030
00031 SizableWindow(Window *parent, int x, int y, int w, int h, bool is2D=true) :
00032 Window(parent, x, y, w, h, is2D)
00033 {
00034 Init();
00035 }
00036
00037 enum ActionBits {
00038 North = 1,
00039 East = 2,
00040 NorthEast = 3,
00041 South = 4,
00042 NorthSouth = 5,
00043 SouthEast = 6,
00044 West = 8,
00045 NorthWest = 9,
00046 EastWest = 10,
00047 SouthWest = 12,
00048 Move = 16,
00049 AllDir = 15
00050 };
00051
00052
00053 bool IsTopWindowInParent()
00054 {
00055 LIST *obj = mOglWnd->parent->wndList;
00056
00057 if (!obj)
00058 return false;
00059
00060 while(obj->next)
00061 obj = obj->next;
00062
00063 return obj->info == mOglWnd;
00064 }
00065
00066
00067 virtual void BringToFront()
00068 {
00069 oglSys.BringToFront(mOglWnd);
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 }
00081
00082 virtual void DisplayFunc()
00083 {
00084 Window::DisplayFunc();
00085 Window::SetBorderType(mHighLight?mHighLightBorderType:mNormalBorderType);
00086
00087 if (mAllowHighLight && mHighLight)
00088 {
00089 float r0, r1, r2, r3;
00090 int w = mOglWnd->width, h = mOglWnd->height;
00091 int brd = mHighLightInset;
00092 OGC myOGC;
00093
00094 OGCSave(&myOGC);
00095 SetSolidLineColor(mStateFeedbackColor);
00096 if (GetRoundness(r0, r1, r2, r3))
00097 DrawRoundRectExt(brd, brd, w - 2*brd, h - 2*brd, r0,r1,r2,r3);
00098 else
00099 DrawRectangle(brd, brd, w - 2*brd, h - 2*brd);
00100 OGCRestore(&myOGC);
00101 }
00102 }
00103
00104 virtual void MouseFunc(int msg, int but, int state, int x, int y)
00105 {
00106 int theAction = 0;
00107 if (!mActOnModifier || !(state&mActOnModifier))
00108 Window::MouseFunc(msg, but, state, x, y);
00109 if (mActOnModifier && (mOglWnd->dragging || !(state&mActOnModifier)))
00110 {
00111 mHighLight = false;
00112 SetActionCursor(mAction = 0);
00113 return;
00114 }
00115 if (msg==oglMouseDown && !(state&oglControl) &&
00116 (mToFrontOnMouseDown && !IsTopWindowInParent()))
00117 BringToFront();
00118
00119 if (mAction && msg == oglMouseUp)
00120 mAction = 0;
00121
00122 if (msg == oglMouseLeave)
00123 {
00124 mHighLight = false;
00125 oglSys.SetCursor(oglCursorArrow);
00126 }
00127
00128 if (msg == oglMouseDown && but == oglLeftButton)
00129 {
00130 mDx = x;
00131 mDy = y;
00132 if (theAction = GetAction(x, y))
00133 mAction |= theAction;
00134 }
00135
00136 if (mAction)
00137 mHighLight = true;
00138
00139 if (msg == oglMouseMove)
00140 mHighLight = (mAction != 0) || (theAction = GetAction(x, y));
00141
00142 if (mAction && msg == oglMouseMove )
00143 PerformAction(x, y);
00144
00145 SetActionCursor(theAction | mAction);
00146 }
00147
00148
00150
00151 void ActOnModifier(int state) { mActOnModifier = state; }
00152 int ActOnModifier() { return mActOnModifier; }
00153 void SetToFrontOnMouseDown(bool m=true) { mToFrontOnMouseDown = m; }
00154 void SetHighLightBorderType(int type) { mHighLightBorderType = type; }
00155 void SetAllowHighlight(bool mode) { mAllowHighLight = mode; }
00156 void SetHighLightInset(int inset) { mHighLightInset = inset; }
00157 void SetAllowMove(bool mode) { mAllowMove = mode; }
00158 bool GetAllowMove() { return mAllowMove; }
00159 void SetMoveFeedback(bool mode) { mMoveFeedback = mode; }
00160 void SetMoveCursor(int nr) { mMoveCursorNr = nr; }
00161
00162 virtual void SetBorderType(int type)
00163 {
00164 Window::SetBorderType(type);
00165 mNormalBorderType = type;
00166 }
00167
00168 void SetMinMaxXY(int minX, int maxX, int minY, int maxY)
00169 {
00170 if (minX != RETAIN)
00171 mMinX = minX;
00172 if (minY != RETAIN)
00173 mMinY = minY;
00174 if (maxX != RETAIN)
00175 mMaxX = maxX;
00176 if (maxY != RETAIN)
00177 mMaxY = maxY;
00178 }
00179
00180 void SetMinMaxSizes(int minW, int maxW, int minH, int maxH)
00181 {
00182 if (minW != RETAIN)
00183 mMinW = minW;
00184 if (minH != RETAIN)
00185 mMinH = minH;
00186 if (maxW != RETAIN)
00187 mMaxW = maxW;
00188 if (maxH != RETAIN)
00189 mMaxH = maxH;
00190 }
00191
00192 void SetAllowMoveDirections(int bits, bool mode=true)
00193 {
00194 if (bits & NorthSouth)
00195 (mAllowMoveVert = mode);
00196 if (bits & EastWest)
00197 mAllowMoveHor = mode;
00198 if (bits & Move)
00199 mAllowMove = mode;
00200 }
00201
00202 void SetAllowSizeDirections(int bits, bool mode=true)
00203 {
00204 if (bits & North)
00205 mAllowSizeNorth = mode;
00206 if (bits & East)
00207 mAllowSizeEast = mode;
00208 if (bits & South)
00209 mAllowSizeSouth = mode;
00210 if (bits & West)
00211 mAllowSizeWest = mode;
00212 if (bits & Move)
00213 mAllowMove = mode;
00214 }
00215
00216
00217 protected:
00218 void SetActionCursor(int action)
00219 {
00220 int cursor = oglCursorArrow;
00221 if ((action & South) && (action & West))
00222 cursor = oglCursorSW;
00223 else if ((action & North) && (action & East))
00224 cursor = oglCursorNE;
00225 else if ((action & North) && (action & West))
00226 cursor = oglCursorNW;
00227 else if ((action & South) && (action & West))
00228 cursor = oglCursorSW;
00229 else if ((action & South) && (action & East))
00230 cursor = oglCursorSE;
00231 else if ((action & West) )
00232 cursor = oglCursorW;
00233 else if ((action & East))
00234 cursor = oglCursorE;
00235 else if ((action & South))
00236 cursor = oglCursorS;
00237 else if ((action & North))
00238 cursor = oglCursorN;
00239
00240
00241 else if (mMoveFeedback && (action & Move))
00242 cursor = mMoveCursorNr;
00243
00244 oglSys.SetCursor(cursor);
00245 }
00246
00247 int GetAction(int x, int y)
00248 {
00249 int action = 0;
00250 int w = WndWidth(), h = WndHeight();
00251
00252 if (x >= 0 && x <= mSensePix && mAllowSizeWest) action |= West;
00253 if (x >= w-mSensePix && x <= w && mAllowSizeEast) action |= East;
00254 if (y >= 0 && y <= mSensePix && mAllowSizeSouth) action |= South;
00255 if (y >= h-mSensePix && y <= h && mAllowSizeNorth)action |= North;
00256
00257
00258 if ((action & (West|East)) == (West|East))
00259 action &= ~West;
00260 if ((action & (North|South)) == (North|South))
00261 action &= ~North;
00262 if (!action && x > 0 && y > 0 && x < w && y < h && mAllowMove)
00263 action = Move;
00264 return action;
00265 }
00266
00267 bool ClampMinMax(int& nX, int& nY, int& nW, int& nH)
00268 {
00269 int clamped = -1;
00270 if (nX < mMinX) clamped = nX = mMinX;
00271 if (nY < mMinY) clamped = nY = mMinY;
00272 if (nX > mMaxX) clamped = nX = mMaxX;
00273 if (nY > mMaxY) clamped = nY = mMaxY;
00274 if (nW < mMinW) clamped = nW = mMinW;
00275 if (nH < mMinH) clamped = nH = mMinH;
00276 if (nW > mMaxW) clamped = nW = mMaxW;
00277 if (nH > mMaxH) clamped = nH = mMaxH;
00278 return clamped != -1;
00279 }
00280
00281
00282 void CheckMinMax(int action, int& nX, int& nY, int& nW, int& nH)
00283 {
00284 int oX, oY, oW, oH;
00285
00286 GetDimensions(oX, oY, oW, oH);
00287
00288 if (nX < mMinX) nX = mMinX;
00289 if (nY < mMinY) nY = mMinY;
00290 if (nX > mMaxX) nX = mMaxX;
00291 if (nY > mMaxY) nY = mMaxY;
00292
00293 if (nW < mMinW)
00294 if (action & West)
00295 nX = oX, nW = oW;
00296 else
00297 nW = mMinW;
00298 if (nH < mMinH)
00299 if (action & South)
00300 nY = oY, nH = oH;
00301 else
00302 nH = mMinH;
00303 if (nW > mMaxW)
00304 if (action & West)
00305 nX = oX, nW = oW;
00306 else
00307 nW = mMaxW;
00308 if (nH > mMaxH)
00309 if (action & South)
00310 nY = oY, nH = oH;
00311 else
00312 nH = mMaxH;
00313 }
00314
00315 void PerformAction(int x, int y)
00316 {
00317 int nX, nY, nW, nH;
00318 GetDimensions(nX,nY,nW,nH);
00319
00320 if (mAction == Move)
00321 {
00322 if (mAllowMoveHor)
00323 nX = x + nX - mDx;
00324 if (mAllowMoveVert)
00325 nY = y + nY - mDy;
00326 }
00327 if (mAction & West)
00328 {
00329 nX = nX + x;
00330 nW = nW - x;
00331 }
00332 if (mAction & East)
00333 nW = x;
00334 if (mAction & South)
00335 {
00336 nY = nY + y;
00337 nH = nH - y;
00338 }
00339 if (mAction & North)
00340 nH = y;
00341
00342 CheckMinMax(mAction, nX, nY, nW, nH);
00343 SetDimensions(nX, nY, nW, nH);
00344 }
00345
00346 protected:
00347
00348 int mAction;
00349 int mHighLightBorderType;
00350 int mNormalBorderType;
00351 int mMoveCursorNr;
00352 bool mMoveFeedback;
00353 bool mToFrontOnMouseDown;
00354 bool mAllowHighLight;
00355 bool mAllowMove;
00356 bool mAllowSizeNorth;
00357 bool mAllowSizeEast;
00358 bool mAllowSizeSouth;
00359 bool mAllowSizeWest;
00360 bool mAllowMoveHor;
00361 bool mAllowMoveVert;
00362 bool mHighLight;
00363 int mActOnModifier;
00364 int mHighLightInset;
00365 int mSensePix;
00366 int mDx, mDy;
00367 int mMinX, mMinY;
00368 int mMaxX, mMaxY;
00369 int mMinW, mMaxW;
00370 int mMinH, mMaxH;
00371
00372 private:
00373 void Init()
00374 {
00375 oglSys.SetAllMouseMotion(mOglWnd, 1);
00376 mNormalBorderType = BEV_ETCHED;
00377 mHighLightBorderType = BEV_RIDGE;
00378 mMoveCursorNr = oglCursorSizeAll;
00379 mHighLight = false;
00380 mToFrontOnMouseDown = true;
00381 mMoveFeedback = false;
00382 mAllowHighLight = true;
00383 mAllowMove = true;
00384 mAllowMoveHor = true;
00385 mAllowMoveVert = true;
00386 mAllowSizeNorth = true;
00387 mAllowSizeEast = true;
00388 mAllowSizeSouth = true;
00389 mAllowSizeWest = true;
00390 mHighLightInset = 3;
00391 mSensePix = 6;
00392 mActOnModifier = 0;
00393 mAction = 0;
00394 mDx = 0;
00395 mDy = 0;
00396 mMinX = mMinY = -2000000;
00397 mMaxX = mMaxY = 2000000;
00398 mMinW = mMinH = 8;
00399 mMaxW = mMaxH = 2000000;
00400 }
00401 };
00402
00403 }
00404 #endif