1 // --------------------------------------------------------------------------- 2 // 3 // @file TwMgr.h 4 // @brief Tweak bar manager. 5 // @author Philippe Decaudin 6 // @license This file is part of the AntTweakBar library. 7 // For conditions of distribution and use, see License.txt 8 // 9 // note: Private header 10 // 11 // --------------------------------------------------------------------------- 12 13 14 #if !defined ANT_TW_MGR_INCLUDED 15 #define ANT_TW_MGR_INCLUDED 16 17 #include <AntTweakBar.h> 18 #define ANT_CALL TW_CALL 19 20 #include "TwColors.h" 21 #include "TwFonts.h" 22 #include "TwGraph.h" 23 #include "AntPerfTimer.h" 24 25 26 //#define BENCH // uncomment to activate benchmarks 27 28 #ifdef BENCH 29 # define PERF(cmd) cmd 30 #else // BENCH 31 # define PERF(cmd) 32 #endif // BENCH 33 34 const int NB_ROTO_CURSORS = 12; 35 36 37 // --------------------------------------------------------------------------- 38 // API unexposed by AntTweakBar.h 39 // --------------------------------------------------------------------------- 40 41 // bar states -> use TwDefine instead 42 typedef enum ETwState 43 { 44 TW_STATE_SHOWN = 1, 45 TW_STATE_ICONIFIED = 2, 46 TW_STATE_HIDDEN = 3, 47 TW_STATE_UNICONIFIED = 4, 48 TW_STATE_ERROR = 0 49 } TwState; 50 /*ANT_TWEAK_BAR_API*/ int ANT_CALL TwSetBarState(TwBar *bar, TwState state); 51 /*ANT_TWEAK_BAR_API*/ //TwState ANT_CALL TwGetBarState(const TwBar *bar); 52 // var states -> use TwDefine instead: visible/iconified implemented only as string commands 53 //ANT_TWEAK_BAR_API int ANT_CALL TwSetVarState(TwBar *bar, const char *name, TwState state); 54 //ANT_TWEAK_BAR_API TwState ANT_CALL TwGetVarState(const TwBar *bar, const char *name); 55 56 struct CTwVarGroup; 57 typedef void (ANT_CALL *TwStructExtInitCallback)(void *structExtValue, void *clientData); 58 typedef void (ANT_CALL *TwCopyVarFromExtCallback)(void *structValue, const void *structExtValue, unsigned int structExtMemberIndex, void *clientData); 59 typedef void (ANT_CALL *TwCopyVarToExtCallback)(const void *structValue, void *structExtValue, unsigned int structExtMemberIndex, void *clientData); 60 /*ANT_TWEAK_BAR_API*/ TwType ANT_CALL TwDefineStructExt(const char *name, const TwStructMember *structExtMembers, unsigned int nbExtMembers, size_t structSize, size_t structExtSize, TwStructExtInitCallback structExtInitCallback, TwCopyVarFromExtCallback copyVarFromExtCallback, TwCopyVarToExtCallback copyVarToExtCallback, TwSummaryCallback summaryCallback, void *clientData, const char *help); 61 typedef void (ANT_CALL *TwCustomDrawCallback)(int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp); 62 typedef bool (ANT_CALL *TwCustomMouseMotionCallback)(int mouseX, int mouseY, int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp); 63 typedef bool (ANT_CALL *TwCustomMouseButtonCallback)(TwMouseButtonID button, bool pressed, int mouseX, int mouseY, int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp); 64 typedef void (ANT_CALL *TwCustomMouseLeaveCallback)(void *structExtValue, void *clientData, TwBar *bar); 65 66 enum ERetType 67 { 68 RET_ERROR = 0, 69 RET_DOUBLE, 70 RET_STRING 71 }; 72 73 enum EButtonAlign 74 { 75 BUTTON_ALIGN_LEFT, 76 BUTTON_ALIGN_CENTER, 77 BUTTON_ALIGN_RIGHT 78 }; 79 80 // --------------------------------------------------------------------------- 81 // AntTweakBar Manager 82 // --------------------------------------------------------------------------- 83 84 struct CTwMgr 85 { 86 ETwGraphAPI m_GraphAPI; 87 void * m_Device; 88 int m_WndID; 89 class ITwGraph * m_Graph; 90 int m_WndWidth; 91 int m_WndHeight; 92 const CTexFont * m_CurrentFont; 93 94 std::vector<TwBar*> m_Bars; 95 std::vector<int> m_Order; 96 97 std::vector<bool> m_MinOccupied; 98 void Minimize(TwBar *_Bar); 99 void Maximize(TwBar *_Bar); 100 void Hide(TwBar *_Bar); 101 void Unhide(TwBar *_Bar); 102 void SetFont(const CTexFont *_Font, bool _ResizeBars); 103 int m_LastMouseX; 104 int m_LastMouseY; 105 int m_LastMouseWheelPos; 106 int m_IconPos; // 0: bottom-left, 1:bottom-right, 2:top-left, 3:top-right 107 int m_IconAlign; // 0: vertical, 1: horizontal 108 int m_IconMarginX, m_IconMarginY; 109 bool m_FontResizable; 110 std::string m_BarAlwaysOnTop; 111 std::string m_BarAlwaysOnBottom; 112 bool m_UseOldColorScheme; 113 bool m_Contained; 114 EButtonAlign m_ButtonAlign; 115 bool m_OverlapContent; 116 bool m_Terminating; 117 118 std::string m_Help; 119 TwBar * m_HelpBar; 120 float m_LastHelpUpdateTime; 121 void UpdateHelpBar(); 122 bool m_HelpBarNotUpToDate; 123 bool m_HelpBarUpdateNow; 124 void * m_KeyPressedTextObj; 125 bool m_KeyPressedBuildText; 126 std::string m_KeyPressedStr; 127 float m_KeyPressedTime; 128 void * m_InfoTextObj; 129 bool m_InfoBuildText; 130 int m_BarInitColorHue; 131 int FindBar(const char *_Name) const; 132 int HasAttrib(const char *_Attrib, bool *_HasValue) const; 133 int SetAttrib(int _AttribID, const char *_Value); 134 ERetType GetAttrib(int _AttribID, std::vector<double>& outDouble, std::ostringstream& outString) const; 135 void SetLastError(const char *_StaticErrorMesssage); // _StaticErrorMesssage must be a static string 136 const char * GetLastError(); // returns a static string describing the error, and set LastError to NULL 137 const char * CheckLastError() const; // returns the LastError, but does not set it to NULL 138 void SetCurrentDbgParams(const char *file, int line); 139 TwBar * m_PopupBar; 140 //bool IsProcessing() const { return m_Processing); 141 //void SetProcessing(bool processing) { m_Processing = processing; } 142 143 CTwMgr(ETwGraphAPI _GraphAPI, void *_Device, int _WndID); 144 ~CTwMgr(); 145 146 struct CStructMember 147 { 148 std::string m_Name; 149 std::string m_Label; 150 TwType m_Type; 151 size_t m_Offset; 152 std::string m_DefString; 153 size_t m_Size; 154 std::string m_Help; 155 }; 156 struct CStruct 157 { 158 std::string m_Name; 159 std::vector<CStructMember> m_Members; 160 size_t m_Size; 161 TwSummaryCallback m_SummaryCallback; 162 void * m_SummaryClientData; 163 std::string m_Help; 164 bool m_IsExt; 165 size_t m_ClientStructSize; 166 TwStructExtInitCallback m_StructExtInitCallback; 167 TwCopyVarFromExtCallback m_CopyVarFromExtCallback; 168 TwCopyVarToExtCallback m_CopyVarToExtCallback; 169 void * m_ExtClientData; CStructCTwMgr::CStruct170 CStruct() : m_IsExt(false), m_StructExtInitCallback(NULL), m_CopyVarFromExtCallback(NULL), m_CopyVarToExtCallback(NULL), m_ExtClientData(NULL) {} 171 static void ANT_CALL DefaultSummary(char *_SummaryString, size_t _SummaryMaxLength, const void *_Value, void *_ClientData); 172 static void * s_PassProxyAsClientData; 173 }; 174 std::vector<CStruct> m_Structs; 175 176 // followings are used for TwAddVarCB( ... StructType ... ) 177 struct CStructProxy 178 { 179 TwType m_Type; 180 void * m_StructData; 181 bool m_DeleteStructData; 182 void * m_StructExtData; 183 TwSetVarCallback m_StructSetCallback; 184 TwGetVarCallback m_StructGetCallback; 185 void * m_StructClientData; 186 TwCustomDrawCallback m_CustomDrawCallback; 187 TwCustomMouseMotionCallback m_CustomMouseMotionCallback; 188 TwCustomMouseButtonCallback m_CustomMouseButtonCallback; 189 TwCustomMouseLeaveCallback m_CustomMouseLeaveCallback; 190 bool m_CustomCaptureFocus; 191 int m_CustomIndexFirst; 192 int m_CustomIndexLast; 193 CStructProxy(); 194 ~CStructProxy(); 195 }; 196 struct CMemberProxy 197 { 198 CStructProxy * m_StructProxy; 199 int m_MemberIndex; 200 struct CTwVar * m_Var; 201 struct CTwVarGroup * m_VarParent; 202 CTwBar * m_Bar; 203 CMemberProxy(); 204 ~CMemberProxy(); 205 static void ANT_CALL SetCB(const void *_Value, void *_ClientData); 206 static void ANT_CALL GetCB(void *_Value, void *_ClientData); 207 }; 208 std::list<CStructProxy> m_StructProxies; // elements should not move 209 std::list<CMemberProxy> m_MemberProxies; // elements should not move 210 //void InitVarData(TwType _Type, void *_Data, size_t _Size); 211 //void UninitVarData(TwType _Type, void *_Data, size_t _Size); 212 213 struct CEnum 214 { 215 std::string m_Name; 216 typedef std::map<unsigned int, std::string> CEntries; 217 CEntries m_Entries; 218 }; 219 std::vector<CEnum> m_Enums; 220 221 TwType m_TypeColor32; 222 TwType m_TypeColor3F; 223 TwType m_TypeColor4F; 224 TwType m_TypeQuat4F; 225 TwType m_TypeQuat4D; 226 TwType m_TypeDir3F; 227 TwType m_TypeDir3D; 228 229 std::vector<char> m_CSStringBuffer; 230 struct CCDStdString 231 { 232 std::string * m_ClientStdStringPtr; 233 char m_LocalString[sizeof(std::string)+2*sizeof(void*)]; //+2*sizeof(void*) because of VC++ std::string extra info in Debug 234 TwSetVarCallback m_ClientSetCallback; 235 TwGetVarCallback m_ClientGetCallback; 236 void * m_ClientData; 237 static void ANT_CALL SetCB(const void *_Value, void *_ClientData); 238 static void ANT_CALL GetCB(void *_Value, void *_ClientData); 239 }; 240 std::list<CCDStdString> m_CDStdStrings; 241 struct CClientStdString // Convertion between VC++ Debug/Release std::string 242 { 243 CClientStdString(); 244 void FromLib(const char *libStr); 245 std::string& ToClient(); 246 private: 247 char m_Data[sizeof(std::string)+2*sizeof(void *)]; 248 std::string m_LibStr; 249 }; 250 struct CLibStdString // Convertion between VC++ Debug/Release std::string 251 { 252 CLibStdString(); 253 void FromClient(const std::string& clientStr); 254 std::string& ToLib(); 255 private: 256 char m_Data[sizeof(std::string)+2*sizeof(void *)]; 257 }; 258 struct CCDStdStringRecord 259 { 260 void * m_DataPtr; 261 char m_PrevValue[sizeof(std::string)+2*sizeof(void*)]; 262 CClientStdString m_ClientStdString; 263 }; 264 std::vector<CCDStdStringRecord> m_CDStdStringRecords; 265 void UnrollCDStdString(std::vector<CCDStdStringRecord>& _Records, TwType _Type, void *_Data); 266 void RestoreCDStdString(const std::vector<CCDStdStringRecord>& _Records); 267 std::map<void *, std::vector<char> > m_CDStdStringCopyBuffers; 268 269 struct CCustom // custom var type 270 { 271 virtual ~CCustom() = 0; 272 }; 273 std::vector<CCustom *> m_Customs; 274 275 PerfTimer m_Timer; 276 double m_LastMousePressedTime; 277 TwMouseButtonID m_LastMousePressedButtonID; 278 int m_LastMousePressedPosition[2]; 279 double m_RepeatMousePressedDelay; 280 double m_RepeatMousePressedPeriod; 281 bool m_CanRepeatMousePressed; 282 bool m_IsRepeatingMousePressed; 283 double m_LastDrawTime; 284 285 #if defined(ANT_WINDOWS) 286 typedef HCURSOR CCursor; 287 CCursor PixmapCursor(int _CurIdx); 288 #elif defined(ANT_UNIX) 289 typedef Cursor CCursor; 290 CCursor PixmapCursor(int _CurIdx); 291 Display * m_CurrentXDisplay; 292 Window m_CurrentXWindow; 293 #elif defined(ANT_OSX) 294 typedef NSCursor * CCursor; 295 CCursor PixmapCursor(int _CurIdx); 296 #endif // defined(ANT_UNIX) 297 bool m_CursorsCreated; 298 void CreateCursors(); 299 void FreeCursors(); 300 void SetCursor(CCursor _Cursor); 301 CCursor m_CursorArrow; 302 CCursor m_CursorMove; 303 CCursor m_CursorWE; 304 CCursor m_CursorNS; 305 CCursor m_CursorTopLeft; 306 CCursor m_CursorTopRight; 307 CCursor m_CursorBottomLeft; 308 CCursor m_CursorBottomRight; 309 CCursor m_CursorHelp; 310 CCursor m_CursorHand; 311 CCursor m_CursorCross; 312 CCursor m_CursorUpArrow; 313 CCursor m_CursorNo; 314 CCursor m_CursorIBeam; 315 CCursor m_RotoCursors[NB_ROTO_CURSORS]; 316 CCursor m_CursorCenter; 317 CCursor m_CursorPoint; 318 319 TwCopyCDStringToClient m_CopyCDStringToClient; 320 TwCopyStdStringToClient m_CopyStdStringToClient; 321 size_t m_ClientStdStringStructSize; 322 TwType m_ClientStdStringBaseType; 323 324 protected: 325 int m_NbMinimizedBars; 326 const char * m_LastError; 327 const char * m_CurrentDbgFile; 328 int m_CurrentDbgLine; 329 //bool m_Processing; 330 }; 331 332 extern CTwMgr *g_TwMgr; 333 334 335 // --------------------------------------------------------------------------- 336 // Extra functions and TwTypes 337 // --------------------------------------------------------------------------- 338 339 340 bool TwGetKeyCode(int *_Code, int *_Modif, const char *_String); 341 bool TwGetKeyString(std::string *_String, int _Code, int _Modif); 342 343 const TwType TW_TYPE_SHORTCUT = TwType(0xfff1); 344 const TwType TW_TYPE_HELP_GRP = TwType(0xfff2); 345 const TwType TW_TYPE_HELP_ATOM = TwType(0xfff3); 346 const TwType TW_TYPE_HELP_HEADER = TwType(0xfff4); 347 const TwType TW_TYPE_HELP_STRUCT = TwType(0xfff5); 348 const TwType TW_TYPE_BUTTON = TwType(0xfff6); 349 const TwType TW_TYPE_CDSTDSTRING = TwType(0xfff7); 350 const TwType TW_TYPE_STRUCT_BASE = TwType(0x10000000); 351 const TwType TW_TYPE_ENUM_BASE = TwType(0x20000000); 352 const TwType TW_TYPE_CSSTRING_BASE = TW_TYPE_CSSTRING(0); // defined as 0x30000000 (see AntTweakBar.h) 353 const TwType TW_TYPE_CSSTRING_MAX = TW_TYPE_CSSTRING(0xfffffff); 354 #define TW_CSSTRING_SIZE(type) ((int)((type)&0xfffffff)) 355 const TwType TW_TYPE_CUSTOM_BASE = TwType(0x40000000); 356 const TwType TW_TYPE_STDSTRING_VS2008 = TwType(0x2fff0000); 357 const TwType TW_TYPE_STDSTRING_VS2010 = TwType(0x2ffe0000); 358 359 extern "C" int ANT_CALL TwSetLastError(const char *_StaticErrorMessage); 360 361 //const TwGraphAPI TW_OPENGL_CORE = (TwGraphAPI)5; // WIP (note: OpenGL Core Profil requires OpenGL 3.2 or later) 362 363 // Clipping helper 364 struct CRect 365 { 366 int X, Y, W, H; CRectCRect367 CRect() : X(0), Y(0), W(0), H(0) {} CRectCRect368 CRect(int _X, int _Y, int _W, int _H) : X(_X), Y(_Y), W(_W), H(_H) {} 369 bool operator==(const CRect& _Rect) { return (Empty() && _Rect.Empty()) || (X==_Rect.X && Y==_Rect.Y && W==_Rect.W && H==_Rect.H); } 370 bool Empty(int _Margin=0) const { return (W<=_Margin || H<=_Margin); } 371 bool Subtract(const CRect& _Rect, std::vector<CRect>& _OutRects) const; 372 bool Subtract(const std::vector<CRect>& _Rects, std::vector<CRect>& _OutRects) const; 373 }; 374 375 376 // --------------------------------------------------------------------------- 377 // Global bar attribs 378 // --------------------------------------------------------------------------- 379 380 381 enum EMgrAttribs 382 { 383 MGR_HELP = 1, 384 MGR_FONT_SIZE, 385 MGR_FONT_STYLE, 386 MGR_ICON_POS, 387 MGR_ICON_ALIGN, 388 MGR_ICON_MARGIN, 389 MGR_FONT_RESIZABLE, 390 MGR_COLOR_SCHEME, 391 MGR_CONTAINED, 392 MGR_BUTTON_ALIGN, 393 MGR_OVERLAP 394 }; 395 396 397 // --------------------------------------------------------------------------- 398 // Color struct ext 399 // --------------------------------------------------------------------------- 400 401 402 struct CColorExt 403 { 404 int R, G, B; 405 int H, L, S; 406 int A; 407 bool m_HLS, m_HasAlpha, m_OGL; 408 bool m_CanHaveAlpha; 409 bool m_IsColorF; 410 unsigned int m_PrevConvertedColor; 411 CTwMgr::CStructProxy*m_StructProxy; 412 void RGB2HLS(); 413 void HLS2RGB(); 414 static void ANT_CALL InitColor32CB(void *_ExtValue, void *_ClientData); 415 static void ANT_CALL InitColor3FCB(void *_ExtValue, void *_ClientData); 416 static void ANT_CALL InitColor4FCB(void *_ExtValue, void *_ClientData); 417 static void ANT_CALL CopyVarFromExtCB(void *_VarValue, const void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData); 418 static void ANT_CALL CopyVarToExtCB(const void *_VarValue, void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData); 419 static void ANT_CALL SummaryCB(char *_SummaryString, size_t _SummaryMaxLength, const void *_ExtValue, void *_ClientData); 420 static void CreateTypes(); 421 }; 422 423 424 // --------------------------------------------------------------------------- 425 // Quaternion struct ext 426 // --------------------------------------------------------------------------- 427 428 429 struct CQuaternionExt 430 { 431 double Qx, Qy, Qz, Qs; // Quat value 432 double Vx, Vy, Vz, Angle; // Not used 433 double Dx, Dy, Dz; // Dir value set when used as a direction 434 bool m_AAMode; // Axis & angle mode -> disabled 435 bool m_ShowVal; // Display values 436 bool m_IsFloat; // Quat/Dir uses floats 437 bool m_IsDir; // Mapped to a dir vector instead of a quat 438 double m_Dir[3]; // If not zero, display one direction vector 439 color32 m_DirColor; // Direction vector color 440 float m_Permute[3][3]; // Permute frame axis 441 CTwMgr::CStructProxy*m_StructProxy; 442 static void ANT_CALL InitQuat4FCB(void *_ExtValue, void *_ClientData); 443 static void ANT_CALL InitQuat4DCB(void *_ExtValue, void *_ClientData); 444 static void ANT_CALL InitDir3FCB(void *_ExtValue, void *_ClientData); 445 static void ANT_CALL InitDir3DCB(void *_ExtValue, void *_ClientData); 446 static void ANT_CALL CopyVarFromExtCB(void *_VarValue, const void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData); 447 static void ANT_CALL CopyVarToExtCB(const void *_VarValue, void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData); 448 static void ANT_CALL SummaryCB(char *_SummaryString, size_t _SummaryMaxLength, const void *_ExtValue, void *_ClientData); 449 static void ANT_CALL DrawCB(int _W, int _H, void *_ExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp); 450 static bool ANT_CALL MouseMotionCB(int _MouseX, int _MouseY, int _W, int _H, void *_StructExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp); 451 static bool ANT_CALL MouseButtonCB(TwMouseButtonID _Button, bool _Pressed, int _MouseX, int _MouseY, int _W, int _H, void *_StructExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp); 452 static void ANT_CALL MouseLeaveCB(void *_StructExtValue, void *_ClientData, TwBar *_Bar); 453 static void CreateTypes(); 454 static TwType s_CustomType; 455 void ConvertToAxisAngle(); 456 void ConvertFromAxisAngle(); 457 void CopyToVar(); 458 static std::vector<float> s_SphTri; 459 static std::vector<color32> s_SphCol; 460 static std::vector<int> s_SphTriProj; 461 static std::vector<color32> s_SphColLight; 462 static std::vector<float> s_ArrowTri[4]; 463 static std::vector<int> s_ArrowTriProj[4]; 464 static std::vector<float> s_ArrowNorm[4]; 465 static std::vector<color32> s_ArrowColLight[4]; 466 enum EArrowParts { ARROW_CONE, ARROW_CONE_CAP, ARROW_CYL, ARROW_CYL_CAP }; 467 static void CreateSphere(); 468 static void CreateArrow(); 469 static void ApplyQuat(float *outX, float *outY, float *outZ, float x, float y, float z, float qx, float qy, float qz, float qs); 470 static void QuatFromDir(double *outQx, double *outQy, double *outQz, double *outQs, double dx, double dy, double dz); 471 inline void Permute(float *outX, float *outY, float *outZ, float x, float y, float z); 472 inline void PermuteInv(float *outX, float *outY, float *outZ, float x, float y, float z); 473 inline void Permute(double *outX, double *outY, double *outZ, double x, double y, double z); 474 inline void PermuteInv(double *outX, double *outY, double *outZ, double x, double y, double z); 475 bool m_Highlighted; 476 bool m_Rotating; 477 double m_OrigQuat[4]; 478 float m_OrigX, m_OrigY; 479 double m_PrevX, m_PrevY; 480 }; 481 482 483 // --------------------------------------------------------------------------- 484 // CTwFPU objects set and restore the fpu precision if needed. 485 // (could be useful because DirectX changes it and AntTweakBar requires default double precision) 486 // --------------------------------------------------------------------------- 487 488 489 struct CTwFPU 490 { CTwFPUCTwFPU491 CTwFPU() 492 { 493 #ifdef ANT_WINDOWS 494 state0 = _controlfp(0, 0); 495 if( (state0&MCW_PC)==_PC_24 ) // we need at least _PC_53 496 _controlfp(_PC_53, MCW_PC); 497 #else 498 state0 = 0; 499 #endif 500 } ~CTwFPUCTwFPU501 ~CTwFPU() 502 { 503 #ifdef ANT_WINDOWS 504 if( (state0&MCW_PC)==_PC_24 ) 505 _controlfp(_PC_24, MCW_PC); 506 #else 507 state0 = 0; 508 #endif 509 } 510 private: 511 unsigned int state0; 512 }; 513 514 // --------------------------------------------------------------------------- 515 516 517 #endif // !defined ANT_TW_MGR_INCLUDED 518