├── .DS_Store ├── .gitignore ├── README.md ├── example-Animation ├── addons.make ├── bin │ ├── .gitignore │ └── data │ │ ├── .gitkeep │ │ └── Gotham-Medium.otf └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-Events ├── addons.make ├── bin │ ├── .gitignore │ └── data │ │ ├── .gitkeep │ │ ├── Gotham-Medium.otf │ │ └── button-spritesheet.png └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-StylingElements ├── addons.make ├── bin │ ├── .gitignore │ └── data │ │ ├── .gitkeep │ │ └── img │ │ ├── grunge.jpg │ │ └── union.jpg └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-TouchEvents ├── addons.make ├── bin │ ├── .gitignore │ └── data │ │ ├── .gitkeep │ │ └── Gotham-Medium.otf └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-ViewManager ├── addons.make ├── bin │ ├── .gitignore │ └── data │ │ ├── .gitkeep │ │ └── Gotham-Medium.otf └── src │ ├── ViewA.h │ ├── ViewB.h │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── ofxaddons_thumbnail.png └── src ├── VUIContainer.cpp ├── VUIContainer.h ├── VUIElement.cpp ├── VUIElement.h ├── VUISlider.cpp ├── VUISlider.h ├── VUIStyleSheet.cpp ├── VUIStyleSheet.h ├── VUIText.h ├── VUITextField.cpp ├── VUITextField.h ├── VUIToggleGroup.h ├── VUIView.cpp ├── VUIView.h ├── ofxVui.cpp └── ofxVui.h /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Project.xcconfig 2 | config.make 3 | *.app 4 | *.xcodeproj 5 | Makefile 6 | openFrameworks-Info.plist 7 | *.vs 8 | *.sln 9 | *.vcxproj 10 | *.vcxproj.filters 11 | *.vcxproj.user 12 | icon.rc 13 | obj/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ✨ Much Easy! View + GUI System for openFrameworks ✨ 2 | ###### *BRANCHES* 3 | * ```master``` » Latest version (constantly adding features, use at your own risk 😈) 4 | * ```v1-stable``` » Last commit 12/21/2018 (use this or commit **0f429e641b8e5554c7e773e14fd50910fd28d451**) 5 | *** 6 | ###### *TELEPORT* 7 | * **Watch Examples Video** 8 | * **ofxVui Features** 9 | * **Code Examples** 10 | * **View Manager** 11 | * **GUI Animation** 12 | * **GUI Events** 13 | * **GUI Styling** 14 | * **Features Requests / In Progress** 15 | 16 | *** 17 | ###### *[DEPENDENCIES](#dependencies)* 18 | * **ofxEasing** » https://github.com/arturoc/ofxEasing 19 | * **ofxWinTouchHook** » https://github.com/trentbrooks/ofxWinTouchHook 20 | * OPTIONAL (Windows only) 21 | 1. add Preprocessor Macro **USING_ofxWinTouchHook** 22 | 2. call **VUI::EnableTouch()** in ofApp::setup() 23 | *** 24 | ###### *[TESTED ON](#tested-on)* 25 | * ***openFrameworks 0.9.8*** 26 | * macOS High Sierra (10.13) » Xcode 9 (✔️ Debug/Release) 27 | * Windows 10 » Visual Studio 2017 (✔️) 28 | * ***openFrameworks 0.10.1*** 29 | * macOS High Sierra (10.13) » Xcode 9 (❌) 30 | * macOS High Sierra (10.13) » Xcode 10 (⚠️ Release Build Only) 31 | *** 32 | ###### *[HIGH RESOLUTION / DPI](#high-res)* 33 | * ***Xcode*** » openFrameworks-Info.plist » right-click » Add Row » High Resolution Capable » YES 34 | * in main.cpp » first line in main() » VUI::SetDpi(2.0) 35 | *** 36 | ###### *[QUICK NOTE](#quick-note)* 37 | 38 | So everything works! 🎉 Although, the code under the hood is a little bit of spaghetti at the moment, uncommented, and there's a lot of legacy/debug stuff 😅. I was originally working on two different addons but decided to merge them together. Cleaning up the code is on my TODO list but first wanted to make this addon usable, tested, and make enough project/code examples. I have to get back to other projects though so yea... please feel free to enjoy this as-is 😋 and I'll continue to make improvements/add features whenever I get the chance 😊 39 | 40 | Also, ofxVui uses *Pascal Case (UpperCamelCase)* for methods because I've grown fond of it in C#/Unity - it just seems more legible IMO 🍕 41 | 42 | *** 43 | ###### *[WATCH EXAMPLES VIDEO](#video)* 44 | [![ofxVui Video](https://i.imgur.com/Pwox7Xa.jpg)](https://vimeo.com/242682198 "ofxVui - View + GUI System for openFrameworks") 45 | 46 | *** 47 | # **[ofxVui Features](#ofxvui)** 48 | ### View Manager 49 | * *Easily add/set views from anywhere* 50 | * *Views have access to same methods as ofApp* 51 | * *Mouse/Touch Events still work when scaling/rotating view* 52 | 53 | ``` 54 | Resolution 55 | Scale 56 | Rotation 57 | ∟ VUI_ROTATE_90_CCW 58 | ``` 59 | 60 | 61 | ### GUI System 62 | * *Mouse/Touch events respect Element render order* 63 | * *Event sends local and global Mouse/Touch positions* 64 | * *Easily animate Elements using one call* 65 | * *Tween has START, STEP, COMPLETE events* 66 | * *Easily style/texture Elements per state » UP, OVER, DOWN* 67 | * *StyleSheet manages fonts/images so there's no redundant loading* 68 | 69 | ``` 70 | Elements 71 | ∟ Element 72 | ∟ Element->MakeToggle() 73 | ∟ ToggleGroup 74 | ∟ Text 75 | ∟ TextField 76 | ∟ Slider 77 | ∟ Container 78 | 79 | (x/y position » px, %, calc) 80 | 81 | Animation Tween 82 | ∟ x 83 | ∟ y 84 | ∟ width 85 | ∟ height 86 | ∟ scale 87 | ∟ opacity 88 | ∟ rotation 89 | ∟ ease/easing 90 | 91 | (x/y/width/height/scale/opacity/rotation » px, +=, -=, *=) 92 | 93 | Animation Events 94 | ∟ ANIMATE_START 95 | ∟ ANIMATE_STEP 96 | ∟ ANIMATE_COMPLETE 97 | 98 | Mouse Events 99 | ∟ MOUSE_OVER 100 | ∟ MOUSE_OUT 101 | ∟ MOUSE_PRESSED 102 | ∟ MOUSE_MOVED 103 | ∟ MOUSE_DRAGGED 104 | ∟ MOUSE_RELEASED 105 | ∟ MOUSE_CLICK 106 | ∟ MOUSE_DOUBLE_CLICK 107 | 108 | Touch Events (only single touch usage tested so far) 109 | ∟ TOUCH_DOWN 110 | ∟ TOUCH_UP 111 | ∟ TOUCH_TAP 112 | ∟ TOUCH_DOUBLE_TAP 113 | 114 | Other Events 115 | ∟ STATE_CHANGE 116 | ∟ TEXT_CHANGE 117 | ∟ VALUE_CHANGE MakeToggle()> 118 | ∟ TOGGLE_CHANGE 119 | ∟ SUBMIT 120 | ∟ FOCUS 121 | ∟ UNFOCUS 122 | 123 | GUI States 124 | ∟ STATE_UP 125 | ∟ STATE_OVER 126 | ∟ STATE_DOWN 127 | 128 | GUI StyleSheet: Styles 129 | ∟ width » px/%/calc 130 | ∟ height » px/%/calc 131 | ∟ scale 132 | ∟ opacity 133 | ∟ rotation 134 | ∟ backgroundImage 135 | ∟ backgroundColor 136 | ∟ anchorPoint 137 | ∟ offset 138 | ∟ color 139 | ∟ padding 140 | ∟ textAlign 141 | ∟ font 142 | 143 | GUI Alignments for anchorPoint/textAlign 144 | ∟ LEFT_TOP 145 | ∟ LEFT_CENTER 146 | ∟ LEFT_BOTTOM 147 | ∟ CENTER_TOP 148 | ∟ CENTER_CENTER 149 | ∟ CENTER_BOTTOM 150 | ∟ RIGHT_TOP 151 | ∟ RIGHT_CENTER 152 | ∟ RIGHT_BOTTOM 153 | ``` 154 | *** 155 | # **[Code Examples](#code-examples)** 156 | There are a bunch of example projects/code in the repo but here are some basics. 157 | 158 | # [GUI Animation](#ui-animation) 159 | *For more info checkout the **example-Animation** project/code* 160 | * *Animate( Float seconds, String params );* 161 | 162 | ```c++ 163 | #include "ofxVui.h" 164 | using namespace VUI; 165 | 166 | // basic 167 | elementPtr->Animate(1.25, "{x: +=160, width: 150, height: 50, scale: *=.5, rotation: -=90, opacity: .75, ease: Elastic.easeOut }"); 168 | 169 | 170 | // add listener - method A 171 | elementPtr->Animate(1.25, "{x: 160, width: 150, height: 50, scale: 1.75, rotation: -135, opacity: .75, ease: Elastic.easeOut }", this, &ListenerClass::vuiEventHandler); 172 | 173 | 174 | // add listener - method B 175 | Tween* tweenPtr = elementPtr->Animate(1.25, "{x: 160, width: 150, height: 50, scale: 1.75, rotation: -135, opacity: .75, ease: Elastic.easeOut }"); 176 | ofAddListener( tweenPtr->onStep, this, &ListenerClass::vuiEventHandler ); 177 | ofAddListener( tweenPtr->onComplete, this, &ListenerClass::vuiEventHandler ); 178 | 179 | 180 | // can also set/reset animation properties: 181 | elementPtr->Set("{x: 0, width: 100, height: 100, scale: 1, rotation: 0, opacity: 1}"); 182 | 183 | 184 | // eventHandler 185 | void ListenerClass::vuiEventHandler(vuiEventArgs& evt){ 186 | if ( evt.element == elementPtr ){ 187 | if ( evt.eventType == VUI_EVENT_ANIMATE_COMPLETE ) /* do stuff */; 188 | else if ( evt.eventType == VUI_EVENT_ANIMATE_STEP ){ 189 | ofLog() << evt.tween->GetProgress(); 190 | } 191 | } 192 | } 193 | 194 | 195 | /* -------------------------------------------- easing functions 196 | 197 | Back.easeIn 198 | Back.easeOut 199 | Back.easeInOut 200 | Bounce.easeIn 201 | Bounce.easeOut 202 | Bounce.easeInOut 203 | Circ.easeIn 204 | Circ.easeOut 205 | Circ.easeInOut 206 | Cubic.easeIn 207 | Cubic.easeOut 208 | Cubic.easeInOut 209 | Elastic.easeIn 210 | Elastic.easeOut 211 | Elastic.easeInOut 212 | Exp.easeIn 213 | Exp.easeOut 214 | Exp.easeInOut 215 | Linear.easeIn 216 | Linear.easeOut 217 | Linear.easeInOut 218 | Linear.easeNone 219 | Quad.easeIn 220 | Quad.easeOut 221 | Quad.easeInOut 222 | 223 | */ 224 | 225 | ``` 226 | 227 | # [GUI Events](#ui-events) 228 | *For more info checkout the **example-Events** project/code* 229 | 230 | ```c++ 231 | #include "ofxVui.h" 232 | using namespace VUI; 233 | 234 | /* 235 | Some Mouse/Touch events are interchangeable so if you 236 | use VUI::EnableTouch() you don't have to change your code: 237 | - onMousePressed / onTouchDown 238 | - onMouseReleased / onTouchUp 239 | - onMouseClick / onTouchTap 240 | - onMouseDoubleClick / onTouchDoubleTap 241 | */ 242 | 243 | // add listener 244 | ofAddListener( elementPtr->onMouseClick, this, &ListenerClass::vuiEventHandler ); 245 | 246 | 247 | // eventHandler 248 | void ListenerClass::vuiEventHandler(vuiEventArgs& evt){ 249 | if ( evt.element == elementPtr ){ 250 | if ( evt.eventType == VUI_EVENT_MOUSE_CLICK ) { 251 | ofLog() << evt.localMousePos; 252 | }; 253 | } 254 | } 255 | 256 | 257 | /* -------------------------------------------- vuiEventArgs 258 | 259 | Element* element; 260 | int eventType; 261 | int renderState; 262 | int virtualState; 263 | 264 | int value = -1; 265 | string text = ""; 266 | 267 | ofVec2f localMousePos; 268 | ofVec2f localDragDelta; 269 | ofVec2f localDragStart; 270 | 271 | ofVec2f globalMousePos; 272 | 273 | Tween* tween; 274 | 275 | */ 276 | 277 | /* -------------------------------------------- events 278 | 279 | VUI_EVENT_MOUSE_OVER 280 | VUI_EVENT_MOUSE_OUT 281 | VUI_EVENT_MOUSE_PRESSED 282 | VUI_EVENT_MOUSE_MOVED 283 | VUI_EVENT_MOUSE_DRAGGED 284 | VUI_EVENT_MOUSE_RELEASED 285 | VUI_EVENT_MOUSE_CLICK 286 | VUI_EVENT_MOUSE_DOUBLE_CLICK 287 | 288 | VUI_EVENT_TOUCH_DOWN 289 | VUI_EVENT_TOUCH_UP 290 | VUI_EVENT_TOUCH_TAP 291 | VUI_EVENT_TOUCH_DOUBLE_TAP 292 | 293 | VUI_EVENT_STATE_CHANGE 294 | VUI_EVENT_TEXT_CHANGE 295 | VUI_EVENT_VALUE_CHANGE 296 | VUI_EVENT_TOGGLE_CHANGE 297 | VUI_EVENT_SLIDER_VALUE_CHANGE 298 | VUI_EVENT_SUBMIT 299 | 300 | VUI_EVENT_FOCUS 301 | VUI_EVENT_UNFOCUS 302 | 303 | VUI_EVENT_ANIMATE_COMPLETE 304 | VUI_EVENT_ANIMATE_STEP 305 | VUI_EVENT_ANIMATE_START 306 | 307 | */ 308 | 309 | ``` 310 | 311 | # [GUI Styling](#ui-styling) 312 | *For more info checkout the **example-StylingElements** project/code* 313 | ```c++ 314 | #include "ofxVui.h" 315 | using namespace VUI; 316 | 317 | StyleSheet* ss; 318 | Element* buttonA; 319 | Element* buttonB; 320 | Text* label; 321 | 322 | 323 | // -------------------------------------------- 324 | 325 | void setup(){ 326 | string styles = R"( 327 | [Images> 328 | btn-up: path/to/image.jpg; 329 | btn-over: path/to/image-over.jpg; 330 | btn-down: path/to/image-down.jpg; 331 | ] 332 | 333 | [.button> 334 | width: calc(40%-20); 335 | height: 10%; 336 | bgImage: btn-up, FILL; 337 | 338 | &:over{ 339 | bgImage: btn-over, FILL; 340 | } 341 | 342 | &:down{ 343 | bgImage: btn-down, FILL; 344 | } 345 | ] 346 | 347 | [#buttonB> 348 | scale: 1.25; 349 | opacity: .9; 350 | ] 351 | 352 | [.text> 353 | width: 160; 354 | height: 32; 355 | font: path/to/fontfile.ttf,16; 356 | color: #dddddd; 357 | padding: 10; 358 | anchorPoint: center-center; 359 | textAlign: center-center; 360 | bg: #ffffff; 361 | ] 362 | )"; 363 | 364 | // 365 | 366 | ss = new StyleSheet( styles ); 367 | 368 | /* 369 | 370 | name stylesheet if you want to load/use it elsewhere 371 | 372 | ss = new StyleSheet( styles, "dope-stylesheet" ); 373 | StyleSheet *elsewhere = VUI::GetStyleSheet( "dope-stylesheet" ); 374 | 375 | */ 376 | 377 | 378 | label = new Text( "50%", "50%", ss, ".text" ); 379 | 380 | // true = automatically set width/height to text 381 | label->SetText( "Stuff", true ); 382 | 383 | 384 | // Element(x, y, StyleSheet*, primarySelector, secondarySelector ); 385 | buttonA = new Element( 20, "calc(50%+30)", ss, ".button" ); 386 | buttonB = new Element( "10%", 300, ss, ".button", "#buttonB" ); 387 | 388 | } 389 | 390 | 391 | // -------------------------------------------- 392 | 393 | void draw(){ 394 | label->Render(); 395 | buttonA->Render(); 396 | buttonB->Render(); 397 | } 398 | 399 | 400 | ``` 401 | 402 | # [View Manager](#example-view-manager) 403 | *For more info checkout the **example-ViewManager** project/code* 404 | 405 | ```c++ 406 | #include "ofxVui.h" 407 | using namespace VUI; 408 | 409 | // ---------------------------------------- main.cpp 410 | 411 | VUI::SetResolution(1080,1920,.6); 412 | // VUI::RotateView( VUI_ROTATE_90_CCW ); 413 | 414 | ofSetupOpenGL(VUI::GetWindowWidth(),VUI::GetWindowHeight(),OF_WINDOW); 415 | 416 | 417 | // ---------------------------------------- create View 418 | 419 | #include "ofxVui.h" 420 | using namespace VUI; 421 | 422 | class MyView : public View { 423 | // a few extra stuff 424 | /* 425 | if overriding BeforeExitView(), you must call ExitView() 426 | when you're done with what you need to do 427 | */ 428 | virtual void BeforeExitView() { 429 | ExitView(); 430 | }; 431 | 432 | virtual void OnEnterView() {}; 433 | 434 | // basic stuff 435 | int mouseX; 436 | int mouseY; 437 | 438 | void setup(){}; 439 | void update(){}; 440 | void draw(){}; 441 | 442 | void keyPressed(int key){}; 443 | void keyReleased(int key){}; 444 | void mouseMoved(int x, int y ){}; 445 | void mouseDragged(int x, int y, int button){}; 446 | void mousePressed(int x, int y, int button){}; 447 | void mouseReleased(int x, int y, int button){}; 448 | void mouseEntered(int x, int y){}; 449 | void mouseExited(int x, int y){}; 450 | void windowResized(int w, int h){}; 451 | void dragEvent(ofDragInfo dragInfo){}; 452 | void gotMessage(ofMessage msg){}; 453 | 454 | } 455 | 456 | 457 | // ---------------------------------------- ofApp.cpp 458 | 459 | #include "MyView.h" 460 | #include "MyOtherView.h" 461 | 462 | void setup(){ 463 | //Windows only, please see Dependencies section above for more info 464 | //VUI::EnableTouch(); 465 | 466 | VUI::AddView( "view-name", new MyView() ); 467 | VUI::AddView( "my-other-view", new MyOtherView() ); 468 | 469 | 470 | // can call from anywhere 471 | VUI::SetView( "view-name" ); 472 | } 473 | 474 | void draw(){ 475 | /* 476 | VUI::Render() is VUI::RenderBegin() + VUI::RenderEnd() 477 | */ 478 | VUI::Render(); 479 | 480 | 481 | /* 482 | 483 | If you still want to scale/rotate your view without using the 484 | View Manager (via AddView()/SetView() you can like this: 485 | 486 | VUI::RenderBegin(); 487 | // draw your stuff here 488 | VUI::RenderEnd(); 489 | 490 | 491 | But you MUST set the 4th arg in VUI::SetResolution() to false (main.cpp): 492 | (ofxVui Element's Mouse/Touch events will adapt to scaled/rotated coordinates) 493 | 494 | VUI::SetResolution(w, h, scale, enableViewManager ); 495 | eg: VUI::SetResolution(1920, 1080, .6, false); 496 | 497 | */ 498 | } 499 | 500 | ``` 501 | *** 502 | ###### *[FEATURE REQUESTS / IN PROGRESS](#todo)* 503 | 504 | ``` 505 | ⭐️ Touch 506 | + Test multiple touch events / scenarios 507 | + Add - VUI_EVENT_TOUCH_DRAG 508 | 509 | ⭐️ UI Elements 510 |      ✔️ Add - Container - scrollable 511 | ✔️ Add - Slider 512 | + Add - Slider2D 513 | 514 | ⭐️ StyleSheet 515 | ✔️ width/height - percentage based values 516 | ✔️ width/height - calc() based values 517 | 518 | ⭐️ Animate 519 | ✔️ += value (x/y/width/height/scale/opacity/rotation) 520 | ✔️ -= value (x/y/width/height/scale/opacity/rotation) 521 | ✔️ *= value (x/y/width/height/scale/opacity/rotation) 522 | 523 | ⭐️ VUI::SetRotation() 524 | + Add option - VUI_ROTATE_90_CW 525 | + Add option - VUI_ROTATE_180 526 | 527 | ⭐️ Cleanup / add comments to ofxVui code 528 | ⭐️ Add more emojis to this README 👓 529 | ``` 530 | If you think of a feature that would be super useful in this addon or have a request to prioritize a feature, please feel free to email me » ***hi.christophermiles@gmail.com*** -or- submit a pull request :) 531 | -------------------------------------------------------------------------------- /example-Animation/addons.make: -------------------------------------------------------------------------------- 1 | ofxEasing 2 | ofxVui 3 | -------------------------------------------------------------------------------- /example-Animation/bin/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | *.exp 4 | *.lib 5 | *.ilk 6 | *.pdb -------------------------------------------------------------------------------- /example-Animation/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-Animation/bin/data/.gitkeep -------------------------------------------------------------------------------- /example-Animation/bin/data/Gotham-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-Animation/bin/data/Gotham-Medium.otf -------------------------------------------------------------------------------- /example-Animation/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | #include "ofxVui.h" 4 | 5 | //======================================================================== 6 | int main( ){ 7 | ofSetupOpenGL(1280, 720, OF_WINDOW); // <-------- setup the GL context 8 | 9 | // this kicks off the running of my app 10 | // can be OF_WINDOW or OF_FULLSCREEN 11 | // pass in width and height too: 12 | ofRunApp(new ofApp()); 13 | } 14 | -------------------------------------------------------------------------------- /example-Animation/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetFrameRate(60); 6 | 7 | string styles = R"( 8 | [#animElement> 9 | width: 100; 10 | height: 100; 11 | anchorPoint: center-center; 12 | bg: #ff0000; 13 | 14 | &:over{ 15 | bg: #7cf9ae; 16 | border: 1, #10532b; 17 | } 18 | ] 19 | 20 | [.button> 21 | bg: #000000; 22 | font: Gotham-Medium.otf, 11; 23 | color: #ffffff; 24 | padding: 10; 25 | 26 | &:over{ 27 | border: 1, #5ab1e2; 28 | bg: #377598; 29 | } 30 | 31 | &:down { 32 | bg: #2c8d3a; 33 | border: 1, #55ff7d; 34 | } 35 | ] 36 | 37 | [#toggleGroup> 38 | width: 80; 39 | height: 80; 40 | anchorPoint: right-bottom; 41 | ] 42 | 43 | [.alignmentBtn> 44 | width: 20; 45 | height: 20; 46 | bg: #000000; 47 | &:over{ 48 | border: 2, #7cf9ae; 49 | } 50 | &:down{ 51 | bg: #7cf9ae; 52 | } 53 | ] 54 | 55 | [#toggleLabel> 56 | anchorPoint: right-top; 57 | font: Gotham-Medium.otf, 8; 58 | ] 59 | 60 | [#leftTop> 61 | anchorPoint: left-top; 62 | ] 63 | 64 | [#leftCenter> 65 | anchorPoint: left-center; 66 | ] 67 | 68 | [#leftBottom> 69 | anchorPoint: left-bottom; 70 | ] 71 | 72 | [#centerTop> 73 | anchorPoint: center-top; 74 | ] 75 | 76 | [#centerCenter> 77 | anchorPoint: center-center; 78 | ] 79 | 80 | [#centerBottom> 81 | anchorPoint: center-bottom; 82 | ] 83 | 84 | [#rightTop> 85 | anchorPoint: right-top; 86 | ] 87 | 88 | [#rightCenter> 89 | anchorPoint: right-center; 90 | ] 91 | 92 | [#rightBottom> 93 | anchorPoint: right-bottom; 94 | ] 95 | 96 | 97 | )"; 98 | 99 | ss = new StyleSheet( styles ); 100 | 101 | 102 | //-------------------------------------------------------------- ANIMATION 103 | 104 | float Y = -20; 105 | 106 | animElement = new Element( 150, ofGetHeight()*.5, ss, "#animElement" ); 107 | 108 | 109 | // make 110 | animationA = new Text( 20, Y+=40, ss, ".button" ); 111 | animationB = new Text( 20, Y+=40, ss, ".button" ); 112 | animationC = new Text( 20, Y+=40, ss, ".button" ); 113 | 114 | 115 | // labels 116 | animationA->SetText( "[A] Animate(1.25, {x: 150, width :150, height: 50, scale:1, rotation: 0, ease:Bounce.easeOut})", true ); 117 | animationB->SetText( "[B] Animate(.5, {x:640, width: 100, height: 100, opacity:.5, scale: 1.75, rotation: -180, ease:Back.easeOut})", true ); 118 | animationC->SetText( "[C] Animate(1, {x:1100, width: 100, height: 100,scale:.5, opacity: 1, rotation: 135, ease:Elastic.easeOut})", true ); 119 | 120 | 121 | // click event 122 | ofAddListener( animationA->onMouseClick, this, &ofApp::vuiEventHandler ); 123 | ofAddListener( animationB->onMouseClick, this, &ofApp::vuiEventHandler ); 124 | ofAddListener( animationC->onMouseClick, this, &ofApp::vuiEventHandler ); 125 | 126 | 127 | 128 | //-------------------------------------------------------------- ALIGNMENT 129 | 130 | // grouping 131 | toggleGroup = new ToggleGroup(ofGetWidth()-20, ofGetHeight()-20, ss, "#toggleGroup"); 132 | 133 | 134 | // label 135 | toggleGroupLabel = new Text(ofGetWidth()-20, ofGetHeight()-120, ss, "#toggleLabel"); 136 | toggleGroupLabel->SetText( "AnchorPoint", true ); 137 | toggleGroupLabel->SetWidth( 80 ); 138 | 139 | float w = toggleGroup->GetWidth(); 140 | float h = toggleGroup->GetHeight(); 141 | 142 | 143 | // alignment buttons 144 | alignLeftTop = new Element(0,0, ss, ".alignmentBtn", "#leftTop" ); 145 | alignLeftCenter = new Element(0,h*.5, ss, ".alignmentBtn", "#leftCenter" ); 146 | alignLeftBottom = new Element(0,h, ss, ".alignmentBtn", "#leftBottom" ); 147 | 148 | alignCenterTop = new Element(w*.5,0, ss, ".alignmentBtn", "#centerTop" ); 149 | alignCenterCenter = new Element(w*.5,h*.5, ss, ".alignmentBtn", "#centerCenter" ); 150 | alignCenterBottom = new Element(w*.5,h, ss, ".alignmentBtn", "#centerBottom" ); 151 | 152 | alignRightTop = new Element(w,0, ss, ".alignmentBtn", "#rightTop" ); 153 | alignRightCenter = new Element(w,h*.5, ss, ".alignmentBtn", "#rightCenter" ); 154 | alignRightBottom = new Element(w,h, ss, ".alignmentBtn", "#rightBottom" ); 155 | 156 | 157 | // add elements to toggle group - this uses AddChild() which renders children 158 | // when rendering parent - toggleGroup->Render(); 159 | toggleGroup->AddToggle( alignLeftTop ); 160 | toggleGroup->AddToggle( alignLeftCenter ); 161 | toggleGroup->AddToggle( alignLeftBottom ); 162 | toggleGroup->AddToggle( alignCenterTop ); 163 | toggleGroup->AddToggle( alignCenterCenter, true ); 164 | toggleGroup->AddToggle( alignCenterBottom ); 165 | toggleGroup->AddToggle( alignRightTop ); 166 | toggleGroup->AddToggle( alignRightCenter ); 167 | toggleGroup->AddToggle( alignRightBottom ); 168 | 169 | 170 | ofAddListener( toggleGroup->onToggleChange, this, &ofApp::vuiEventHandler ); 171 | 172 | } 173 | 174 | void ofApp::vuiEventHandler(vuiEventArgs& evt){ 175 | 176 | 177 | if ( evt.eventType == VUI_EVENT_MOUSE_CLICK ){ 178 | if ( evt.element == animationA ) { 179 | 180 | // COMPLETE Listener [Method A] 181 | 182 | tweenPtr = animElement->Animate( 1.25, "{x: 150, width:150, height: 50, scale:1, rotation: 0, ease:Bounce.easeOut}" ); 183 | tweenPtr->SetID( "Animation A" ); 184 | 185 | } else if ( evt.element == animationB ) { 186 | 187 | // COMPLETE Listener [Method B] 188 | 189 | tweenPtr = animElement->Animate( .5, "{x:640, width: 100, height: 100, opacity:.5, scale: 1.75, rotation: -180, ease:Back.easeOut}" ); 190 | tweenPtr->SetID( "Animation B" ); 191 | 192 | ofAddListener( tweenPtr->onComplete, this, &ofApp::vuiEventHandler ); 193 | 194 | } else if ( evt.element == animationC ) { 195 | 196 | // Tween STEP/PROGRESS Listener 197 | 198 | tweenPtr = animElement->Animate( 1, "{x:1100, width: 100, height: 100,scale:.5, opacity: 1, rotation: 135, ease:Elastic.easeOut}", this, &ofApp::vuiEventHandler ); 199 | 200 | tweenPtr->SetID( "Animation C" ); 201 | 202 | ofAddListener( tweenPtr->onStep, this, &ofApp::vuiEventHandler ); 203 | 204 | } 205 | } else if ( evt.eventType == VUI_EVENT_ANIMATE_COMPLETE ){ 206 | 207 | ofLog() << "[" << evt.tween->GetID() << "] VUI_EVENT_ANIMATE_COMPLETE"; 208 | 209 | } else if ( evt.eventType == VUI_EVENT_ANIMATE_STEP ){ 210 | 211 | ofLog() << "[" << evt.tween->GetID() << "] progress:" << evt.tween->GetProgress(); 212 | } 213 | 214 | 215 | 216 | // change anchorPoint 217 | 218 | if ( evt.eventType == VUI_EVENT_TOGGLE_CHANGE ){ 219 | if ( evt.value == 1 ) { 220 | if ( evt.element == alignLeftTop ) animElement->SetAnchorPoint( VUI_ALIGN_LEFT_TOP ); 221 | else if ( evt.element == alignLeftCenter ) animElement->SetAnchorPoint( VUI_ALIGN_LEFT_CENTER ); 222 | else if ( evt.element == alignLeftBottom ) animElement->SetAnchorPoint( VUI_ALIGN_LEFT_BOTTOM ); 223 | else if ( evt.element == alignCenterTop ) animElement->SetAnchorPoint( VUI_ALIGN_CENTER_TOP ); 224 | else if ( evt.element == alignCenterCenter ) animElement->SetAnchorPoint( VUI_ALIGN_CENTER_CENTER ); 225 | else if ( evt.element == alignCenterBottom ) animElement->SetAnchorPoint( VUI_ALIGN_CENTER_BOTTOM ); 226 | else if ( evt.element == alignRightTop ) animElement->SetAnchorPoint( VUI_ALIGN_RIGHT_TOP ); 227 | else if ( evt.element == alignRightCenter ) animElement->SetAnchorPoint( VUI_ALIGN_RIGHT_CENTER ); 228 | else if ( evt.element == alignRightBottom ) animElement->SetAnchorPoint( VUI_ALIGN_RIGHT_BOTTOM ); 229 | } else { 230 | animElement->SetAnchorPoint( VUI_ALIGN_CENTER_CENTER ); 231 | alignCenterCenter->SetSelected(); 232 | } 233 | } 234 | } 235 | 236 | //-------------------------------------------------------------- 237 | void ofApp::update(){ 238 | ofSetWindowTitle( ofToString(ofGetFrameRate()) ); 239 | } 240 | 241 | //-------------------------------------------------------------- 242 | void ofApp::draw(){ 243 | // animation targers 244 | ofSetColor(100,100,100,255); 245 | ofDrawCircle( 150, ofGetHeight()*.5, 3 ); 246 | ofDrawCircle( 640, ofGetHeight()*.5, 3 ); 247 | ofDrawCircle( 1100, ofGetHeight()*.5, 3 ); 248 | 249 | // animated element 250 | animElement->Render(); 251 | 252 | // anchorPoint 253 | ofSetColor(255,255,255,255); 254 | ofDrawCircle( animElement->GetPosition(), 3 ); 255 | 256 | // buttons / cmds 257 | animationA->Render(); 258 | animationB->Render(); 259 | animationC->Render(); 260 | 261 | // anchorPoint selection - this renders all the toggles added to the group 262 | toggleGroup->Render(); 263 | 264 | // anchorPoint label 265 | toggleGroupLabel->Render(); 266 | } 267 | 268 | //-------------------------------------------------------------- 269 | void ofApp::keyPressed(int key){ 270 | 271 | } 272 | 273 | //-------------------------------------------------------------- 274 | void ofApp::keyReleased(int key){ 275 | 276 | } 277 | 278 | //-------------------------------------------------------------- 279 | void ofApp::mouseMoved(int x, int y ){ 280 | 281 | } 282 | 283 | //-------------------------------------------------------------- 284 | void ofApp::mouseDragged(int x, int y, int button){ 285 | 286 | } 287 | 288 | //-------------------------------------------------------------- 289 | void ofApp::mousePressed(int x, int y, int button){ 290 | 291 | } 292 | 293 | //-------------------------------------------------------------- 294 | void ofApp::mouseReleased(int x, int y, int button){ 295 | 296 | } 297 | 298 | //-------------------------------------------------------------- 299 | void ofApp::mouseEntered(int x, int y){ 300 | 301 | } 302 | 303 | //-------------------------------------------------------------- 304 | void ofApp::mouseExited(int x, int y){ 305 | 306 | } 307 | 308 | //-------------------------------------------------------------- 309 | void ofApp::windowResized(int w, int h){ 310 | 311 | } 312 | 313 | //-------------------------------------------------------------- 314 | void ofApp::gotMessage(ofMessage msg){ 315 | 316 | } 317 | 318 | //-------------------------------------------------------------- 319 | void ofApp::dragEvent(ofDragInfo dragInfo){ 320 | 321 | } 322 | -------------------------------------------------------------------------------- /example-Animation/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxVui.h" 5 | 6 | using namespace VUI; 7 | 8 | class ofApp : public ofBaseApp{ 9 | 10 | public: 11 | void setup(); 12 | void update(); 13 | void draw(); 14 | 15 | void keyPressed(int key); 16 | void keyReleased(int key); 17 | void mouseMoved(int x, int y ); 18 | void mouseDragged(int x, int y, int button); 19 | void mousePressed(int x, int y, int button); 20 | void mouseReleased(int x, int y, int button); 21 | void mouseEntered(int x, int y); 22 | void mouseExited(int x, int y); 23 | void windowResized(int w, int h); 24 | void dragEvent(ofDragInfo dragInfo); 25 | void gotMessage(ofMessage msg); 26 | 27 | void vuiEventHandler(vuiEventArgs& evt); 28 | 29 | Element* animElement; 30 | Tween* tweenPtr; 31 | 32 | Text* animationA; 33 | Text* animationB; 34 | Text* animationC; 35 | 36 | StyleSheet* ss; 37 | 38 | 39 | // alignments 40 | 41 | Text* toggleGroupLabel; 42 | ToggleGroup* toggleGroup; 43 | 44 | Element* alignLeftTop; 45 | Element* alignLeftCenter; 46 | Element* alignLeftBottom; 47 | 48 | Element* alignCenterTop; 49 | Element* alignCenterCenter; 50 | Element* alignCenterBottom; 51 | 52 | Element* alignRightTop; 53 | Element* alignRightCenter; 54 | Element* alignRightBottom; 55 | 56 | }; 57 | -------------------------------------------------------------------------------- /example-Events/addons.make: -------------------------------------------------------------------------------- 1 | ofxEasing 2 | ofxVui 3 | -------------------------------------------------------------------------------- /example-Events/bin/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | *.exp 4 | *.lib 5 | *.ilk 6 | *.pdb -------------------------------------------------------------------------------- /example-Events/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-Events/bin/data/.gitkeep -------------------------------------------------------------------------------- /example-Events/bin/data/Gotham-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-Events/bin/data/Gotham-Medium.otf -------------------------------------------------------------------------------- /example-Events/bin/data/button-spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-Events/bin/data/button-spritesheet.png -------------------------------------------------------------------------------- /example-Events/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | #include "ofxVui.h" 4 | 5 | //======================================================================== 6 | int main( ){ 7 | ofSetupOpenGL(1280, 720, OF_WINDOW); // <-------- setup the GL context 8 | 9 | // this kicks off the running of my app 10 | // can be OF_WINDOW or OF_FULLSCREEN 11 | // pass in width and height too: 12 | ofRunApp(new ofApp()); 13 | } 14 | -------------------------------------------------------------------------------- /example-Events/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetFrameRate(60); 6 | 7 | string styles = R"( 8 | [Images> 9 | btn-sprite: button-spritesheet.png; 10 | ] 11 | [#square> 12 | 13 | width: 400; 14 | height: 400; 15 | background-color: #ff0000; 16 | anchorPoint: center-center; 17 | 18 | &:over { 19 | background-color: #00ff00; 20 | } 21 | 22 | &:down { 23 | background-color: #0000ff; 24 | } 25 | ] 26 | 27 | [.rectangle> 28 | 29 | width: 200; 30 | height: 60; 31 | background-color: #ffffff; 32 | anchorPoint: center-center; 33 | 34 | &:over { 35 | background-color: #00ff00; 36 | } 37 | 38 | &:down { 39 | background-color: #0000ff; 40 | } 41 | ] 42 | 43 | [#rectangleB> 44 | 45 | width: 60; 46 | height: 200; 47 | background-color: #dddddd; 48 | 49 | ] 50 | 51 | [#textField> 52 | width: 240; 53 | height: 36; 54 | background-color: #aeaeae; 55 | font: Gotham-Medium.otf,13; 56 | text-align: left-center; 57 | color: #000000; 58 | padding-left: 10; 59 | 60 | &:over{ 61 | background-color: #7cf9ae; 62 | } 63 | 64 | &:down{ 65 | background-color: #00ff00; 66 | } 67 | ] 68 | 69 | [#text> 70 | width: 180; 71 | height: 40; 72 | color: #ffffff; 73 | textAlign: center-center; 74 | font: Gotham-Medium.otf,13; 75 | bgImage: btn-sprite; 76 | 77 | &:over{ 78 | bgImage: btn-sprite,0, 40; 79 | } 80 | &:down{ 81 | bgImage: btn-sprite, 0, 80; 82 | } 83 | ] 84 | 85 | [.toggle> 86 | width: 80; 87 | height: 32; 88 | background-color: #a2e3f3; 89 | 90 | &:over { 91 | background-color: #f879fd; 92 | } 93 | 94 | &:down { 95 | background-color: #43df6c; 96 | } 97 | ] 98 | 99 | [#preToggle> 100 | border: 1, #ffffff, ALL; 101 | ] 102 | 103 | )"; 104 | 105 | // 106 | 107 | ss = new StyleSheet( styles ); 108 | 109 | 110 | // 111 | 112 | square = new Element( 220, ofGetHeight()*.4, ss, "#square" ); 113 | rectangle = new Element( 220, ofGetHeight()*.4, ss, ".rectangle" ); 114 | rectangleB = new Element( 260, ofGetHeight()*.4, ss, ".rectangle", "#rectangleB" ); 115 | 116 | 117 | // 118 | 119 | text = new Text( 640, 50, ss, "#text" ); 120 | text->SetText("Text / Button"); 121 | 122 | ofAddListener( text->onMouseClick, this, &ofApp::vuiEventHandler ); 123 | ofAddListener( text->onMouseDoubleClick, this, &ofApp::vuiEventHandler ); 124 | 125 | textField = new TextField( 640, 100, ss, "#textField" ); 126 | textField->SetText("omg textfield"); 127 | 128 | 129 | // 130 | 131 | preToggle = new Element( 640, 160, ss, ".toggle", "#preToggle" ); 132 | ofAddListener( preToggle->onStateChange, this, &ofApp::vuiEventHandler ); 133 | 134 | postToggle = new Element( 640, 200, ss, ".toggle" ); 135 | postToggle->MakeToggle(); 136 | 137 | 138 | // ------------------------------------------------------------------- Toggle EVENTS 139 | ofAddListener( postToggle->onValueChange, this, &ofApp::vuiEventHandler ); 140 | 141 | 142 | // ------------------------------------------------------------------- TextField EVENTS 143 | ofAddListener( textField->onFocus, this, &ofApp::vuiEventHandler ); 144 | ofAddListener( textField->onUnfocus, this, &ofApp::vuiEventHandler ); 145 | ofAddListener( textField->onTextChange, this, &ofApp::vuiEventHandler ); 146 | ofAddListener( textField->onSubmit, this, &ofApp::vuiEventHandler ); 147 | 148 | 149 | // ------------------------------------------------------------------- Mouse EVENTS 150 | /* 151 | VUI_EVENT_MOUSE_OVER 152 | VUI_EVENT_MOUSE_OUT 153 | VUI_EVENT_MOUSE_PRESSED 154 | VUI_EVENT_MOUSE_MOVED 155 | VUI_EVENT_MOUSE_DRAGGED 156 | VUI_EVENT_MOUSE_RELEASED 157 | VUI_EVENT_MOUSE_CLICK 158 | VUI_EVENT_MOUSE_DOUBLE_CLICK 159 | 160 | */ 161 | 162 | ofAddListener( square->onMouseOver, this, &ofApp::vuiEventHandler ); 163 | ofAddListener( square->onMouseOut, this, &ofApp::vuiEventHandler ); 164 | ofAddListener( square->onMousePressed, this, &ofApp::vuiEventHandler ); 165 | ofAddListener( square->onMouseMoved, this, &ofApp::vuiEventHandler ); 166 | ofAddListener( square->onMouseDragged, this, &ofApp::vuiEventHandler ); 167 | ofAddListener( square->onMouseReleased, this, &ofApp::vuiEventHandler ); 168 | ofAddListener( square->onMouseClick, this, &ofApp::vuiEventHandler ); 169 | ofAddListener( square->onMouseDoubleClick, this, &ofApp::vuiEventHandler ); 170 | 171 | ofAddListener( rectangle->onMouseOver, this, &ofApp::vuiEventHandler ); 172 | ofAddListener( rectangle->onMouseOut, this, &ofApp::vuiEventHandler ); 173 | ofAddListener( rectangle->onMousePressed, this, &ofApp::vuiEventHandler ); 174 | ofAddListener( rectangle->onMouseMoved, this, &ofApp::vuiEventHandler ); 175 | ofAddListener( rectangle->onMouseDragged, this, &ofApp::vuiEventHandler ); 176 | ofAddListener( rectangle->onMouseReleased, this, &ofApp::vuiEventHandler ); 177 | ofAddListener( rectangle->onMouseClick, this, &ofApp::vuiEventHandler ); 178 | ofAddListener( rectangle->onMouseDoubleClick, this, &ofApp::vuiEventHandler ); 179 | 180 | ofAddListener( rectangleB->onMouseOver, this, &ofApp::vuiEventHandler ); 181 | ofAddListener( rectangleB->onMouseOut, this, &ofApp::vuiEventHandler ); 182 | ofAddListener( rectangleB->onMousePressed, this, &ofApp::vuiEventHandler ); 183 | ofAddListener( rectangleB->onMouseMoved, this, &ofApp::vuiEventHandler ); 184 | ofAddListener( rectangleB->onMouseDragged, this, &ofApp::vuiEventHandler ); 185 | ofAddListener( rectangleB->onMouseReleased, this, &ofApp::vuiEventHandler ); 186 | ofAddListener( rectangleB->onMouseClick, this, &ofApp::vuiEventHandler ); 187 | ofAddListener( rectangleB->onMouseDoubleClick, this, &ofApp::vuiEventHandler ); 188 | 189 | /* 190 | ofAddListener( textField->onMouseOver, this, &ofApp::vuiEventHandler ); 191 | ofAddListener( textField->onMouseOut, this, &ofApp::vuiEventHandler ); 192 | ofAddListener( textField->onMousePressed, this, &ofApp::vuiEventHandler ); 193 | ofAddListener( textField->onMouseMoved, this, &ofApp::vuiEventHandler ); 194 | ofAddListener( textField->onMouseDragged, this, &ofApp::vuiEventHandler ); 195 | ofAddListener( textField->onMouseReleased, this, &ofApp::vuiEventHandler ); 196 | ofAddListener( textField->onMouseClick, this, &ofApp::vuiEventHandler ); 197 | ofAddListener( textField->onMouseDoubleClick, this, &ofApp::vuiEventHandler ); 198 | 199 | */ 200 | 201 | } 202 | 203 | void ofApp::vuiEventHandler(vuiEventArgs& evt){ 204 | 205 | string s = "[" + evt.element->GetName() + "] "; 206 | 207 | 208 | switch( evt.eventType ){ 209 | case VUI_EVENT_STATE_CHANGE: 210 | /* 211 | 212 | So virtual state is the state that it should be in: UP, OVER, DOWN 213 | But if you don't style the OVER or DOWN state manually, it won't be rendered. 214 | Like if you use elementPtr->MakeToggle() it doesn't automatically style an OVER/DOWN 215 | state for you, you need to do that yourself bc you should get in the habit of doing so. 216 | 217 | */ 218 | 219 | s += "VUI_EVENT_STATE_CHANGE renderState:" + ofToString(evt.renderState) + " virtualState:" + ofToString(evt.virtualState); 220 | StoreLog(s); 221 | //ofLog() << s; 222 | return; 223 | case VUI_EVENT_FOCUS: 224 | s += "VUI_EVENT_FOCUS"; 225 | StoreLog(s); 226 | //ofLog() << s; 227 | return; 228 | break; 229 | case VUI_EVENT_UNFOCUS: 230 | s += "VUI_EVENT_UNFOCUS"; 231 | StoreLog(s); 232 | //ofLog() << s; 233 | return; 234 | break; 235 | case VUI_EVENT_TEXT_CHANGE: 236 | s += "VUI_EVENT_TEXT_CHANGE text:" + evt.text; 237 | StoreLog(s); 238 | //ofLog() << s; 239 | return; 240 | break; 241 | case VUI_EVENT_VALUE_CHANGE: 242 | s += "VUI_EVENT_VALUE_CHANGE value:" + ofToString(evt.value); 243 | StoreLog(s); 244 | //ofLog() << s; 245 | return; 246 | break; 247 | case VUI_EVENT_SUBMIT: 248 | s += "VUI_EVENT_SUBMIT text:" + evt.text; 249 | StoreLog(s); 250 | //ofLog() << s; 251 | return; 252 | break; 253 | case VUI_EVENT_MOUSE_OVER: 254 | s += "VUI_EVENT_MOUSE_OVER"; 255 | break; 256 | case VUI_EVENT_MOUSE_OUT: 257 | s += "VUI_EVENT_MOUSE_OUT"; 258 | break; 259 | case VUI_EVENT_MOUSE_PRESSED: 260 | s += "VUI_EVENT_MOUSE_PRESSED"; 261 | break; 262 | case VUI_EVENT_MOUSE_MOVED: 263 | s += "VUI_EVENT_MOUSE_MOVED"; 264 | break; 265 | case VUI_EVENT_MOUSE_DRAGGED: 266 | s += "VUI_EVENT_MOUSE_DRAGGED dragStart:" + ofToString(evt.localDragStart.x) + "," + ofToString(evt.localDragStart.y) + " dragDelta:" + ofToString(evt.localDragDelta.x) + "," + ofToString(evt.localDragDelta.y); 267 | break; 268 | case VUI_EVENT_MOUSE_RELEASED: 269 | s += "VUI_EVENT_MOUSE_RELEASED"; 270 | break; 271 | case VUI_EVENT_MOUSE_CLICK: 272 | s += "VUI_EVENT_MOUSE_CLICK"; 273 | break; 274 | case VUI_EVENT_MOUSE_DOUBLE_CLICK: 275 | s += "VUI_EVENT_MOUSE_DOUBLE_CLICK"; 276 | break; 277 | } 278 | 279 | s += " local:" + ofToString(evt.localMousePos.x) + "," + ofToString(evt.localMousePos.y) + " global:" + ofToString(evt.globalMousePos.x) + "," + ofToString(evt.globalMousePos.y); 280 | 281 | StoreLog(s); 282 | 283 | //ofLog() << s << " local:" << evt.localMousePos.x << "," << evt.localMousePos.y << " global:" << evt.globalMousePos.x << "," << evt.globalMousePos.y; 284 | } 285 | 286 | //-------------------------------------------------------------- 287 | void ofApp::update(){ 288 | ofSetWindowTitle( ofToString(ofGetFrameRate()) ); 289 | } 290 | 291 | //-------------------------------------------------------------- 292 | void ofApp::draw(){ 293 | ofSetColor(255,255,255,255); 294 | 295 | // 296 | 297 | square->Render(); 298 | rectangle->Render(); 299 | rectangleB->Render(); 300 | textField->Render(); 301 | text->Render(); 302 | 303 | preToggle->Render(); 304 | postToggle->Render(); 305 | 306 | 307 | // logs 308 | 309 | int i = 0; 310 | int gray = 0; 311 | int g2 = 255; 312 | ofColor c; 313 | ofColor t; 314 | 315 | for ( vector::iterator it = logs.begin(); it != logs.end(); it++){ 316 | c.set(gray, gray, gray); 317 | t.set(g2, g2, g2); 318 | 319 | if ( i == 0 ) ofDrawBitmapStringHighlight( (*it), 20, 590 + i*20, c, t ); 320 | else ofDrawBitmapStringHighlight( (*it), 20, 610 + i*20, c, t ); 321 | i++; 322 | gray += 48; 323 | g2 -= 10; 324 | } 325 | } 326 | 327 | //-------------------------------------------------------------- 328 | void ofApp::keyPressed(int key){ 329 | 330 | } 331 | 332 | //-------------------------------------------------------------- 333 | void ofApp::keyReleased(int key){ 334 | 335 | } 336 | 337 | //-------------------------------------------------------------- 338 | void ofApp::mouseMoved(int x, int y ){ 339 | 340 | } 341 | 342 | //-------------------------------------------------------------- 343 | void ofApp::mouseDragged(int x, int y, int button){ 344 | 345 | } 346 | 347 | //-------------------------------------------------------------- 348 | void ofApp::mousePressed(int x, int y, int button){ 349 | 350 | } 351 | 352 | //-------------------------------------------------------------- 353 | void ofApp::mouseReleased(int x, int y, int button){ 354 | 355 | } 356 | 357 | //-------------------------------------------------------------- 358 | void ofApp::mouseEntered(int x, int y){ 359 | 360 | } 361 | 362 | //-------------------------------------------------------------- 363 | void ofApp::mouseExited(int x, int y){ 364 | 365 | } 366 | 367 | //-------------------------------------------------------------- 368 | void ofApp::windowResized(int w, int h){ 369 | 370 | } 371 | 372 | //-------------------------------------------------------------- 373 | void ofApp::gotMessage(ofMessage msg){ 374 | 375 | } 376 | 377 | //-------------------------------------------------------------- 378 | void ofApp::dragEvent(ofDragInfo dragInfo){ 379 | 380 | } 381 | -------------------------------------------------------------------------------- /example-Events/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxVui.h" 5 | 6 | using namespace VUI; 7 | 8 | class ofApp : public ofBaseApp{ 9 | 10 | public: 11 | void setup(); 12 | void update(); 13 | void draw(); 14 | 15 | void keyPressed(int key); 16 | void keyReleased(int key); 17 | void mouseMoved(int x, int y ); 18 | void mouseDragged(int x, int y, int button); 19 | void mousePressed(int x, int y, int button); 20 | void mouseReleased(int x, int y, int button); 21 | void mouseEntered(int x, int y); 22 | void mouseExited(int x, int y); 23 | void windowResized(int w, int h); 24 | void dragEvent(ofDragInfo dragInfo); 25 | void gotMessage(ofMessage msg); 26 | 27 | // 28 | 29 | void vuiEventHandler(vuiEventArgs& evt); 30 | 31 | // 32 | 33 | Element* square; 34 | Element* rectangle; 35 | Element* rectangleB; 36 | 37 | // 38 | 39 | Element* preToggle; 40 | Element* postToggle; 41 | 42 | // 43 | 44 | TextField* textField; 45 | Text* text; 46 | StyleSheet* ss; 47 | 48 | // 49 | 50 | vector logs; 51 | 52 | void StoreLog(string log){ 53 | vector::iterator it = logs.begin(); 54 | logs.insert( it, log ); 55 | 56 | if ( logs.size() > 5 ) logs.pop_back(); 57 | } 58 | 59 | }; 60 | -------------------------------------------------------------------------------- /example-StylingElements/addons.make: -------------------------------------------------------------------------------- 1 | ofxEasing 2 | ofxVui 3 | -------------------------------------------------------------------------------- /example-StylingElements/bin/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | *.exp 4 | *.lib 5 | *.ilk 6 | *.pdb -------------------------------------------------------------------------------- /example-StylingElements/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-StylingElements/bin/data/.gitkeep -------------------------------------------------------------------------------- /example-StylingElements/bin/data/img/grunge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-StylingElements/bin/data/img/grunge.jpg -------------------------------------------------------------------------------- /example-StylingElements/bin/data/img/union.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-StylingElements/bin/data/img/union.jpg -------------------------------------------------------------------------------- /example-StylingElements/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1280, 720, OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | } 13 | -------------------------------------------------------------------------------- /example-StylingElements/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetFrameRate(60); 6 | 7 | string styles = R"( 8 | 9 | [Images> 10 | grunge: img/grunge.jpg; 11 | illustration: img/union.jpg; 12 | ] 13 | 14 | [.baseClass> 15 | width: 160; 16 | height: 60; 17 | bg: #ff0000; 18 | border: 1, #ffffff; 19 | 20 | &:over { 21 | bg: #405c6c; 22 | border: 2, #00ffff; 23 | } 24 | 25 | &:down { 26 | background-color: #7ccbf9; 27 | } 28 | ] 29 | 30 | 31 | 32 | [#leftTop> 33 | border: 1, #fff600, ALL; 34 | bgImage: illustration, 0, 130; 35 | &:over{ 36 | border-left: 5, #f907df; 37 | bgImage: illustration, 160, 130; 38 | } 39 | &:down{ 40 | bgImage: illustration, 320, 130; 41 | } 42 | ] 43 | 44 | [#leftCenter> 45 | anchorPoint: left-center; 46 | bgImage: illustration, 210, 130, ALL; 47 | &:over{ 48 | border-left: 5, #f907df; 49 | } 50 | ] 51 | 52 | [#leftBottom> 53 | anchorPoint: left-bottom; 54 | bgImage: illustration, FILL; 55 | &:over{ 56 | border-left: 5, #f907df; 57 | bgImage: grunge, FILL; 58 | } 59 | 60 | &:down{ 61 | bgImage: grunge, 50, 50, 400, 50; 62 | } 63 | ] 64 | 65 | 66 | 67 | [#centerTop> 68 | anchorPoint: center-top; 69 | opacity: .1; 70 | &:over{ 71 | border-top: 5, #f907df; 72 | } 73 | ] 74 | 75 | [#centerCenter> 76 | anchorPoint: center-center; 77 | width: 200; 78 | height: 200; 79 | scale: .5; 80 | rotation: 45; 81 | bg: #ffff00; 82 | border: clear; 83 | 84 | &:over{ 85 | opacity: .2; 86 | } 87 | ] 88 | 89 | [#centerBottom> 90 | 91 | anchorPoint: center-bottom; 92 | &:over{ 93 | border-bottom: 5, #f907df; 94 | } 95 | &:down{ 96 | opacity: .25; 97 | } 98 | ] 99 | 100 | 101 | 102 | [#rightTop> 103 | anchorPoint: right-top; 104 | &:over{ 105 | border-right: 5, #f907df; 106 | } 107 | ] 108 | 109 | [#rightCenter> 110 | anchorPoint: right-center; 111 | &:over{ 112 | border-right: 5, #f907df; 113 | } 114 | ] 115 | 116 | [#rightBottom> 117 | anchorPoint: right-bottom; 118 | opacity: .1, ALL; 119 | &:over{ 120 | border-right: 5, #f907df; 121 | } 122 | ] 123 | 124 | )"; 125 | 126 | ss = new StyleSheet( styles ); 127 | 128 | 129 | //-------------------------------------------------------------- STYLES 130 | /* 131 | 132 | SYNTAX 133 | 134 | [Images> 135 | imageID: filepath; 136 | ] 137 | 138 | [.styleClass> 139 | (styles) 140 | ] 141 | 142 | [#styleID> 143 | (styles) 144 | ] 145 | 146 | 147 | The primary styleClass/ID is applied to ALL states. 148 | • VUI_STATE_UP 149 | • VUI_STATE_OVER 150 | • VUI_STATE_DOWN 151 | 152 | 153 | The secondary style class/ID overrides properties for specific states. 154 | Some properties have an ALL flag that will override ALL states to make 155 | it behave like a primary styleClass/ID. 156 | • opacity 157 | • border 158 | • background-image 159 | 160 | 161 | -------------------------------------------------------------- 162 | 163 | • width (applies to all states) 164 | • height (applies to all states) 165 | 166 | • color text #hexColor 167 | • font fontFilepath, fontSize 168 | • scale 169 | • opacity 0.0 - 1.0, ALL (optional) 170 | • rotation 171 | 172 | 173 | • background-image imageID, FIT -or- imageID (, sx, sy, sw, sh) 174 | + bg-image 175 | + backgroundImage 176 | + bgImage 177 | 178 | 179 | • background-color #hexColor -or- "clear" 180 | + backgroundColor 181 | + bgColor 182 | + bg 183 | 184 | 185 | • anchor-point 186 | + anchorPoint 187 | 188 | 189 | • border thickness, #hexColor, ALL (optional) -or- "clear" (turns border off) 190 | ∟ border-top 191 | ∟ border-right 192 | ∟ border-bottom 193 | ∟ border-left 194 | 195 | 196 | • offset (not based on anchorPoint, from left-top position) 197 | ∟ offset-x 198 | ∟ offset-y 199 | 200 | 201 | • padding for text / textFields, adds to textAligned position (be mindful) 202 | ∟ padding-x 203 | ∟ padding-y 204 | 205 | 206 | • text-align 207 | + textAlign 208 | 209 | VALUES for text-align and anchor-point 210 | - left-top 211 | - left-center 212 | - left-bottom 213 | - center-top 214 | - center-center 215 | - center-bottom 216 | - right-top 217 | - right-center 218 | - right-bottom 219 | 220 | 221 | 222 | -------------------------------------------------------------- 223 | 224 | STATES - must be appended to end of style block 225 | • &:over{} 226 | • &:down{} 227 | 228 | 229 | 230 | */ 231 | 232 | //-------------------------------------------------------------- 233 | 234 | 235 | leftTop = new Element( 0,0, ss, ".baseClass", "#leftTop" ); 236 | leftCenter = new Element( 0, ofGetHeight()*.5, ss, ".baseClass", "#leftCenter" ); 237 | leftBottom = new Element( 0, ofGetHeight(), ss, ".baseClass", "#leftBottom" ); 238 | 239 | centerTop = new Element( ofGetWidth()*.5,0, ss, ".baseClass", "#centerTop" ); 240 | centerCenter = new Element( ofGetWidth()*.5,ofGetHeight()*.5, ss, ".baseClass", "#centerCenter" ); 241 | centerBottom = new Element( ofGetWidth()*.5,ofGetHeight(), ss, ".baseClass", "#centerBottom" ); 242 | 243 | rightTop = new Element( ofGetWidth(),0, ss, ".baseClass", "#rightTop" ); 244 | rightCenter = new Element( ofGetWidth(),ofGetHeight()*.5, ss, ".baseClass", "#rightCenter" ); 245 | rightBottom = new Element( ofGetWidth(),ofGetHeight(), ss, ".baseClass", "#rightBottom" ); 246 | 247 | 248 | 249 | //-------------------------------------------------------------- BORDERS 250 | 251 | // Normal rendering order is "border-top", "border-bottom", "border-left", "border-right" 252 | // Uncomment lines below to see difference on OVER state 253 | 254 | //centerTop->SetBorderRenderingOrder( "border-left", "border-right", "border-top", "border-bottom" ); 255 | //centerBottom->SetBorderRenderingOrder( "border-left", "border-right", "border-top", "border-bottom" ); 256 | 257 | 258 | } 259 | 260 | //-------------------------------------------------------------- 261 | void ofApp::update(){ 262 | ofSetWindowTitle( ofToString(ofGetFrameRate()) ); 263 | } 264 | 265 | //-------------------------------------------------------------- 266 | void ofApp::draw(){ 267 | leftTop->Render(); 268 | leftCenter->Render(); 269 | leftBottom->Render(); 270 | 271 | centerTop->Render(); 272 | centerCenter->Render(); 273 | centerBottom->Render(); 274 | 275 | rightTop->Render(); 276 | rightCenter->Render(); 277 | rightBottom->Render(); 278 | } 279 | 280 | //-------------------------------------------------------------- 281 | void ofApp::keyPressed(int key){ 282 | 283 | } 284 | 285 | //-------------------------------------------------------------- 286 | void ofApp::keyReleased(int key){ 287 | 288 | } 289 | 290 | //-------------------------------------------------------------- 291 | void ofApp::mouseMoved(int x, int y ){ 292 | 293 | } 294 | 295 | //-------------------------------------------------------------- 296 | void ofApp::mouseDragged(int x, int y, int button){ 297 | 298 | } 299 | 300 | //-------------------------------------------------------------- 301 | void ofApp::mousePressed(int x, int y, int button){ 302 | 303 | } 304 | 305 | //-------------------------------------------------------------- 306 | void ofApp::mouseReleased(int x, int y, int button){ 307 | 308 | } 309 | 310 | //-------------------------------------------------------------- 311 | void ofApp::mouseEntered(int x, int y){ 312 | 313 | } 314 | 315 | //-------------------------------------------------------------- 316 | void ofApp::mouseExited(int x, int y){ 317 | 318 | } 319 | 320 | //-------------------------------------------------------------- 321 | void ofApp::windowResized(int w, int h){ 322 | 323 | } 324 | 325 | //-------------------------------------------------------------- 326 | void ofApp::gotMessage(ofMessage msg){ 327 | 328 | } 329 | 330 | //-------------------------------------------------------------- 331 | void ofApp::dragEvent(ofDragInfo dragInfo){ 332 | 333 | } 334 | -------------------------------------------------------------------------------- /example-StylingElements/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxVui.h" 5 | 6 | using namespace VUI; 7 | 8 | class ofApp : public ofBaseApp{ 9 | 10 | public: 11 | void setup(); 12 | void update(); 13 | void draw(); 14 | 15 | void keyPressed(int key); 16 | void keyReleased(int key); 17 | void mouseMoved(int x, int y ); 18 | void mouseDragged(int x, int y, int button); 19 | void mousePressed(int x, int y, int button); 20 | void mouseReleased(int x, int y, int button); 21 | void mouseEntered(int x, int y); 22 | void mouseExited(int x, int y); 23 | void windowResized(int w, int h); 24 | void dragEvent(ofDragInfo dragInfo); 25 | void gotMessage(ofMessage msg); 26 | 27 | Element* leftTop; 28 | Element* leftCenter; 29 | Element* leftBottom; 30 | Element* centerTop; 31 | Element* centerCenter; 32 | Element* centerBottom; 33 | Element* rightTop; 34 | Element* rightCenter; 35 | Element* rightBottom; 36 | 37 | StyleSheet* ss; 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /example-TouchEvents/addons.make: -------------------------------------------------------------------------------- 1 | ofxEasing 2 | ofxVui 3 | ofxWinTouchHook 4 | -------------------------------------------------------------------------------- /example-TouchEvents/bin/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | *.exp 4 | *.lib 5 | *.ilk 6 | *.pdb -------------------------------------------------------------------------------- /example-TouchEvents/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-TouchEvents/bin/data/.gitkeep -------------------------------------------------------------------------------- /example-TouchEvents/bin/data/Gotham-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-TouchEvents/bin/data/Gotham-Medium.otf -------------------------------------------------------------------------------- /example-TouchEvents/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | #include "ofxVui.h" 4 | 5 | //======================================================================== 6 | int main( ){ 7 | ofSetupOpenGL(1280, 720, OF_WINDOW); // <-------- setup the GL context 8 | 9 | // this kicks off the running of my app 10 | // can be OF_WINDOW or OF_FULLSCREEN 11 | // pass in width and height too: 12 | ofRunApp(new ofApp()); 13 | } 14 | -------------------------------------------------------------------------------- /example-TouchEvents/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetFrameRate(60); 6 | 7 | /* 8 | This only works on Windows. To use this you have to: 9 | • add ofxWinTouchHook addon - https://github.com/trentbrooks/ofxWinTouchHook 10 | • add Preprocessor Macro "USING_ofxWinTouchHook" 11 | */ 12 | 13 | VUI::EnableTouch(); 14 | 15 | string styles = R"( 16 | [#square> 17 | 18 | width: 400; 19 | height: 400; 20 | background-color: #ff0000; 21 | anchorPoint: center-center; 22 | 23 | &:over { 24 | background-color: #00ff00; 25 | } 26 | 27 | &:down { 28 | background-color: #0000ff; 29 | } 30 | ] 31 | 32 | [#rectangle> 33 | 34 | width: 200; 35 | height: 60; 36 | background-color: #ffffff; 37 | anchorPoint: center-center; 38 | 39 | &:over { 40 | background-color: #00ff00; 41 | } 42 | 43 | &:down { 44 | background-color: #0000ff; 45 | } 46 | ] 47 | 48 | [#textField> 49 | width: 240; 50 | height: 36; 51 | background-color: #aeaeae; 52 | font: Gotham-Medium.otf,13; 53 | text-align: left-center; 54 | color: #000000; 55 | padding-left: 10; 56 | 57 | &:over{ 58 | background-color: #7cf9ae; 59 | } 60 | 61 | &:down{ 62 | background-color: #00ff00; 63 | } 64 | ] 65 | 66 | [#text> 67 | font: Gotham-Medium.otf,13; 68 | ] 69 | 70 | [.toggle> 71 | width: 80; 72 | height: 32; 73 | background-color: #a2e3f3; 74 | 75 | &:over { 76 | background-color: #f879fd; 77 | } 78 | 79 | &:down { 80 | background-color: #43df6c; 81 | } 82 | ] 83 | 84 | 85 | )"; 86 | 87 | ss = new StyleSheet( styles ); 88 | text = new Text( 50, 50, ss, "#text" ); 89 | text->SetText("text"); 90 | 91 | textField = new TextField( 50, 100, ss, "#textField" ); 92 | textField->SetText("omg textfield"); 93 | 94 | square = new Element( 760, ofGetHeight()*.5, ss, "#square" ); 95 | rectangle = new Element( 760, ofGetHeight()*.5, ss, "#rectangle" ); 96 | 97 | // 98 | 99 | preToggle = new Element( 50, 160, ss, ".toggle" ); 100 | 101 | postToggle = new Element( 50, 200, ss, ".toggle" ); 102 | postToggle->MakeToggle(); 103 | 104 | 105 | // ------------------------------------------------------------------- Toggle EVENTS 106 | ofAddListener( postToggle->onValueChange, this, &ofApp::vuiEventHandler ); 107 | 108 | 109 | // ------------------------------------------------------------------- TextField EVENTS 110 | ofAddListener( textField->onFocus, this, &ofApp::vuiEventHandler ); 111 | ofAddListener( textField->onUnfocus, this, &ofApp::vuiEventHandler ); 112 | ofAddListener( textField->onTextChange, this, &ofApp::vuiEventHandler ); 113 | ofAddListener( textField->onSubmit, this, &ofApp::vuiEventHandler ); 114 | 115 | 116 | // ------------------------------------------------------------------- Touch EVENTS 117 | /* 118 | VUI_EVENT_TOUCH_DOWN 119 | VUI_EVENT_TOUCH_UP 120 | VUI_EVENT_TOUCH_TAP 121 | VUI_EVENT_TOUCH_DOUBLE_TAP 122 | */ 123 | 124 | ofAddListener( square->onTouchDown, this, &ofApp::vuiEventHandler ); 125 | ofAddListener( square->onTouchUp, this, &ofApp::vuiEventHandler ); 126 | ofAddListener( square->onTouchTap, this, &ofApp::vuiEventHandler ); 127 | ofAddListener( square->onTouchDoubleTap, this, &ofApp::vuiEventHandler ); 128 | 129 | ofAddListener( rectangle->onTouchDown, this, &ofApp::vuiEventHandler ); 130 | ofAddListener( rectangle->onTouchUp, this, &ofApp::vuiEventHandler ); 131 | ofAddListener( rectangle->onTouchTap, this, &ofApp::vuiEventHandler ); 132 | ofAddListener( rectangle->onTouchDoubleTap, this, &ofApp::vuiEventHandler ); 133 | 134 | 135 | // ------------------------------------------------------------------- Mouse EVENTS 136 | /* 137 | VUI_EVENT_MOUSE_OVER 138 | VUI_EVENT_MOUSE_OUT 139 | VUI_EVENT_MOUSE_PRESSED 140 | VUI_EVENT_MOUSE_MOVED 141 | VUI_EVENT_MOUSE_DRAGGED 142 | VUI_EVENT_MOUSE_RELEASED 143 | VUI_EVENT_MOUSE_CLICK 144 | VUI_EVENT_MOUSE_DOUBLE_CLICK 145 | 146 | */ 147 | 148 | // Uncomment this if you want to see Mouse and Touch events 149 | /* 150 | 151 | ofAddListener(square->onMouseOver, this, &ofApp::vuiEventHandler); 152 | ofAddListener(square->onMouseOut, this, &ofApp::vuiEventHandler); 153 | ofAddListener(square->onMousePressed, this, &ofApp::vuiEventHandler); 154 | ofAddListener(square->onMouseMoved, this, &ofApp::vuiEventHandler); 155 | ofAddListener(square->onMouseDragged, this, &ofApp::vuiEventHandler); 156 | ofAddListener(square->onMouseReleased, this, &ofApp::vuiEventHandler); 157 | ofAddListener(square->onMouseClick, this, &ofApp::vuiEventHandler); 158 | ofAddListener(square->onMouseDoubleClick, this, &ofApp::vuiEventHandler); 159 | 160 | ofAddListener( rectangle->onMouseOver, this, &ofApp::vuiEventHandler ); 161 | ofAddListener( rectangle->onMouseOut, this, &ofApp::vuiEventHandler ); 162 | ofAddListener( rectangle->onMousePressed, this, &ofApp::vuiEventHandler ); 163 | ofAddListener( rectangle->onMouseMoved, this, &ofApp::vuiEventHandler ); 164 | ofAddListener( rectangle->onMouseDragged, this, &ofApp::vuiEventHandler ); 165 | ofAddListener( rectangle->onMouseReleased, this, &ofApp::vuiEventHandler ); 166 | ofAddListener( rectangle->onMouseClick, this, &ofApp::vuiEventHandler ); 167 | ofAddListener( rectangle->onMouseDoubleClick, this, &ofApp::vuiEventHandler ); 168 | 169 | ofAddListener( textField->onMouseOver, this, &ofApp::vuiEventHandler ); 170 | ofAddListener( textField->onMouseOut, this, &ofApp::vuiEventHandler ); 171 | ofAddListener( textField->onMousePressed, this, &ofApp::vuiEventHandler ); 172 | ofAddListener( textField->onMouseMoved, this, &ofApp::vuiEventHandler ); 173 | ofAddListener( textField->onMouseDragged, this, &ofApp::vuiEventHandler ); 174 | ofAddListener( textField->onMouseReleased, this, &ofApp::vuiEventHandler ); 175 | ofAddListener( textField->onMouseClick, this, &ofApp::vuiEventHandler ); 176 | ofAddListener( textField->onMouseDoubleClick, this, &ofApp::vuiEventHandler ); 177 | 178 | */ 179 | 180 | } 181 | 182 | void ofApp::vuiEventHandler(vuiEventArgs& evt){ 183 | 184 | string s = "[" + evt.element->GetName() + "] "; 185 | 186 | switch( evt.eventType ){ 187 | case VUI_EVENT_FOCUS: 188 | s += "VUI_EVENT_FOCUS"; 189 | ofLog() << s; 190 | return; 191 | break; 192 | case VUI_EVENT_UNFOCUS: 193 | s += "VUI_EVENT_UNFOCUS"; 194 | ofLog() << s; 195 | return; 196 | break; 197 | case VUI_EVENT_TEXT_CHANGE: 198 | s += "VUI_EVENT_TEXT_CHANGE text:" + evt.text; 199 | ofLog() << s; 200 | return; 201 | break; 202 | case VUI_EVENT_VALUE_CHANGE: 203 | s += "VUI_EVENT_VALUE_CHANGE value:" + ofToString(evt.value); 204 | ofLog() << s; 205 | return; 206 | break; 207 | case VUI_EVENT_SUBMIT: 208 | s += "VUI_EVENT_SUBMIT text:" + evt.text; 209 | ofLog() << s; 210 | return; 211 | break; 212 | case VUI_EVENT_MOUSE_OVER: 213 | s += "VUI_EVENT_MOUSE_OVER"; 214 | break; 215 | case VUI_EVENT_MOUSE_OUT: 216 | s += "VUI_EVENT_MOUSE_OUT"; 217 | break; 218 | case VUI_EVENT_MOUSE_PRESSED: 219 | s += "VUI_EVENT_MOUSE_PRESSED"; 220 | break; 221 | case VUI_EVENT_MOUSE_MOVED: 222 | s += "VUI_EVENT_MOUSE_MOVED"; 223 | break; 224 | case VUI_EVENT_MOUSE_DRAGGED: 225 | s += "VUI_EVENT_MOUSE_DRAGGED dragStart:" + ofToString(evt.localDragStart.x) + "," + ofToString(evt.localDragStart.y) + " dragDelta:" + ofToString(evt.localDragDelta.x) + "," + ofToString(evt.localDragDelta.y); 226 | break; 227 | case VUI_EVENT_MOUSE_RELEASED: 228 | s += "VUI_EVENT_MOUSE_RELEASED"; 229 | break; 230 | case VUI_EVENT_MOUSE_CLICK: 231 | s += "VUI_EVENT_MOUSE_CLICK"; 232 | break; 233 | case VUI_EVENT_MOUSE_DOUBLE_CLICK: 234 | s += "VUI_EVENT_MOUSE_DOUBLE_CLICK"; 235 | break; 236 | case VUI_EVENT_TOUCH_DOWN: 237 | s += "VUI_EVENT_TOUCH_DOWN"; 238 | break; 239 | case VUI_EVENT_TOUCH_UP: 240 | s += "VUI_EVENT_TOUCH_UP"; 241 | break; 242 | case VUI_EVENT_TOUCH_TAP: 243 | s += "VUI_EVENT_TOUCH_TAP"; 244 | break; 245 | case VUI_EVENT_TOUCH_DOUBLE_TAP: 246 | s += "VUI_EVENT_TOUCH_DOUBLE_TAP"; 247 | break; 248 | } 249 | 250 | ofLog() << s << " local:" << evt.localMousePos.x << "," << evt.localMousePos.y << " global:" << evt.globalMousePos.x << "," << evt.globalMousePos.y; 251 | } 252 | 253 | //-------------------------------------------------------------- 254 | void ofApp::update(){ 255 | ofSetWindowTitle( ofToString(ofGetFrameRate()) ); 256 | } 257 | 258 | //-------------------------------------------------------------- 259 | void ofApp::draw(){ 260 | square->Render(); 261 | rectangle->Render(); 262 | textField->Render(); 263 | text->Render(); 264 | 265 | preToggle->Render(); 266 | postToggle->Render(); 267 | } 268 | 269 | //-------------------------------------------------------------- 270 | void ofApp::keyPressed(int key){ 271 | 272 | } 273 | 274 | //-------------------------------------------------------------- 275 | void ofApp::keyReleased(int key){ 276 | 277 | } 278 | 279 | //-------------------------------------------------------------- 280 | void ofApp::mouseMoved(int x, int y ){ 281 | 282 | } 283 | 284 | //-------------------------------------------------------------- 285 | void ofApp::mouseDragged(int x, int y, int button){ 286 | 287 | } 288 | 289 | //-------------------------------------------------------------- 290 | void ofApp::mousePressed(int x, int y, int button){ 291 | 292 | } 293 | 294 | //-------------------------------------------------------------- 295 | void ofApp::mouseReleased(int x, int y, int button){ 296 | 297 | } 298 | 299 | //-------------------------------------------------------------- 300 | void ofApp::mouseEntered(int x, int y){ 301 | 302 | } 303 | 304 | //-------------------------------------------------------------- 305 | void ofApp::mouseExited(int x, int y){ 306 | 307 | } 308 | 309 | //-------------------------------------------------------------- 310 | void ofApp::windowResized(int w, int h){ 311 | 312 | } 313 | 314 | //-------------------------------------------------------------- 315 | void ofApp::gotMessage(ofMessage msg){ 316 | 317 | } 318 | 319 | //-------------------------------------------------------------- 320 | void ofApp::dragEvent(ofDragInfo dragInfo){ 321 | 322 | } 323 | -------------------------------------------------------------------------------- /example-TouchEvents/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxVui.h" 5 | 6 | using namespace VUI; 7 | 8 | class ofApp : public ofBaseApp{ 9 | 10 | public: 11 | void setup(); 12 | void update(); 13 | void draw(); 14 | 15 | void keyPressed(int key); 16 | void keyReleased(int key); 17 | void mouseMoved(int x, int y ); 18 | void mouseDragged(int x, int y, int button); 19 | void mousePressed(int x, int y, int button); 20 | void mouseReleased(int x, int y, int button); 21 | void mouseEntered(int x, int y); 22 | void mouseExited(int x, int y); 23 | void windowResized(int w, int h); 24 | void dragEvent(ofDragInfo dragInfo); 25 | void gotMessage(ofMessage msg); 26 | 27 | // 28 | 29 | void vuiEventHandler(vuiEventArgs& evt); 30 | 31 | Element* square; 32 | Element* rectangle; 33 | 34 | Element* preToggle; 35 | Element* postToggle; 36 | 37 | TextField* textField; 38 | Text* text; 39 | StyleSheet* ss; 40 | 41 | }; 42 | -------------------------------------------------------------------------------- /example-ViewManager/addons.make: -------------------------------------------------------------------------------- 1 | ofxEasing 2 | ofxVui 3 | -------------------------------------------------------------------------------- /example-ViewManager/bin/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | *.exp 4 | *.lib 5 | *.ilk 6 | *.pdb -------------------------------------------------------------------------------- /example-ViewManager/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-ViewManager/bin/data/.gitkeep -------------------------------------------------------------------------------- /example-ViewManager/bin/data/Gotham-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/example-ViewManager/bin/data/Gotham-Medium.otf -------------------------------------------------------------------------------- /example-ViewManager/src/ViewA.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef __ViewA__ 3 | #define __ViewA__ 4 | 5 | #include "ofMain.h" 6 | #include "ofxVui.h" 7 | 8 | using namespace VUI; 9 | 10 | class ViewA : public View { 11 | public: 12 | ~ViewA() {}; 13 | ViewA() {}; 14 | 15 | // 16 | 17 | StyleSheet* ss; 18 | 19 | Text* label; 20 | Text* resolution; 21 | 22 | Text* btnViewB; 23 | Text* btnViewBTriggerExit; 24 | 25 | Element* box; 26 | 27 | // 28 | 29 | void setup() { 30 | // ------------------------------------------------------------------ styling 31 | string styles = R"( 32 | 33 | [.view-label> 34 | width: 200; 35 | height: 60; 36 | font: Gotham-Medium.otf,{{font-size}}; 37 | color: #ffffff; 38 | padding: 6; 39 | ] 40 | 41 | [.resolution> 42 | width: 340; 43 | height: 30; 44 | font: Gotham-Medium.otf,{{font-size}}; 45 | color: #ffffff; 46 | anchorPoint: right-bottom; 47 | textAlign: right-bottom; 48 | ] 49 | 50 | [.btn-setView> 51 | width: 400; 52 | height: 60; 53 | background-color: #ffffff; 54 | color: #000000; 55 | textAlign: center-center; 56 | font: Gotham-Medium.otf,18; 57 | 58 | &:over { 59 | background-color: #a5e5f3; 60 | } 61 | 62 | &:down { 63 | background-color: #7cf9ae; 64 | } 65 | ] 66 | 67 | [.box> 68 | width: 200; 69 | height: 200; 70 | background-color: #f422e3; 71 | anchorPoint: center-center; 72 | ] 73 | 74 | [#boxB> 75 | background-color: #fff227; 76 | ] 77 | 78 | )"; 79 | // ------------------------------------------------------------------ 80 | 81 | // scale font size so it's the same size regardless of what scale VUI resolution is (in main.cpp) 82 | ofStringReplace( styles, "{{font-size}}", ofToString(12*VUI::GetScale(true)) ); 83 | 84 | // create new stylesheet and name/store it for global usage 85 | ss = new StyleSheet( styles, "ViewAStyles" ); 86 | 87 | // view name 88 | label = new Text( 20, 20, ss, ".view-label" ); 89 | label->SetText( "View A" ); 90 | 91 | // resolution (in main.cpp) 92 | resolution = new Text( VUI::GetResolutionX() - 20, VUI::GetResolutionY() - 20, ss, ".resolution" ); 93 | resolution->SetText( ofToString(VUI::GetResolutionX()) + "x" + ofToString(VUI::GetResolutionY()) + " scale=" + ofToString(VUI::GetScale()) ); 94 | 95 | // buttonZ 96 | btnViewB = new Text( 300, 120, ss, ".btn-setView" ); 97 | btnViewB->SetText( "SetView(\"view-b\")" ); 98 | 99 | // debugging 100 | btnViewB->SetName( "btnViewB" ); 101 | 102 | btnViewBTriggerExit = new Text( 300, 120 + 60 + 10, ss, ".btn-setView" ); 103 | btnViewBTriggerExit->SetText( "SetView(\"view-b\", true)" ); 104 | 105 | // events 106 | ofAddListener( btnViewB->onMouseClick, this, &ViewA::vuiEventHandler ); 107 | ofAddListener( btnViewBTriggerExit->onMouseClick, this, &ViewA::vuiEventHandler ); 108 | 109 | // exit animation element 110 | box = new Element( 400, 400, ss, ".box" ); 111 | } 112 | 113 | void vuiEventHandler(vuiEventArgs& evt) { 114 | if ( evt.eventType == VUI_EVENT_MOUSE_CLICK ){ 115 | if ( evt.element == btnViewB ) VUI::SetView( "view-b" ); 116 | else if ( evt.element == btnViewBTriggerExit ) VUI::SetView( "view-b", true ); 117 | } 118 | 119 | if ( evt.element == box ){ 120 | // must call ExitView() if overriding BeforeExitView() 121 | if ( evt.eventType == VUI_EVENT_ANIMATE_COMPLETE ) ExitView(); 122 | } 123 | } 124 | 125 | void update() { 126 | 127 | } 128 | 129 | void OnEnterView(){ 130 | box->Set( "{rotation:0, x: 400}" ); 131 | } 132 | 133 | void BeforeExitView(){ 134 | box->Animate( 1, "{rotation: 585, easing:Elastic.easeOut, x:1200}", this, &ViewA::vuiEventHandler ); 135 | } 136 | 137 | void draw() { 138 | label->Render(); 139 | 140 | btnViewB->Render(); 141 | btnViewBTriggerExit->Render(); 142 | 143 | box->Render(); 144 | resolution->Render(); 145 | } 146 | 147 | 148 | /* 149 | 150 | // NEW Stuff 151 | 152 | // useful for animate in / out states for view 153 | virtual void OnEnterView() {}; 154 | virtual void BeforeExitView() { 155 | ExitView(); 156 | }; 157 | 158 | // IMPORTANT - if overriding BeforeExitView() make sure to call this when your done 159 | ExitView(); 160 | 161 | 162 | 163 | // OG Stuff 164 | 165 | virtual void setup() {}; 166 | virtual void draw() {} 167 | virtual void update() {}; 168 | 169 | virtual void windowResized(int w, int h) {} 170 | 171 | virtual void keyPressed(int key) {} 172 | virtual void keyReleased(int key) {} 173 | 174 | virtual void mouseMoved(int x, int y) {} 175 | virtual void mouseDragged(int x, int y, int button) {} 176 | virtual void mousePressed(int x, int y, int button) {} 177 | virtual void mouseReleased(int x, int y, int button) {} 178 | virtual void mouseScrolled(int x, int y, float scrollX, float scrollY) {} 179 | virtual void mouseEntered(int x, int y) {} 180 | virtual void mouseExited(int x, int y) {} 181 | 182 | virtual void dragEvent(ofDragInfo dragInfo) { } 183 | virtual void gotMessage(ofMessage msg) { } 184 | 185 | virtual void touchDown(int x, int y, int id) {}; 186 | virtual void touchMoved(int x, int y, int id) {}; 187 | virtual void touchUp(int x, int y, int id) {}; 188 | 189 | virtual void touchDoubleTap(int x, int y, int id) {}; 190 | virtual void touchCancelled(int x, int y, int id) {}; 191 | 192 | */ 193 | 194 | }; 195 | 196 | 197 | #endif 198 | -------------------------------------------------------------------------------- /example-ViewManager/src/ViewB.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef __ViewB__ 3 | #define __ViewB__ 4 | 5 | #include "ofMain.h" 6 | #include "ofxVui.h" 7 | 8 | using namespace VUI; 9 | 10 | class ViewB : public View { 11 | public: 12 | ~ViewB() {}; 13 | ViewB() {}; 14 | 15 | // 16 | 17 | Text* label; 18 | Text* resolution; 19 | 20 | Text* btnViewA; 21 | Text* btnViewATriggerExit; 22 | 23 | Element* box; 24 | Tween* boxTween; 25 | 26 | // 27 | 28 | void setup() { 29 | 30 | // view name - using StyleSheet made in ViewA 31 | label = new Text( 20, 20, VUI::GetStyleSheet("ViewAStyles"), ".view-label" ); 32 | label->SetText( "View B" ); 33 | 34 | // resolution (main.cpp) 35 | resolution = new Text( VUI::GetResolutionX() - 20, VUI::GetResolutionY() - 20, VUI::GetStyleSheet("ViewAStyles"), ".resolution" ); 36 | resolution->SetText( ofToString(VUI::GetResolutionX()) + "x" + ofToString(VUI::GetResolutionY()) + " scale=" + ofToString(VUI::GetScale()) ); 37 | 38 | // buttonZ 39 | btnViewA = new Text( 300, 120, VUI::GetStyleSheet("ViewAStyles"), ".btn-setView" ); 40 | btnViewA->SetText( "SetView(\"view-a\")" ); 41 | 42 | // debugging 43 | btnViewA->SetName( "btnViewA" ); 44 | 45 | btnViewATriggerExit = new Text( 300, 120 + 60 + 10, VUI::GetStyleSheet("ViewAStyles"), ".btn-setView" ); 46 | btnViewATriggerExit->SetText( "SetView(\"view-a\", true)" ); 47 | 48 | // events 49 | ofAddListener( btnViewA->onMouseClick, this, &ViewB::vuiEventHandler ); 50 | ofAddListener( btnViewATriggerExit->onMouseClick, this, &ViewB::vuiEventHandler ); 51 | 52 | // exit animation element 53 | box = new Element( 1200, 400, VUI::GetStyleSheet("ViewAStyles"), ".box", "#boxB" ); 54 | } 55 | 56 | void vuiEventHandler(vuiEventArgs& evt) { 57 | if ( evt.eventType == VUI_EVENT_MOUSE_CLICK ){ 58 | if ( evt.element == btnViewA ) VUI::SetView( "view-a" ); 59 | else if ( evt.element == btnViewATriggerExit ) VUI::SetView( "view-a", true ); 60 | } 61 | 62 | // must call ExitView() if overriding BeforeExitView() 63 | if ( evt.tween == boxTween && evt.eventType == VUI_EVENT_ANIMATE_COMPLETE ) ExitView(); 64 | } 65 | 66 | void update() { 67 | 68 | } 69 | 70 | void OnEnterView(){ 71 | box->Set( "{rotation:0, scale: 1, x: 1200}" ); 72 | } 73 | 74 | void BeforeExitView(){ 75 | // a different way to find event using vuiEventArgs.tween 76 | boxTween = box->Animate( 1, "{rotation: 135, easing:Elastic.easeOut, scale: 2}", this, &ViewB::vuiEventHandler ); 77 | } 78 | 79 | void draw() { 80 | label->Render(); 81 | 82 | btnViewA->Render(); 83 | btnViewATriggerExit->Render(); 84 | 85 | box->Render(); 86 | resolution->Render(); 87 | } 88 | 89 | 90 | /* 91 | 92 | // NEW Stuff 93 | 94 | // useful for animate in / out states for view 95 | virtual void OnEnterView() {}; 96 | virtual void BeforeExitView() { 97 | ExitView(); 98 | }; 99 | 100 | // IMPORTANT - if overriding BeforeExitView() make sure to call this when your done 101 | ExitView(); 102 | 103 | 104 | 105 | // OG Stuff 106 | 107 | virtual void setup() {}; 108 | virtual void draw() {} 109 | virtual void update() {}; 110 | 111 | virtual void windowResized(int w, int h) {} 112 | 113 | virtual void keyPressed(int key) {} 114 | virtual void keyReleased(int key) {} 115 | 116 | virtual void mouseMoved(int x, int y) {} 117 | virtual void mouseDragged(int x, int y, int button) {} 118 | virtual void mousePressed(int x, int y, int button) {} 119 | virtual void mouseReleased(int x, int y, int button) {} 120 | virtual void mouseScrolled(int x, int y, float scrollX, float scrollY) {} 121 | virtual void mouseEntered(int x, int y) {} 122 | virtual void mouseExited(int x, int y) {} 123 | 124 | virtual void dragEvent(ofDragInfo dragInfo) { } 125 | virtual void gotMessage(ofMessage msg) { } 126 | 127 | virtual void touchDown(int x, int y, int id) {}; 128 | virtual void touchMoved(int x, int y, int id) {}; 129 | virtual void touchUp(int x, int y, int id) {}; 130 | 131 | virtual void touchDoubleTap(int x, int y, int id) {}; 132 | virtual void touchCancelled(int x, int y, int id) {}; 133 | 134 | */ 135 | 136 | }; 137 | 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /example-ViewManager/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | #include "ofxVui.h" 4 | 5 | //======================================================================== 6 | int main( ){ 7 | VUI::SetResolution(1920,1080,2./3.); // 1280x720 8 | 9 | // Rotate view 10 | /* 11 | VUI::SetResolution(1920,1080,.4); 12 | VUI::RotateView( VUI_ROTATE_90_CCW ); 13 | */ 14 | 15 | ofSetupOpenGL(VUI::GetWindowWidth(),VUI::GetWindowHeight(),OF_WINDOW); // <-------- setup the GL context 16 | 17 | // this kicks off the running of my app 18 | // can be OF_WINDOW or OF_FULLSCREEN 19 | // pass in width and height too: 20 | ofRunApp(new ofApp()); 21 | } 22 | -------------------------------------------------------------------------------- /example-ViewManager/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ViewA.h" 3 | #include "ViewB.h" 4 | 5 | //-------------------------------------------------------------- 6 | void ofApp::setup(){ 7 | ofSetFrameRate(60); 8 | 9 | // usually a transparent background 10 | VUI::SetBackground( 20 ); 11 | 12 | // name, viewPtr, set view 13 | VUI::AddView( "view-a", new ViewA(), true ); 14 | VUI::AddView( "view-b", new ViewB() ); 15 | 16 | // another way to set view 17 | //VUI::SetView( "my-view" ); 18 | } 19 | 20 | //-------------------------------------------------------------- 21 | void ofApp::update(){ 22 | ofSetWindowTitle(ofToString(ofGetFrameRate())); 23 | } 24 | 25 | //-------------------------------------------------------------- 26 | void ofApp::draw(){ 27 | /* 28 | VUI::Render() is VUI::RenderBefore() + VUI::RenderAfter() 29 | */ 30 | VUI::Render(); 31 | 32 | 33 | /* 34 | 35 | If you still want to scale/rotate your view without using the 36 | View Manager (via AddView()/SetView() you can like this: 37 | 38 | VUI::RenderBefore(); 39 | // draw your stuff here 40 | VUI::RenderAfter(); 41 | 42 | 43 | But you MUST set the 4th arg in VUI::SetResolution() to false (main.cpp): 44 | (ofxVui Element's Mouse/Touch events will adapt to scaled/rotated coordinates) 45 | 46 | VUI::SetResolution(w, h, scale, enableViewManager ); 47 | eg: VUI::SetResolution(1920, 1080, .6, false); 48 | 49 | */ 50 | } 51 | 52 | //-------------------------------------------------------------- 53 | void ofApp::keyPressed(int key){ 54 | 55 | } 56 | 57 | //-------------------------------------------------------------- 58 | void ofApp::keyReleased(int key){ 59 | 60 | } 61 | 62 | //-------------------------------------------------------------- 63 | void ofApp::mouseMoved(int x, int y ){ 64 | 65 | } 66 | 67 | //-------------------------------------------------------------- 68 | void ofApp::mouseDragged(int x, int y, int button){ 69 | 70 | } 71 | 72 | //-------------------------------------------------------------- 73 | void ofApp::mousePressed(int x, int y, int button){ 74 | 75 | } 76 | 77 | //-------------------------------------------------------------- 78 | void ofApp::mouseReleased(int x, int y, int button){ 79 | 80 | } 81 | 82 | //-------------------------------------------------------------- 83 | void ofApp::mouseEntered(int x, int y){ 84 | 85 | } 86 | 87 | //-------------------------------------------------------------- 88 | void ofApp::mouseExited(int x, int y){ 89 | 90 | } 91 | 92 | //-------------------------------------------------------------- 93 | void ofApp::windowResized(int w, int h){ 94 | 95 | } 96 | 97 | //-------------------------------------------------------------- 98 | void ofApp::gotMessage(ofMessage msg){ 99 | 100 | } 101 | 102 | //-------------------------------------------------------------- 103 | void ofApp::dragEvent(ofDragInfo dragInfo){ 104 | 105 | } 106 | -------------------------------------------------------------------------------- /example-ViewManager/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxVui.h" 5 | 6 | using namespace VUI; 7 | 8 | class ofApp : public ofBaseApp{ 9 | 10 | public: 11 | void setup(); 12 | void update(); 13 | void draw(); 14 | 15 | void keyPressed(int key); 16 | void keyReleased(int key); 17 | void mouseMoved(int x, int y ); 18 | void mouseDragged(int x, int y, int button); 19 | void mousePressed(int x, int y, int button); 20 | void mouseReleased(int x, int y, int button); 21 | void mouseEntered(int x, int y); 22 | void mouseExited(int x, int y); 23 | void windowResized(int w, int h); 24 | void dragEvent(ofDragInfo dragInfo); 25 | void gotMessage(ofMessage msg); 26 | 27 | }; 28 | -------------------------------------------------------------------------------- /ofxaddons_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelsandcandy/ofxVui/02be8aaa881bec13808e9c3638d49ab573d5fb7a/ofxaddons_thumbnail.png -------------------------------------------------------------------------------- /src/VUIContainer.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxVui.h" 2 | #include "VUIContainer.h" 3 | 4 | namespace VUI { 5 | 6 | void Container::SetScrollbar( StyleSheet *ss, string styleSelector){ 7 | scrollbar->Setup("calc(100%-" + ofToString(scrollbarPadding+scrollbarWidth) + ")", scrollbarPadding, ss,styleSelector); 8 | 9 | UpdateScrollbarStyle(); 10 | } 11 | 12 | void Container::Setup(StyleSheet *ss, string primarySelector, string secondarySelector){ 13 | horzContainer = new Element(0, 0 ); 14 | horzContainer->SetInteractive(false); 15 | 16 | vertContainer = new Element(0, 0 ); 17 | vertContainer->SetInteractive(false); 18 | 19 | container = new Element(0,0 ); 20 | container->SetInteractive(false); 21 | 22 | UpdateContainerStyle(); 23 | 24 | horzContainer->AddChild(vertContainer); 25 | vertContainer->AddChild(container); 26 | Element::AddChild(horzContainer); 27 | 28 | scrollbar = new Element("calc(100%-" + ofToString(scrollbarPadding+scrollbarWidth) + ")", scrollbarPadding, VUI::GetStyleSheet("VUIStyleSheet"), ".Container-scrollbar" ); 29 | scrollbar->SetInteractive(false); 30 | scrollbar->SetOpacity(0); 31 | Element::AddChild(scrollbar); 32 | 33 | UpdateContainerStyle(); 34 | } 35 | 36 | void Container::Setup(int x, int y, StyleSheet *ss, string primarySelector, string secondarySelector){ 37 | Element::Setup(x,y,ss,primarySelector,secondarySelector); 38 | Setup(ss,primarySelector,secondarySelector); 39 | } 40 | 41 | void Container::Setup(string x, int y, StyleSheet *ss, string primarySelector, string secondarySelector){ 42 | Element::Setup(x,y,ss,primarySelector,secondarySelector); 43 | Setup(ss,primarySelector,secondarySelector); 44 | } 45 | 46 | void Container::Setup(int x, string y, StyleSheet *ss, string primarySelector, string secondarySelector){ 47 | Element::Setup(x,y,ss,primarySelector,secondarySelector); 48 | Setup(ss,primarySelector,secondarySelector); 49 | } 50 | 51 | void Container::Setup(string x, string y, StyleSheet *ss, string primarySelector, string secondarySelector){ 52 | Element::Setup(x,y,ss,primarySelector,secondarySelector); 53 | Setup(ss,primarySelector,secondarySelector); 54 | } 55 | 56 | int Container::GetInnerWidth(bool scaled){ return GetWidth(scaled); } 57 | int Container::GetInnerHeight(bool scaled){ return GetHeight(scaled); } 58 | 59 | void Container::_vuiEventHandler(vuiEventArgs& evt){ 60 | #ifdef USING_ofxTouchPadScroll 61 | if ( !IsMouseInside() ) return; 62 | 63 | if ( evt.eventType == VUI_EVENT_TOUCHPAD_SCROLL_END ){ 64 | scrollbar->Animate(.3,"{delay:.4,opacity:0}"); 65 | return; 66 | } 67 | 68 | if ( evt.eventType == VUI_EVENT_TOUCHPAD_SCROLL_START ){ 69 | scrollbar->StopTween(); 70 | startScrollPos = container->GetPosition(); 71 | scrollbar->SetOpacity(1.0); 72 | 73 | } else if ( evt.eventType == VUI_EVENT_TOUCHPAD_SCROLL_INERTIA || evt.eventType == VUI_EVENT_TOUCHPAD_SCROLL ) { 74 | if ( evt.eventType == VUI_EVENT_TOUCHPAD_SCROLL_INERTIA ) startScrollPos = container->GetPosition(); 75 | tempScrollPos.set(startScrollPos); 76 | 77 | tempScrollPos.y += evt.touchPadScroll.y*VUI::divideDpi; 78 | 79 | if ( tempScrollPos.y < -scrollDist.y ) tempScrollPos.y = -scrollDist.y; 80 | else if ( tempScrollPos.y > padding.top*VUI::dpi ) tempScrollPos.y = padding.top*VUI::dpi; 81 | 82 | container->SetPositionY( (tempScrollPos.y*VUI::divideDpi) ); 83 | 84 | float perc = ((tempScrollPos.y)/(-scrollDist.y+padding.top*VUI::dpi)); 85 | if ( perc < 0.0 ) perc = 0.0; 86 | 87 | scrollbar->SetPositionY( (perc*scrollbarDist) + scrollbarPadding ); 88 | 89 | } 90 | #endif 91 | 92 | } 93 | 94 | }; 95 | -------------------------------------------------------------------------------- /src/VUIContainer.h: -------------------------------------------------------------------------------- 1 | // 2 | // VUIContainer.h 3 | // 4 | // Created by Christopher Miles on 2/13/18 5 | // 6 | // 7 | 8 | #pragma once 9 | 10 | #ifndef __ofxVui_Container__ 11 | #define __ofxVui_Container__ 12 | 13 | #include "ofMain.h" 14 | 15 | namespace VUI { 16 | 17 | class Container : public Element 18 | { 19 | public: 20 | Container(){}; 21 | ~Container(){}; 22 | 23 | Container( int x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ){ 24 | Setup(x,y,ss,primarySelector,secondarySelector); 25 | } 26 | 27 | Container( int x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ){ 28 | Setup(x,y,ss,primarySelector,secondarySelector); 29 | } 30 | 31 | Container( string x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ){ 32 | Setup(x,y,ss,primarySelector,secondarySelector); 33 | } 34 | 35 | Container( string x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ){ 36 | Setup(x,y,ss,primarySelector,secondarySelector); 37 | } 38 | 39 | void SetScrollbar( StyleSheet *ss, string styleSelector ); 40 | 41 | void SetPadding( int top, int right, int bottom, int left ){ 42 | padding.Set(top,right,bottom,left); 43 | UpdateContainerStyle(); 44 | } 45 | 46 | void SetPadding( int pad ){ 47 | padding.Set(pad,pad,pad,pad); 48 | UpdateContainerStyle(); 49 | } 50 | 51 | Stack stackDirection = VUI_STACK_VERT; 52 | 53 | void SetStackDirection(Stack direction){ 54 | stackDirection = direction; 55 | } 56 | 57 | void SetPadding( int topBottom, int leftRight ){ 58 | padding.Set(topBottom,leftRight,topBottom,leftRight); 59 | UpdateContainerStyle(); 60 | } 61 | 62 | void ResizeToContent(){ 63 | SetHeight(stackPos.y+padding.top+padding.bottom); 64 | UpdateContainerStyle(); 65 | UpdateScrollbarStyle(); 66 | vertContainer->RemoveMask(); 67 | 68 | #ifdef USING_ofxTouchPadScroll 69 | ofRemoveListener( GetEventManager()->onTouchPadScroll, this, &Container::_vuiEventHandler ); 70 | #endif 71 | } 72 | 73 | void SwapPosition(Element* a, Element* b){ 74 | ofVec2f posA = a->GetPosition()*VUI::divideDpi; 75 | ofVec2f posB = b->GetPosition()*VUI::divideDpi; 76 | 77 | /*ofLog() << ""; 78 | ofLog() << "----"; 79 | ofLog() << "a:" << a->GetPosition().y << " b:" << b->GetPosition().y; 80 | ofLog() << posA.y << " <> " << posB.y;*/ 81 | 82 | a->SetPosition( posB.x, posB.y ); 83 | b->SetPosition( posA.x, posA.y ); 84 | 85 | //ofLog() << "a:" << a->GetPosition().y << " b:" << b->GetPosition().y; 86 | } 87 | 88 | void FixChildrenPosition(){ 89 | stackPos.y = 0; 90 | for (vector::reverse_iterator it = container->children.rbegin(); it != container->children.rend(); it++){ 91 | if ( stackPos.y != 0 ) stackPos.y += margin.y; 92 | (*it)->SetPositionY(stackPos.y); 93 | stackPos.y += (*it)->GetOriginalHeight(); 94 | } 95 | } 96 | 97 | void AddAndStackChild(Element* child, bool resizeToContent = false){ 98 | 99 | if ( stackPos.y != 0 ) stackPos.y += margin.y; 100 | 101 | if ( stackDirection == VUI_STACK_VERT ) { 102 | AddChild(child); 103 | child->SetPosition(0,stackPos.y); 104 | stackPos.y += child->GetOriginalHeight(); 105 | 106 | } else if ( stackDirection == VUI_STACK_VERT_REVERSE ){ 107 | AddChild(child); 108 | stackPos.y = 0; 109 | 110 | for (vector::reverse_iterator it = container->children.rbegin(); it != container->children.rend(); it++){ 111 | if ( stackPos.y != 0 ) stackPos.y += margin.y; 112 | (*it)->SetPositionY(stackPos.y); 113 | stackPos.y += (*it)->GetOriginalHeight(); 114 | } 115 | } else { 116 | // TODO: Test/Fix this 117 | 118 | int x = stackPos.x + child->GetWidth(); 119 | if ( stackPos.x != 0 ) x += margin.x; 120 | 121 | if ( x <= container->GetWidth() ){ 122 | 123 | AddChild(child); 124 | child->SetPosition(stackPos.x, stackPos.y); 125 | 126 | stackPos.x += x; 127 | } else if ( child->GetWidth() <= container->GetWidth() ) { 128 | stackPos.x = 0; 129 | stackPos.y += child->GetOriginalHeight(); 130 | 131 | AddAndStackChild(child); 132 | } 133 | 134 | } 135 | 136 | if ( stackPos.y > vertContainer->GetOriginalHeight() - padding.top ) CreateMask(); 137 | UpdateScrollbarStyle(); 138 | 139 | if ( resizeToContent ) ResizeToContent(); 140 | 141 | } 142 | 143 | void RemoveStackedChild(Element* child){ 144 | for(vector::iterator it = container->children.begin(); it != container->children.begin() + container->children.size(); ) 145 | { 146 | if ( (*it) == child ) { 147 | (*it)->RemoveChildren(); 148 | it = container->children.erase( it ); 149 | 150 | UpdateStackedPositions(); 151 | return; 152 | } else { 153 | it++; 154 | } 155 | } 156 | } 157 | 158 | void UpdateStackedPositions(){ 159 | vertContainer->RemoveMask(); 160 | 161 | #ifdef USING_ofxTouchPadScroll 162 | ofRemoveListener( GetEventManager()->onTouchPadScroll, this, &Container::_vuiEventHandler ); 163 | #endif 164 | 165 | stackPos.y = 0; 166 | 167 | if ( stackDirection == VUI_STACK_VERT_REVERSE ){ 168 | for (vector::reverse_iterator it = container->children.rbegin(); it != container->children.rend(); it++){ 169 | if ( stackPos.y != 0 ) stackPos.y += margin.y; 170 | (*it)->SetPositionY(stackPos.y); 171 | stackPos.y += (*it)->GetOriginalHeight(); 172 | } 173 | } else { 174 | for (vector::iterator it = container->children.begin(); it != container->children.end(); it++){ 175 | if ( stackPos.y != 0 ) stackPos.y += margin.y; 176 | (*it)->SetPositionY(stackPos.y); 177 | stackPos.y += (*it)->GetOriginalHeight(); 178 | } 179 | } 180 | 181 | if ( stackPos.y > vertContainer->GetOriginalHeight() - padding.top ) CreateMask(); 182 | UpdateScrollbarStyle(); 183 | } 184 | 185 | void Clear(){ 186 | container->RemoveChildren(); 187 | vertContainer->RemoveMask(); 188 | stackPos.x = 0; 189 | stackPos.y = 0; 190 | 191 | #ifdef USING_ofxTouchPadScroll 192 | ofRemoveListener( GetEventManager()->onTouchPadScroll, this, &Container::_vuiEventHandler ); 193 | #endif 194 | 195 | if ( scrollbar != NULL ){ 196 | scrollbar->StopTween(); 197 | scrollbar->SetOpacity(0.0); 198 | } 199 | 200 | } 201 | 202 | 203 | vector GetChildren(){ 204 | return container->children; 205 | } 206 | 207 | vector* GetChildrenPtr(){ 208 | return &container->children; 209 | } 210 | 211 | void SetEventManager(VUI::EM* eventManager){ 212 | Element::SetEventManager(eventManager); 213 | 214 | if ( horzContainer != NULL ){ 215 | horzContainer->SetEventManager(eventManager); 216 | vertContainer->SetEventManager(eventManager); 217 | container->SetEventManager(eventManager); 218 | scrollbar->SetEventManager(eventManager); 219 | } 220 | } 221 | 222 | void Setup(int x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = ""); 223 | void Setup(string x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = ""); 224 | void Setup(int x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = ""); 225 | void Setup(string x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = ""); 226 | void Setup(StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = ""); 227 | 228 | void SetStackMargin(int x, int y){ 229 | margin.x = x; 230 | margin.y = y; 231 | } 232 | 233 | ofVec2f GetStackPos(){ 234 | return stackPos; 235 | } 236 | 237 | void AddChild( Element* el ){ 238 | container->AddChild(el); 239 | } 240 | 241 | void SetScrollPercentage(float perc){ 242 | if ( mask == NULL ) return; 243 | if ( perc == 1.0 ) container->SetPositionY( (-scrollDist.y*VUI::divideDpi) ); 244 | } 245 | 246 | //virtual int GetHeight( bool scaled = true); 247 | //virtual int GetWidth(bool scaled = true); 248 | virtual int GetInnerWidth(bool scaled = true); 249 | virtual int GetInnerHeight(bool scaled = true); 250 | 251 | 252 | private: 253 | Padding padding; 254 | Element* scrollbar = NULL; 255 | Element* horzContainer = NULL; 256 | Element* vertContainer = NULL; 257 | Element* container = NULL; 258 | StyleSheet* ss = NULL; 259 | ofVec2f stackPos; 260 | ofVec2f prevMargin; 261 | ofVec2f margin; 262 | ofTexture* mask = NULL; 263 | ofVec2f startScrollPos; 264 | ofVec2f tempScrollPos; 265 | ofVec2f scrollDist; 266 | 267 | int scrollbarDist = 0; 268 | int scrollbarPadding = 2; 269 | int scrollbarWidth = 8; 270 | int minScrollbarHeight = 60; 271 | int maxScrollbarHeight; 272 | 273 | private: 274 | 275 | void CreateMask(){ 276 | if ( vertContainer == NULL ) return; 277 | 278 | bool create = false; 279 | 280 | /*if ( texture == NULL ) create = true; 281 | else { 282 | if ( texture->getWidth() != vertContainer->GetWidth() && texture->getHeight() != vertContainer->GetHeight() ) create = true; 283 | }*/ 284 | 285 | if ( !vertContainer->HasMask() ) create = true; 286 | else { 287 | if ( vertContainer->GetMask()->getWidth() != vertContainer->GetWidth() && vertContainer->GetMask()->getHeight() != vertContainer->GetHeight() ) create = true; 288 | } 289 | 290 | container->SetHeight(stackPos.y*VUI::dpi+padding.bottom); 291 | 292 | 293 | scrollDist.y = (stackPos.y*VUI::dpi - vertContainer->GetHeight()) + padding.bottom*VUI::dpi; 294 | 295 | 296 | if ( create ) { 297 | ofFbo fbo; 298 | fbo.allocate( vertContainer->GetWidth(), vertContainer->GetHeight(), GL_RGBA ); 299 | fbo.begin(); 300 | ofClear(255, 255, 255, 0); 301 | ofSetColor(255,255,255, 255); 302 | ofDrawRectangle(0,0,vertContainer->GetWidth(), vertContainer->GetHeight() ); 303 | fbo.end(); 304 | 305 | if ( mask != NULL ) { 306 | mask = 0; 307 | delete mask; 308 | } 309 | 310 | mask = new ofTexture(fbo.getTexture()); 311 | vertContainer->SetMask(mask); 312 | 313 | #ifdef USING_ofxTouchPadScroll 314 | ofAddListener( GetEventManager()->onTouchPadScroll, this, &Container::_vuiEventHandler ); 315 | #endif 316 | //container->SetOffsetY(container->GetOriginalHeight()); 317 | } 318 | } 319 | 320 | void UpdateScrollbarStyle(){ 321 | minScrollbarHeight = vertContainer->GetOriginalHeight()*.1; 322 | if ( minScrollbarHeight < 50 ) minScrollbarHeight = 50; 323 | 324 | maxScrollbarHeight = vertContainer->GetOriginalHeight()*.85; 325 | 326 | scrollbar->SetPosition("calc(100%-" + ofToString(scrollbarPadding+scrollbarWidth) + ")", scrollbarPadding); 327 | 328 | int h = (vertContainer->GetOriginalHeight() / (stackPos.y*.8)) * vertContainer->GetOriginalHeight(); 329 | if ( h < minScrollbarHeight ) h = minScrollbarHeight; 330 | else if ( h > maxScrollbarHeight ) h = maxScrollbarHeight; 331 | 332 | scrollbar->SetHeight(h); 333 | scrollbar->SetWidth(scrollbarWidth); 334 | 335 | scrollbarDist = vertContainer->GetOriginalHeight() - (scrollbarPadding*2) - h; 336 | 337 | scrollbar->SetOpacity(0); 338 | } 339 | 340 | void UpdateContainerStyle(){ 341 | horzContainer->Setup(padding.left, 0 ); 342 | horzContainer->SetWidth("calc(100%-"+ofToString(padding.left+padding.right)+")"); 343 | 344 | vertContainer->SetWidth("100%" ); 345 | vertContainer->SetHeight("100%"); 346 | 347 | container->Setup(0, padding.top ); 348 | container->SetWidth("100%"); 349 | } 350 | 351 | void _vuiEventHandler(vuiEventArgs& evt); 352 | 353 | 354 | }; 355 | 356 | } 357 | 358 | 359 | #endif 360 | -------------------------------------------------------------------------------- /src/VUIElement.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef __ofxVui_Element__ 4 | #define __ofxVui_Element__ 5 | 6 | #include "ofMain.h" 7 | #include "ofxEasing.h" 8 | 9 | namespace VUI { 10 | 11 | 12 | class Element : public ofNode 13 | { 14 | public: 15 | 16 | friend class VUI::EM; 17 | 18 | class PercentCalcValues { 19 | public: 20 | PercentCalcValues(){}; 21 | ~PercentCalcValues(){}; 22 | 23 | class PCV { 24 | public: 25 | PCV(){}; 26 | ~PCV(){}; 27 | 28 | float perc = 1.0; 29 | float offset = 0.0; 30 | float val = 0.0; 31 | 32 | bool pxValue = false; 33 | 34 | float getValue( float parentValue){ 35 | if ( pxValue == true ) return val*VUI::dpi; 36 | else return (parentValue*perc)+offset*VUI::dpi; 37 | } 38 | 39 | void parse(int value){ 40 | perc = 1.0; 41 | offset = 0.0; 42 | 43 | val = (float)value; 44 | pxValue = true; 45 | } 46 | 47 | void parse(string value){ 48 | perc = 1.0; 49 | val = 0.0; 50 | offset = 0.0; 51 | 52 | if ( value.find( "calc" ) != -1 && value.find( "%" ) != -1 && value.find("(") != -1 && value.find(")") != -1 && (value.find("-") != -1 || value.find("+") != -1 ) ) { 53 | 54 | int start, end; 55 | start = value.find( "(" ) + 1; 56 | end = value.find( "%" ); 57 | string per = value.substr( start, end - start ); 58 | 59 | perc = ofToFloat( per )*.01; 60 | 61 | if ( value.find("-") != -1 ) { 62 | start = value.find("-")+1; 63 | offset = -1.0; 64 | } else { 65 | start = value.find("+")+1; 66 | offset = 1.0; 67 | } 68 | 69 | end = value.find(")"); 70 | 71 | string diff = value.substr( start, end - start); 72 | offset = (ofToFloat( diff )*offset); 73 | pxValue = false; 74 | 75 | } else if ( value.find("%") != -1 ){ 76 | perc = ofToFloat( value )*.01; 77 | pxValue = false; 78 | } else { 79 | val = ofToFloat(value); 80 | pxValue = true; 81 | } 82 | } 83 | }; 84 | 85 | map< string, PCV > values; 86 | 87 | void parseValue( string name, string value ){ 88 | values[name].parse(value); 89 | } 90 | 91 | void parseValue( string name, int value ){ 92 | values[name].parse(value); 93 | } 94 | 95 | int getValue(string name, float parentValue ){ 96 | return values[name].getValue(parentValue); 97 | } 98 | 99 | 100 | 101 | }; 102 | 103 | bool HasState(int state){ 104 | return hasState[state]; 105 | } 106 | 107 | PercentCalcValues percentCalcValues; 108 | 109 | 110 | 111 | 112 | struct Image { 113 | ofRectangle bounds; 114 | ofImage *image; 115 | ofVec2f scale; 116 | ofPoint dimensions; 117 | 118 | bool active = false; 119 | 120 | ImageSize size = VUI_IMAGE_NORMAL; 121 | 122 | void Set( ofImage *imagePtr, int x = 0, int y = 0, int width = -1, int height = -1){ 123 | image = imagePtr; 124 | bounds.set(x, y, width, height ); 125 | active = true; 126 | dimensions.set(imagePtr->getWidth(), imagePtr->getHeight()); 127 | } 128 | 129 | void Set( ofImage *imagePtr, string value ){ 130 | if ( value == "FILL" ) { 131 | image = imagePtr; 132 | size = VUI_IMAGE_FILL; 133 | scale.set(1,1); 134 | bounds.set(0,0, image->getWidth(), image->getHeight() ); 135 | active = true; 136 | dimensions.set(imagePtr->getWidth(), imagePtr->getHeight()); 137 | } 138 | } 139 | 140 | void Clear(){ 141 | active = false; 142 | } 143 | }; 144 | 145 | map< int, Image> bgImage; 146 | 147 | Image& GetBackgroundImage(VUI::State state){ 148 | return bgImage[(int)state]; 149 | } 150 | 151 | 152 | protected: 153 | 154 | string name = "VUIElement"; 155 | 156 | map< int, map > style; 157 | map< int, map > styleFloat; 158 | map< int, map > styleInt; 159 | 160 | vector borderProps = {"border-top", "border-bottom", "border-left", "border-right" }; 161 | 162 | map< int, vector > imageIDs; 163 | map< string, ofImage* > images; 164 | vector extraImages; 165 | map< int, bool> hasState; 166 | 167 | int anchorPoint = VUI_ALIGN_LEFT_TOP; 168 | 169 | int renderState = VUI_STATE_UP; 170 | int virtualState = VUI_STATE_UP; 171 | int prevVirtualState = VUI_STATE_UP; 172 | bool hasStyle = false; 173 | 174 | bool DEBUG_MODE = false; 175 | 176 | 177 | ofVec3f anchorOffset; 178 | StyleSheet *styleSheet = nullptr; 179 | 180 | bool userUpdating = false; 181 | ofColor color; 182 | 183 | string unparsedStyle; 184 | 185 | 186 | public: 187 | virtual ~Element(); 188 | Element(){}; 189 | 190 | void Setup( int x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ); 191 | 192 | void Setup( int x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ); 193 | 194 | void Setup( string x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ); 195 | void Setup( string x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ); 196 | 197 | 198 | Element( int x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ); 199 | Element( int x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ); 200 | Element( string x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ); 201 | Element( string x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ); 202 | 203 | ofEvent onMouseOver; 204 | ofEvent onMouseOut; 205 | ofEvent onMouseExit; 206 | ofEvent onMouseEnter; 207 | ofEvent onMousePressed; 208 | ofEvent onMouseMoved; 209 | ofEvent onMouseDragged; 210 | ofEvent onMouseReleased; 211 | ofEvent onMouseClick; 212 | ofEvent onMouseDoubleClick; 213 | 214 | ofEvent onTouchDown; 215 | ofEvent onTouchUp; 216 | ofEvent onTouchTap; 217 | ofEvent onTouchDoubleTap; 218 | 219 | ofEvent onStateChange; 220 | ofEvent onValueChange; 221 | ofEvent onTextChange; 222 | 223 | ofEvent onFocus; 224 | ofEvent onUnfocus; 225 | 226 | #ifdef USING_ofxTouchPadScroll 227 | ofEvent onTouchPadScroll; 228 | #endif 229 | 230 | ofFbo *fbo = nullptr; 231 | ofTexture *maskTex = nullptr; 232 | 233 | int vuiUID = abs((int)ofRandom(7, 7777777777)); 234 | 235 | int GetVirtualState(){ 236 | return virtualState; 237 | } 238 | 239 | void DEBUG(){ 240 | DEBUG_MODE = true; 241 | } 242 | 243 | void SetBorderRenderingOrder( string a, string b, string c, string d ){ 244 | borderProps[0] = a; 245 | borderProps[1] = b; 246 | borderProps[2] = c; 247 | borderProps[3] = d; 248 | }; 249 | 250 | void RemoveMask(){ 251 | maskTex = nullptr; 252 | if ( fbo != nullptr ){ 253 | fbo->clear(); 254 | fbo = 0; 255 | fbo = nullptr; 256 | } 257 | } 258 | 259 | void SetMask( ofTexture *maskTexture ) { 260 | maskTex = maskTexture; 261 | 262 | if (fbo != nullptr) return; 263 | 264 | fbo = new ofFbo(); 265 | //fbo->allocate(styleFloat[state]["width"], styleFloat[state]["height"], GL_RGBA); 266 | fbo->allocate(GetWidth()*scale, GetHeight()*scale, GL_RGBA); 267 | fbo->begin(); 268 | ofClear(255, 255, 255, 0); 269 | fbo->end(); 270 | } 271 | 272 | bool HasMask(){ 273 | if ( maskTex != nullptr ) return true; 274 | return false; 275 | } 276 | 277 | ofTexture* GetMask(){ 278 | return maskTex; 279 | } 280 | 281 | float width = 60; 282 | float height = 60; 283 | float rotation = 0.0; 284 | 285 | int GetState(){ 286 | return renderState; 287 | } 288 | 289 | float GetRotation(){ 290 | return rotation; 291 | } 292 | 293 | void SetRotation( float r ){ 294 | rotation = r; 295 | } 296 | 297 | void SetState( VUI::State toState, bool notifyEvent = true, bool force = false ){ 298 | if ( DEBUG_MODE ) ofLog() << GetName() << " - " << toState << " > " << hasState[VUI_STATE_OVER] << " > "; 299 | 300 | VUI::State s = toState; 301 | 302 | if ( isToggle ){ 303 | if ( renderState == VUI_STATE_DOWN && toState == VUI_STATE_OVER && !force ) return; 304 | } 305 | 306 | if ( s == VUI_STATE_DOWN && !hasState[VUI_STATE_DOWN] ) s = VUI_STATE_OVER; 307 | if ( s == VUI_STATE_OVER && !hasState[VUI_STATE_OVER] ) s = VUI_STATE_UP; 308 | 309 | 310 | 311 | bool updated = false; 312 | 313 | if ( s != renderState ) { 314 | renderState = s; 315 | } 316 | 317 | if ( s == VUI_STATE_UP ) ResetEnterExit(); 318 | 319 | UpdateVirtualState( toState, false, notifyEvent ); 320 | } 321 | 322 | void SetSelected( bool selected = true, bool notifyEvent = true, bool force = false ){ 323 | if ( selected ) SetState( VUI_STATE_DOWN, notifyEvent, force ); 324 | else SetState( VUI_STATE_UP, notifyEvent, force ); 325 | } 326 | 327 | 328 | 329 | void UpdateVirtualState( VUI::State toState, bool force = false, bool notifyEvent = true ){ 330 | if ( virtualState != toState ){ 331 | 332 | prevVirtualState = int(virtualState); 333 | virtualState = toState; 334 | 335 | if ( notifyEvent ){ 336 | vuiEventArgs args; 337 | args.element = this; 338 | args.eventType = VUI_EVENT_STATE_CHANGE; 339 | args.renderState = int(toState); 340 | args.virtualState = int(virtualState); 341 | if ( toState == VUI_STATE_DOWN ) args.value = 1; 342 | else args.value = 0; 343 | 344 | ofNotifyEvent( onStateChange, args, this ); 345 | } 346 | 347 | if ( toState == VUI_STATE_DOWN ) { 348 | TriggerEvent( VUI_EVENT_VALUE_CHANGE ); 349 | } else if ( prevVirtualState == VUI_STATE_DOWN && (toState == VUI_STATE_OVER || toState == VUI_STATE_UP) ){ 350 | TriggerEvent( VUI_EVENT_VALUE_CHANGE ); 351 | } 352 | 353 | 354 | } 355 | 356 | if ( force ) { 357 | prevVirtualState = int(virtualState); 358 | virtualState = toState; 359 | } 360 | } 361 | 362 | int timeLastToggle = -1; 363 | void SetToggle( bool doToggle = true){ 364 | isToggle = doToggle; 365 | } 366 | 367 | void MakeToggle(){ 368 | SetToggle(); 369 | } 370 | 371 | void SetSelection(bool doSelection = true){ 372 | isSelection = doSelection; 373 | } 374 | void MakeSelection(){ 375 | SetSelection(); 376 | } 377 | 378 | bool IsToggled(){ 379 | if ( !isToggle ) return false; 380 | else { 381 | if (virtualState == VUI_STATE_DOWN) return true; 382 | else return false; 383 | } 384 | } 385 | 386 | // 387 | 388 | Element* SetName(string _name) { name = _name; return this; } 389 | string GetName(){ return name; } 390 | 391 | Element* SetStyle(string style, int renderState = VUI_STATE_UP, bool initState = true ); 392 | 393 | void Render(float parentOffsetX = 0, float parentOffsetY = 0, float parentOpacity = 1.0, ofVec2f _anchorOffset = ofVec2f::zero(), ofVec2f _parentOffsetPos = ofVec2f::zero() ); 394 | void Update(int mouseX = -1, int mouseY = -1, bool internalUpdate = false); 395 | void ParseStyle(string property = "", int renderState = VUI_STATE_UP); 396 | void ParseStyleSheet(StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = ""); 397 | float GetProperty(string property); 398 | void SetProperty(string property, string val); 399 | void SetProperty(string property, float val); 400 | void SetProperty(string property, int val); 401 | 402 | 403 | 404 | vector children; 405 | Element* parent = nullptr; 406 | 407 | VUI::EM* EventManager = NULL; 408 | 409 | VUI::EM* GetEventManager(){ 410 | if ( this->EventManager == NULL ) return &VUI::EventManager; 411 | else return this->EventManager; 412 | } 413 | 414 | virtual void SetEventManager(VUI::EM* eventManager){ 415 | this->EventManager = eventManager; 416 | 417 | for(vector::iterator it = children.begin(); it != children.end(); it++ ){ 418 | (*it)->SetEventManager( eventManager ); 419 | } 420 | } 421 | 422 | Element* GetParent(){ 423 | return parent; 424 | } 425 | 426 | bool HasParent(){ 427 | if ( parent == nullptr || parent == NULL ) return false; 428 | return true; 429 | } 430 | 431 | virtual void AddChild( Element* el){ 432 | if ( !el->HasParent() ) { 433 | el->SetParent( this ); 434 | el->SetEventManager( EventManager ); 435 | children.push_back(el); 436 | } 437 | } 438 | 439 | void AddImage(ofImage* image ){ 440 | extraImages.push_back(image); 441 | } 442 | 443 | vector& GetImages(){ 444 | return extraImages; 445 | } 446 | 447 | virtual void RemoveChild(Element* child){ 448 | for(vector::iterator it = children.begin(); it != children.begin() + children.size(); ) 449 | { 450 | if ( (*it) == child ) { 451 | (*it)->RemoveParent(); 452 | (*it)->RemoveChildren(); 453 | it = children.erase( it ); 454 | return; 455 | } else { 456 | it++; 457 | } 458 | } 459 | } 460 | 461 | virtual void RemoveChildren(){ 462 | for(vector::reverse_iterator it = children.rbegin(); it != children.rend(); it++ ) 463 | { 464 | 465 | (*it)->RemoveParent(); 466 | (*it)->RemoveChildren(); 467 | children.erase( --(it.base()) ); 468 | }; 469 | 470 | children = vector(); 471 | } 472 | 473 | virtual vector GetChildren(){ 474 | return children; 475 | } 476 | 477 | void SetParent( Element* el ){ 478 | this->parent = el; 479 | } 480 | 481 | void RemoveParent(){ 482 | this->parent = NULL; 483 | } 484 | 485 | Element* SetSize(float w, float h); 486 | Element* SetSize(string w, string h); 487 | void SetHeight( float h ); 488 | void SetWidth( float w ); 489 | void SetHeight( string h ); 490 | void SetWidth( string w ); 491 | 492 | virtual int GetHeight( bool scaled = true); 493 | virtual int GetWidth(bool scaled = true); 494 | virtual int GetOriginalHeight( bool scaled = true); 495 | virtual int GetOriginalWidth(bool scaled = true); 496 | 497 | virtual int GetInnerWidth(bool scaled = true){ return GetWidth(scaled); } 498 | virtual int GetInnerHeight(bool scaled = true){ return GetHeight(scaled); } 499 | 500 | ofVec2f GetPosition(bool normalize = false); 501 | Element* SetPosition(float x, float y); 502 | void SetPosition(string x, string y); 503 | void SetPosition(float x, string y); 504 | void SetPosition(string x, float y); 505 | void SetPositionX( float x ); 506 | void SetPositionY( float y ); 507 | void SetPositionX( string x ); 508 | void SetPositionY( string y ); 509 | void UseStyleClass(string name); 510 | void UseStyleID(string name); 511 | void UseStyle(string style); 512 | 513 | float scale = 1.0; 514 | 515 | bool isInteractive = true; 516 | bool isActive = true; 517 | 518 | virtual void Hide(){ 519 | isActive = false; 520 | ResetEnterExit(); 521 | } 522 | 523 | virtual void Show(){ 524 | isActive = true; 525 | } 526 | 527 | void SetInteractive( bool interactive ){ 528 | isInteractive = interactive; 529 | } 530 | 531 | float GetScale(){ 532 | return scale; 533 | } 534 | 535 | void SetScale( float scale ){ 536 | this->scale = scale; 537 | } 538 | 539 | void Set( string properties ){ 540 | 541 | string s(properties); 542 | ofStringReplace(s, "{", " "); 543 | ofStringReplace(s, "}", " "); 544 | ofStringReplace(s, " ", ""); 545 | 546 | vector split = ofSplitString(s, "," ); 547 | for ( vector::iterator it = split.begin(); it != split.end(); it++){ 548 | vector propVal = ofSplitString( (*it), ":" ); 549 | if ( propVal.size() == 2 ){ 550 | if ( propVal[0] == "x" ){ 551 | SetPositionX( ofToFloat( propVal[1] ) ); 552 | } else if ( propVal[0] == "y" ){ 553 | SetPositionY( ofToFloat( propVal[1] ) ); 554 | } else if ( propVal[0] == "opacity" ){ 555 | SetOpacity( ofToFloat( propVal[1] ) ); 556 | } else if ( propVal[0] == "rotation" ){ 557 | SetRotation( ofToFloat( propVal[1] ) ); 558 | } else if ( propVal[0] == "width" ){ 559 | SetWidth( ofToFloat( propVal[1] ) ); 560 | } else if ( propVal[0] == "height" ){ 561 | SetHeight( ofToFloat( propVal[1] ) ); 562 | } else if ( propVal[0] == "interactive" ){ 563 | if ( propVal[1] == "true" ) SetInteractive(true); 564 | else if ( propVal[1] == "false" ) SetInteractive(false); 565 | } else if ( propVal[0] == "scale" ){ 566 | SetScale( ofToFloat( propVal[1] ) ); 567 | } 568 | } 569 | } 570 | } 571 | 572 | void SetStyleSheet(StyleSheet* ss) { 573 | styleSheet = ss; 574 | } 575 | void SetAnchorPoint(Align alignment) { 576 | anchorPoint = alignment; 577 | } 578 | 579 | void TriggerEvent(vuiEvent eventType); 580 | 581 | string GetExitPositionString(ofVec2f localMousePos){ 582 | if ( localMousePos.x <= 0 ) return "left"; 583 | else if ( localMousePos.y <= 0 ) return "top"; 584 | else if ( localMousePos.x >= GetWidth() ) return "right"; 585 | else return "bottom"; 586 | } 587 | 588 | Position GetExitPosition(ofVec2f localMousePos){ 589 | if ( localMousePos.x <= 0 ) return Position::VUI_LEFT; 590 | else if ( localMousePos.y <= 0 ) return Position::VUI_TOP; 591 | else if ( localMousePos.x >= GetWidth() ) return Position::VUI_RIGHT; 592 | else return Position::VUI_BOTTOM; 593 | } 594 | 595 | vuiEventArgs GetEventArgs(vuiEvent eventType); 596 | 597 | map propValue; 598 | 599 | void StorePropValue( string prop, string value){ 600 | propValue[prop] = value; 601 | } 602 | 603 | virtual void RenderBefore(ofRectangle& parentRect){}; 604 | virtual void RenderAfter(ofRectangle& parentRect){}; 605 | virtual void CustomUpdate(){}; 606 | 607 | template 608 | Tween* Animate( float timeSeconds, string params, ListenerClass* listener, void (ListenerClass::*listenerMethod)(ArgumentsType&) ){ 609 | //ofLog() << timeSeconds << " - " << params; 610 | return VUI::Animate( this, timeSeconds, params, listener, listenerMethod ); 611 | 612 | } 613 | 614 | Tween* Animate( float timeSeconds, string params ){ 615 | //ofLog() << timeSeconds << " - " << params; 616 | return VUI::Animate( this, timeSeconds, params ); 617 | } 618 | 619 | void SetOpacity( float o ){ 620 | opacity = o; 621 | } 622 | 623 | float GetOpacity(){ 624 | return ofToFloat(style[renderState]["opacity"]); 625 | //return opacity; 626 | } 627 | 628 | bool IsMouseInside(){ 629 | return _mInside; 630 | } 631 | 632 | bool IsMouseDown(){ 633 | return isMouseDown; 634 | } 635 | 636 | bool IsActive(){ 637 | return isActive; 638 | } 639 | 640 | Tween* tween = NULL; 641 | 642 | void StopTween(){ 643 | if ( tween != NULL ) { 644 | tween->Stop(); 645 | tween = NULL; 646 | } 647 | } 648 | 649 | void StoreTween(Tween* tween){ 650 | this->tween = tween; 651 | } 652 | 653 | void SetOffsetY(int offset); 654 | void SetOffsetX(int offset); 655 | 656 | Padding padding; 657 | 658 | void SetPadding( int top, int right, int bottom, int left ){ 659 | padding.Set(top,right,bottom,left); 660 | } 661 | 662 | void SetPadding( int pad ){ 663 | padding.Set(pad,pad,pad,pad); 664 | } 665 | 666 | void SetPadding( int topBottom, int leftRight ){ 667 | padding.Set(topBottom,leftRight,topBottom,leftRight); 668 | } 669 | 670 | void SetPaddingTop( int pad){ 671 | padding.top = pad; 672 | } 673 | 674 | void SetPaddingRight( int pad){ 675 | padding.right = pad; 676 | } 677 | 678 | void SetPaddingBottom( int pad){ 679 | padding.bottom = pad; 680 | } 681 | 682 | void SetPaddingLeft( int pad){ 683 | padding.left = pad; 684 | } 685 | 686 | protected: 687 | ofTrueTypeFont* font = nullptr; 688 | string fontFilename; 689 | int fontSize; 690 | float fontLetterSpacing; 691 | 692 | vector SplitStyles(string s); 693 | virtual void UpdateState(int renderState, bool isInside = false, bool isMouseDown = false); 694 | void UpdatePosition(); 695 | 696 | ofVec3f localMinPosition; 697 | ofVec3f localMaxPosition; 698 | ofVec3f posOffset; 699 | ofVec2f parentOffsetPos; 700 | ofVec2f parentAnchorOffset; 701 | 702 | ofVec3f globalMinPosition; 703 | ofVec3f globalMaxPosition; 704 | 705 | ofVec4f globalPos; 706 | ofVec2f size; 707 | 708 | ofVec3f drawPosition; 709 | 710 | float opacity = 1.0; 711 | float parentSumOpacity = 1.0; 712 | 713 | ofVec2f mouseDownPos; 714 | bool isMouseDown = false; 715 | bool isMouseInside = false; 716 | bool _mInside = false; 717 | bool _mEnter = false; 718 | int lastClickTimeMS = 0; 719 | int touchDownTimeMS = 0; 720 | 721 | ofVec2f touchPoint; 722 | private: 723 | void SetDefaultStyles(int x, int y); 724 | void UpdateAnchorOffset(); 725 | ofVec3f parentSumOffset; 726 | 727 | bool isToggle = false; 728 | bool isSelection = false; 729 | int lastTimeMouseDown; 730 | int fixMouseY = 3; 731 | 732 | void ResetEnterExit(){ 733 | _mInside = false; 734 | _mEnter = false; 735 | } 736 | 737 | }; 738 | } 739 | 740 | #endif 741 | -------------------------------------------------------------------------------- /src/VUISlider.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxVui.h" 2 | #include "VUISlider.h" 3 | 4 | namespace VUI { 5 | 6 | void Slider::SetBar( StyleSheet *ss, string styleBarSelector, string styleBarBgSelector){ 7 | if ( bar == NULL ){ 8 | SetInteractive(false); 9 | 10 | barContainer = new Element(padding.left, padding.top, ss, styleBarBgSelector ); 11 | //barContainer->SetInteractive(false); 12 | AddChild(barContainer); 13 | 14 | bar = new Element(0,0, ss, styleBarSelector ); 15 | bar->SetInteractive(false); 16 | barContainer->AddChild(bar); 17 | 18 | ofAddListener( barContainer->onMouseReleased, this, &Slider::_vuiEventHandler ); 19 | ofAddListener( barContainer->onMousePressed, this, &Slider::_vuiEventHandler ); 20 | ofAddListener( barContainer->onMouseDragged, this, &Slider::_vuiEventHandler ); 21 | ofAddListener( barContainer->onMouseClick, this, &Slider::_vuiEventHandler ); 22 | 23 | ofAddListener( barContainer->onMouseOver, this, &Slider::_vuiEventHandler ); 24 | ofAddListener( barContainer->onMouseOut, this, &Slider::_vuiEventHandler ); 25 | 26 | } else { 27 | bar->Setup(0,0, ss, styleBarSelector ); 28 | barContainer->Setup(padding.left,padding.top, ss, styleBarBgSelector ); 29 | } 30 | UpdateBarStyle(); 31 | } 32 | 33 | }; 34 | -------------------------------------------------------------------------------- /src/VUISlider.h: -------------------------------------------------------------------------------- 1 | // 2 | // xText.h 3 | // 4 | // Created by Christopher Miles on 2/09/18 5 | // 6 | // 7 | 8 | #pragma once 9 | 10 | #ifndef __ofxVui_Slider__ 11 | #define __ofxVui_Slider__ 12 | 13 | #include "ofMain.h" 14 | 15 | namespace VUI { 16 | 17 | class Slider : public Element 18 | { 19 | public: 20 | ~Slider(){}; 21 | 22 | Slider( int x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Element(x,y,ss,primarySelector,secondarySelector){ 23 | Setup(); 24 | } 25 | 26 | Slider( int x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Element(x,y,ss,primarySelector,secondarySelector){ 27 | Setup(); 28 | } 29 | 30 | Slider( string x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Element(x,y,ss,primarySelector,secondarySelector){ 31 | Setup(); 32 | } 33 | 34 | Slider( string x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Element(x,y,ss,primarySelector,secondarySelector){ 35 | Setup(); 36 | } 37 | 38 | ofEvent onSliderValueChange; 39 | 40 | void SetBar( StyleSheet *ss, string styleBarSelector, string styleBarBgSelector ); 41 | 42 | void SetPadding( int top, int right, int bottom, int left ){ 43 | padding.Set(top,right,bottom,left); 44 | UpdateBarStyle(); 45 | } 46 | 47 | void SetPadding( int pad ){ 48 | padding.Set(pad,pad,pad,pad); 49 | UpdateBarStyle(); 50 | } 51 | 52 | void SetPadding( int topBottom, int leftRight ){ 53 | padding.Set(topBottom,leftRight,topBottom,leftRight); 54 | UpdateBarStyle(); 55 | } 56 | 57 | float GetPercentageValue(){ 58 | return sliderPerc; 59 | } 60 | 61 | int GetValue(){ 62 | return sliderVal; 63 | } 64 | 65 | void Setup(){ 66 | SetPadding(1); 67 | } 68 | 69 | Padding& GetPadding(){ 70 | return padding; 71 | } 72 | 73 | Element* GetBarContainer(){ 74 | return barContainer; 75 | } 76 | 77 | void SetPercValue(float perc){ 78 | bar->SetWidth( ofToString(perc*100.0) + "%" ); 79 | } 80 | 81 | void SetValue(int value){ 82 | if ( value < 0 ) SetPercValue(0.0); 83 | else if ( value > GetOriginalBarWidth() ) SetPercValue( 1.0 ); 84 | else SetPercValue( value / GetOriginalBarWidth() ); 85 | } 86 | 87 | private: 88 | 89 | 90 | Padding padding; 91 | float sliderPerc = 1.0; 92 | int sliderVal = 0; 93 | 94 | Element* bar = NULL; 95 | Element* barContainer = NULL; 96 | 97 | int width = 0; 98 | 99 | void UpdateBarStyle(){ 100 | if ( bar != NULL ){ 101 | barContainer->SetPosition(padding.left, padding.top); 102 | barContainer->SetWidth( "calc(100%-" + ofToString(padding.left+padding.right) + ")" ); 103 | barContainer->SetHeight( "calc(100%-" + ofToString(padding.top+padding.bottom) + ")" ); 104 | 105 | bar->SetPosition(0,0); 106 | bar->SetWidth( "100%" ); 107 | bar->SetHeight( "100%" ); 108 | } 109 | } 110 | 111 | float GetOriginalBarWidth(){ 112 | return barContainer->GetWidth() - 2; 113 | } 114 | 115 | void _vuiEventHandler(vuiEventArgs& evt){ 116 | 117 | if ( evt.eventType == VUI_EVENT_MOUSE_OVER || evt.eventType == VUI_EVENT_MOUSE_OUT ){ 118 | if ( evt.eventType == VUI_EVENT_MOUSE_OVER ) bar->SetState(VUI_STATE_OVER, false); 119 | else bar->SetState(VUI_STATE_UP, false); 120 | return; 121 | } 122 | 123 | if ( evt.eventType == VUI_EVENT_MOUSE_RELEASED || evt.eventType == VUI_EVENT_MOUSE_CLICK ){ 124 | bar->SetState(VUI_STATE_UP, false); 125 | } else { 126 | if ( bar->HasState(VUI_STATE_DOWN ) ) bar->SetState(VUI_STATE_DOWN, false); 127 | } 128 | 129 | 130 | float w = GetOriginalBarWidth(); 131 | 132 | if ( evt.localMousePos.x < 1 ) sliderVal = 0; 133 | else if ( evt.localMousePos.x > w) sliderVal = w+2; 134 | else sliderVal = evt.localMousePos.x; 135 | 136 | sliderPerc = sliderVal / w; 137 | if ( sliderPerc > 1.0 ) sliderPerc = 1.0; 138 | 139 | bar->SetWidth( ofToString(sliderPerc*100.0) + "%" ); 140 | 141 | /*if ( evt.eventType == VUI_EVENT_MOUSE_CLICK || evt.eventType == VUI_EVENT_MOUSE_RELEASED || evt.eventType == VUI_EVENT_MOUSE_PRESSED ) bar->SetWidth( ofToString(sliderPerc*100.0) + "%" ); 142 | else bar->SetWidth( ofToString(sliderPerc*100.0) + "%" );*/ 143 | 144 | vuiEventArgs args = GetEventArgs(VUI_EVENT_SLIDER_VALUE_CHANGE); 145 | args.value = sliderVal; 146 | args.percValue = sliderPerc; 147 | 148 | ofNotifyEvent(onSliderValueChange, args, this); 149 | } 150 | 151 | 152 | }; 153 | 154 | } 155 | 156 | 157 | #endif 158 | -------------------------------------------------------------------------------- /src/VUIStyleSheet.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxVui.h" 2 | #include "VUIStyleSheet.h" 3 | #include 4 | #include 5 | 6 | namespace VUI { 7 | 8 | StyleSheet::~StyleSheet() { 9 | VUI::Init(); 10 | 11 | } 12 | StyleSheet::StyleSheet( string ss ) { 13 | VUI::Init(); 14 | 15 | Process( ss ); 16 | } 17 | StyleSheet::StyleSheet( string ss, string name ){ 18 | VUI::Init(); 19 | 20 | Process( ss ); 21 | VUI::AddStyleSheet( name, this ); 22 | } 23 | 24 | void StyleSheet::AddImage(string id, string fileName) { 25 | ofImage *img = new ofImage(); 26 | img->load(fileName); 27 | 28 | images[id] = img; 29 | } 30 | 31 | void StyleSheet::AddVideo(string id, string fileName) { 32 | ofVideoPlayer *video = new ofVideoPlayer(); 33 | video->load(fileName); 34 | 35 | videos[id] = video; 36 | } 37 | 38 | ofVideoPlayer* StyleSheet::GetVideo(string id) { 39 | return videos[id]; 40 | } 41 | 42 | ofImage* StyleSheet::GetImage(string id) { 43 | return images[id]; 44 | } 45 | 46 | bool StyleSheet::HasImage( string id ){ 47 | if ( images[id] != nullptr ) return true; 48 | return false; 49 | } 50 | 51 | 52 | 53 | void StyleSheet::Process(string ss) { 54 | string s(ss); 55 | ofStringReplace(s, " ", ""); 56 | ofStringReplace(s, "\n", ""); 57 | ofStringReplace(s, " ", ""); 58 | 59 | vector split = ofSplitString(s, "]"); 60 | 61 | vector tempSplit; 62 | string name; 63 | string classifier; 64 | 65 | for (vector::iterator it = split.begin(); it != split.end(); it++) { 66 | tempSplit = ofSplitString((*it), ">"); 67 | if (tempSplit.size() == 2) { 68 | name = tempSplit.at(0).substr(2); 69 | 70 | classifier = tempSplit.at(0).substr(1, 1); 71 | 72 | //cout << "name: " << name << endl; 73 | //cout << "[" << classifier << name << "] => " << tempSplit.at(1) << endl; 74 | 75 | if (classifier == ".") { 76 | //classes[ name ] 77 | //cout << "." << name << " => " << tempSplit.at(1) << endl; 78 | classes[name] = tempSplit.at(1); 79 | } else if (classifier == "#") { 80 | ids[name] = tempSplit.at(1); 81 | 82 | //cout << "#" << name << " => " << tempSplit.at(1) << endl; 83 | } 84 | else if (tempSplit.at(0).substr(1) == "Images" ){ 85 | tempSplit = ofSplitString(tempSplit.at(1), ";"); 86 | 87 | vector assets; 88 | 89 | for (vector::iterator it = tempSplit.begin(); it != tempSplit.end(); it++) { 90 | assets = ofSplitString((*it), ":"); 91 | 92 | if (assets.size() == 2) { 93 | //cout << assets[0] << " > " << assets[1] << endl; 94 | AddImage(assets[0], assets[1]); 95 | } 96 | } 97 | } 98 | else if (tempSplit.at(0).substr(1) == "Videos") { 99 | tempSplit = ofSplitString(tempSplit.at(1), ";"); 100 | 101 | vector assets; 102 | 103 | for (vector::iterator it = tempSplit.begin(); it != tempSplit.end(); it++) { 104 | assets = ofSplitString((*it), ":"); 105 | 106 | if (assets.size() == 2) { 107 | //cout << assets[0] << " > " << assets[1] << endl; 108 | AddVideo(assets[0], assets[1]); 109 | } 110 | } 111 | } 112 | 113 | /*if (tempSplit.at(0).at(1) == ".") { 114 | //classes[ name ] = 115 | cout << tempSplit.at(1) << endl; 116 | }*/ 117 | } 118 | } 119 | } 120 | 121 | string StyleSheet::GetStyleByClass(string name) { 122 | return classes[name]; 123 | } 124 | 125 | string StyleSheet::GetStyleByID(string name) { 126 | return ids[name]; 127 | } 128 | 129 | 130 | string StyleSheet::ExtractStyleByState(string style, int state) { 131 | vector split = ofSplitString(style, "&"); 132 | if (state == VUI_STATE_UP) return split.at(0); 133 | 134 | vector tempSplit; 135 | for (vector::iterator it = split.begin()+1; it != split.end(); it++) { 136 | //cout << "(*it) => " << (*it) << endl; 137 | 138 | tempSplit = ofSplitString((*it), "}"); 139 | tempSplit = ofSplitString(tempSplit.at(0), "{"); 140 | 141 | //cout << "[0] => " << tempSplit.at(0) << endl; 142 | //cout << "[1] => " << tempSplit.at(1) << endl; 143 | 144 | if ((state == VUI_STATE_OVER && tempSplit.at(0).find("over") != string::npos) || 145 | (state == VUI_STATE_DOWN && tempSplit.at(0).find("down") != string::npos)) { 146 | return tempSplit.at(1); 147 | } 148 | 149 | } 150 | 151 | return ""; 152 | } 153 | 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/VUIStyleSheet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef __ofxVui_StyleSheet__ 4 | #define __ofxVui_StyleSheet__ 5 | 6 | #include "ofMain.h" 7 | 8 | namespace VUI { 9 | 10 | class StyleSheet { 11 | 12 | 13 | public: 14 | virtual ~StyleSheet(); 15 | StyleSheet( string ss); 16 | StyleSheet( string ss, string name ); 17 | 18 | map assets; 19 | 20 | map classes; 21 | map ids; 22 | 23 | map images; 24 | map videos; 25 | 26 | void Process(string ss); 27 | string GetStyleByClass(string name); 28 | string GetStyleByID(string name); 29 | 30 | void AddImage(string id, string fileName); 31 | void AddVideo(string id, string fileName); 32 | 33 | bool HasImage( string id ); 34 | ofImage* GetImage(string id); 35 | ofVideoPlayer* GetVideo(string id); 36 | 37 | static string ExtractStyleByState(string style, int state); 38 | }; 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/VUIText.h: -------------------------------------------------------------------------------- 1 | // 2 | // xText.h 3 | // 4 | // Created by Christopher Miles on 9/27/17. 5 | // 6 | // 7 | 8 | #pragma once 9 | 10 | #ifndef __ofxVui_Text__ 11 | #define __ofxVui_Text__ 12 | 13 | #include "ofMain.h" 14 | 15 | namespace VUI { 16 | 17 | 18 | class Text : public Element 19 | { 20 | friend Element; 21 | 22 | public: 23 | Text(){}; 24 | ~Text(){}; 25 | 26 | 27 | 28 | Text( int x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ){ 29 | Setup(x, y, ss, primarySelector,secondarySelector); 30 | } 31 | 32 | Text( int x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ){ 33 | Setup(x, y, ss, primarySelector,secondarySelector); 34 | } 35 | 36 | Text( string x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ){ 37 | Setup(x, y, ss, primarySelector,secondarySelector); 38 | } 39 | 40 | Text( string x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ){ 41 | Setup(x, y, ss, primarySelector,secondarySelector); 42 | } 43 | 44 | 45 | 46 | void ParsePropValue( string prop, string value ){ 47 | //ofLog() << prop << ":" << value; 48 | 49 | if ( prop == "text-align" || prop == "textAlign" ){ 50 | if (value == "left-top") SetTextAlignment(VUI_ALIGN_LEFT_TOP); 51 | else if (value == "left-center") SetTextAlignment(VUI_ALIGN_LEFT_CENTER); 52 | else if (value == "left-bottom") SetTextAlignment(VUI_ALIGN_LEFT_BOTTOM); 53 | else if (value == "center-top") SetTextAlignment(VUI_ALIGN_CENTER_TOP); 54 | else if (value == "center-center") SetTextAlignment(VUI_ALIGN_CENTER_CENTER); 55 | else if (value == "center-bottom") SetTextAlignment(VUI_ALIGN_CENTER_BOTTOM); 56 | else if (value == "right-top") SetTextAlignment(VUI_ALIGN_RIGHT_TOP); 57 | else if (value == "right-center") SetTextAlignment(VUI_ALIGN_RIGHT_CENTER); 58 | else if (value == "right-bottom") SetTextAlignment(VUI_ALIGN_RIGHT_BOTTOM); 59 | } else if ( prop == "text-shadow" ){ 60 | vector xy = ofSplitString( value, "," ); 61 | if ( xy.size() == 2 ) SetTextShadow( ofToInt( xy[0] ), ofToInt( xy[1] ) ); 62 | else if ( xy.size() == 3 ) SetTextShadow( ofToInt( xy[0] ), ofToInt( xy[1] ), ofToInt(xy[2]) ); 63 | } else if ( prop == "color" ) { 64 | string colorStr(value); 65 | 66 | float floatColor; 67 | if ( colorStr.find("#") != string::npos ){ 68 | string str(colorStr); 69 | 70 | ofStringReplace(str, "#", ""); 71 | floatColor = stoul(str, nullptr, 16); 72 | } else { 73 | floatColor = ofToFloat( colorStr ); 74 | } 75 | 76 | textColor.setHex(floatColor, 255.0); 77 | } else if ( prop == "padding" ){ 78 | vector xy = ofSplitString( value, "," ); 79 | if ( xy.size() == 1 ) SetPadding( ofToInt(xy[0]) ); 80 | else if ( xy.size() == 2 ) SetPadding( ofToInt(xy[0]), ofToInt(xy[1]) ); 81 | else if ( xy.size() == 4 ) SetPadding( ofToInt(xy[0]), ofToInt(xy[1]), ofToInt(xy[2]), ofToInt(xy[3]) ); 82 | } else if ( prop == "padding-left" ){ 83 | SetPaddingLeft( ofToInt(value) ); 84 | } else if ( prop == "padding-top" ){ 85 | SetPaddingTop( ofToInt(value) ); 86 | } else if ( prop == "padding-right" ){ 87 | SetPaddingRight( ofToInt(value) ); 88 | } else if ( prop == "padding-bottom" ){ 89 | SetPaddingBottom( ofToInt(value) ); 90 | } 91 | } 92 | 93 | 94 | string text = ""; 95 | Align textAlignment = VUI_ALIGN_LEFT_TOP; 96 | 97 | float GetTextOpacity(){ 98 | if ( HasParent() ) return parent->GetOpacity() * GetOpacity(); 99 | else return GetOpacity(); 100 | } 101 | 102 | float GetTextOpacity255(){ 103 | return GetTextOpacity()*255.0; 104 | } 105 | 106 | Text* SetText( string t, bool sizeToText = false ){ 107 | text = t; 108 | UpdateRect(); 109 | if ( sizeToText ) SizeToText(); 110 | return this; 111 | } 112 | 113 | Text* SetTextColor( string hexColor ){ 114 | float floatColor; 115 | 116 | if ( hexColor.find("#") != string::npos ){ 117 | string str(hexColor); 118 | 119 | ofStringReplace(str, "#", ""); 120 | floatColor = stoul(str, nullptr, 16); 121 | } else { 122 | floatColor = ofToFloat( hexColor ); 123 | } 124 | 125 | textColor.setHex(floatColor, 255.0); 126 | }; 127 | 128 | string GetText(){ 129 | return text; 130 | } 131 | 132 | void SizeToText(){ 133 | ofRectangle rect = font->getStringBoundingBox(text, 0,0); 134 | rect.width*=VUI::divideDpi; 135 | rect.height*=VUI::divideDpi; 136 | SetSize( rect.width + (padding.left+padding.right)*VUI::dpi, rect.height + (padding.top+padding.bottom)*VUI::dpi ); 137 | } 138 | 139 | void SizeWidthToText(){ 140 | ofRectangle rect = font->getStringBoundingBox(text, 0,0); 141 | rect.width*=VUI::divideDpi; 142 | rect.height*=VUI::divideDpi; 143 | SetWidth( rect.width + padding.left*VUI::dpi + padding.top*VUI::dpi ); 144 | } 145 | 146 | bool IsFocused(){ 147 | if ( GetVirtualState() == VUI_STATE_DOWN ) return true; 148 | return false; 149 | } 150 | 151 | ofTrueTypeFont* GetFont(){ 152 | return font; 153 | } 154 | 155 | void SetTextAlignment( Align align ){ 156 | textAlignment = align; 157 | } 158 | 159 | 160 | 161 | ofVec2f textOffset; 162 | ofVec3f shadowPos = ofVec3f(0,0,210); 163 | ofColor textColor = ofColor::gray; 164 | ofColor tempTextColor = ofColor::gray; 165 | 166 | 167 | int spaceOffsetX = 0; 168 | 169 | bool hasTextShadow = false; 170 | void SetTextShadow( float x, float y, float opacity = 1.0 ){ 171 | shadowPos.set(x,y, opacity); 172 | hasTextShadow = true; 173 | } 174 | 175 | bool isTextField = false; 176 | int dpi = -1; 177 | 178 | ofRectangle rect; 179 | 180 | void RenderAfter(ofRectangle& parentRect){ 181 | if ( dpi == -1 ) dpi = VUI::dpi; 182 | if ( dpi != VUI::dpi ) { 183 | _Calibrate(true); 184 | UpdateRect(); 185 | dpi = VUI::dpi; 186 | } 187 | 188 | if ( font != nullptr ) { 189 | _Calibrate(); 190 | 191 | //ofSetColor(255,0,255,255); 192 | float x = 0; 193 | float y = 0; 194 | 195 | switch( textAlignment ){ 196 | case VUI_ALIGN_LEFT_TOP: 197 | x = padding.left*VUI::dpi; 198 | y = padding.top*VUI::dpi; 199 | break; 200 | case VUI_ALIGN_LEFT_CENTER: 201 | x = padding.left*VUI::dpi; 202 | //y = ((GetOriginalHeight() - textOffset.y)*0.5) + textOffset.y*0.5; 203 | y = (GetHeight() - originalRect.height)*0.5; 204 | break; 205 | case VUI_ALIGN_LEFT_BOTTOM: 206 | x = padding.left*VUI::dpi; 207 | y = (GetHeight() - originalRect.height) - padding.bottom*VUI::dpi; 208 | break; 209 | case VUI_ALIGN_CENTER_TOP: 210 | x = (GetWidth() - rect.width)*0.5; 211 | y = padding.top*VUI::dpi; 212 | break; 213 | case VUI_ALIGN_CENTER_CENTER: 214 | x = (GetWidth() - rect.width)*0.5; 215 | y = (GetHeight() - originalRect.height)*0.5; 216 | break; 217 | case VUI_ALIGN_CENTER_BOTTOM: 218 | x = (GetWidth() - rect.width)*0.5; 219 | y = (GetHeight() - originalRect.height) - padding.bottom*VUI::dpi; 220 | break; 221 | case VUI_ALIGN_RIGHT_TOP: 222 | x = GetWidth() - rect.width - padding.right*VUI::dpi - VUI::dpi; 223 | y = padding.top*VUI::dpi; 224 | break; 225 | case VUI_ALIGN_RIGHT_CENTER: 226 | x = GetWidth() - rect.width - padding.right*VUI::dpi - VUI::dpi; 227 | y = (GetHeight() - originalRect.height)*0.5; 228 | break; 229 | case VUI_ALIGN_RIGHT_BOTTOM: 230 | x = GetWidth() - rect.width - padding.right*VUI::dpi - VUI::dpi; 231 | y = (GetHeight() - originalRect.height) - padding.bottom*VUI::dpi; 232 | break; 233 | } 234 | 235 | //x*=VUI::dpi; 236 | //y*=VUI::dpi; 237 | 238 | //x-=VUI::dpi; 239 | 240 | float op = GetTextOpacity255(); 241 | 242 | if ( hasTextShadow ) { 243 | ofSetColor(0,0,0, shadowPos.z*op ); 244 | font->drawString( text, shadowPos.x + parentRect.x + x, shadowPos.y + parentRect.y + y + textOffset.y ); 245 | } 246 | 247 | ofSetColor(textColor, op); 248 | if ( styleFloat[renderState]["color"] ){ 249 | tempTextColor.setHex(styleFloat[renderState]["color"], 255); 250 | ofSetColor(tempTextColor, op); 251 | } 252 | font->drawString( text, parentRect.x + x, parentRect.y + y + textOffset.y ); 253 | 254 | ofSetColor(0,0,0,255); 255 | 256 | // typing cursor 257 | //if ( isTextField && GetVirtualState() == VUI_STATE_DOWN ) ofDrawRectangle( parentRect.x + spaceOffsetX + padding.left*VUI::divideDpi + x + rect.width + (font->getSize()*.18), parentRect.y + padding.top*VUI::divideDpi + y - 1 - 2, VUI::dpi, rect.height*VUI::dpi); 258 | if ( isTextField && GetVirtualState() == VUI_STATE_DOWN ) ofDrawRectangle( parentRect.x + spaceOffsetX + x + rect.width + VUI::dpi, parentRect.y + y - 2*VUI::dpi, VUI::dpi, _typingIndicatorHeight); 259 | } 260 | } 261 | 262 | 263 | 264 | void UpdateRect(){ 265 | rect = font->getStringBoundingBox(text, 0,0); 266 | //rect.width *= VUI::divideDpi; 267 | //rect.height *= VUI::divideDpi; 268 | } 269 | 270 | void Setup(int x, int y, StyleSheet *ss = nullptr, const string primarySelector = "", const string secondarySelector = ""){ 271 | Element::Setup(x, y, ss,primarySelector,secondarySelector); 272 | Setup(ss, primarySelector, secondarySelector); 273 | } 274 | 275 | void Setup(string x, int y, StyleSheet *ss = nullptr, const string primarySelector = "", const string secondarySelector = ""){ 276 | Element::Setup(x, y, ss,primarySelector,secondarySelector); 277 | Setup(ss, primarySelector, secondarySelector); 278 | } 279 | 280 | void Setup(int x, string y, StyleSheet *ss = nullptr, const string primarySelector = "", const string secondarySelector = ""){ 281 | Element::Setup(x, y, ss,primarySelector,secondarySelector); 282 | Setup(ss, primarySelector, secondarySelector); 283 | } 284 | 285 | void Setup(string x, string y, StyleSheet *ss = nullptr, const string primarySelector = "", const string secondarySelector = ""){ 286 | Element::Setup(x, y, ss,primarySelector,secondarySelector); 287 | Setup(ss, primarySelector, secondarySelector); 288 | } 289 | 290 | void Setup(StyleSheet *ss = nullptr, const string primarySelector = "", const string secondarySelector = ""){ 291 | textColor.setHex(stoul("0x000000", nullptr, 16), 255.0 ); 292 | 293 | for (int i = 0; i < 3; i++) { 294 | style[i]["background-color"] = "clear"; 295 | } 296 | 297 | hasStyle = false; 298 | 299 | ParseStyle(); 300 | 301 | ParseStyleSheet(ss, primarySelector, secondarySelector ); 302 | 303 | 304 | //textOffset.y = VUI::fontSize; 305 | //if ( font != nullptr ) textOffset.y = font->getSize(); 306 | 307 | /*vector split = SplitStyles( unparsedStyle ); 308 | 309 | vector tempSplit; 310 | 311 | for (vector::iterator it = split.begin(); it != split.end(); it++) { 312 | tempSplit = ofSplitString((*it), ":"); 313 | if (tempSplit.size() == 2) { 314 | ParsePropValue( tempSplit[0], tempSplit[1] ); 315 | } 316 | }*/ 317 | 318 | for ( map::iterator it = propValue.begin(); it != propValue.end(); it++){ 319 | ParsePropValue( (*it).first, (*it).second ); 320 | } 321 | } 322 | 323 | virtual int GetInnerWidth(bool scaled = true){ return GetWidth(scaled) - padding.right*VUI::dpi - padding.left*VUI::dpi; } 324 | virtual int GetInnerHeight(bool scaled = true){ return GetHeight(scaled) - padding.bottom*VUI::dpi - padding.top*VUI::dpi; } 325 | 326 | private: 327 | 328 | 329 | bool _isCalibrated = false; 330 | float _typingIndicatorOffset; 331 | float _typingIndicatorHeight = 0; 332 | ofRectangle originalRect; 333 | void _Calibrate(bool force = false){ 334 | if ( _isCalibrated && !force ) return; 335 | _isCalibrated = true; 336 | 337 | originalRect = font->getStringBoundingBox("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0,0); 338 | 339 | //textOffset.set(0,originalRect.height*.25 + font->getSize()*.75 ); 340 | textOffset.set(0, font->getSize() ); 341 | 342 | //if ( VUI::dpi == 1.0 ) textOffset.y = -10.0; 343 | //ofLog() << VUI::dpi; 344 | 345 | //textOffset.y*=VUI::divideDpi; 346 | _typingIndicatorOffset = textOffset.y; 347 | _typingIndicatorHeight = originalRect.height + 4*VUI::dpi; 348 | } 349 | 350 | 351 | 352 | 353 | }; 354 | 355 | } 356 | 357 | 358 | #endif 359 | -------------------------------------------------------------------------------- /src/VUITextField.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxVui.h" 2 | #include "VUITextField.h" 3 | 4 | namespace VUI { 5 | void TextField::_vuiEventHandler(vuiEventArgs& evt){ 6 | if ( evt.eventType == VUI_EVENT_VALUE_CHANGE ){ 7 | if ( evt.value == 1 ) { 8 | VUI::ResetTextFields(this); 9 | 10 | TriggerEvent( VUI_EVENT_FOCUS ); 11 | VUI::activeTextField = this; 12 | 13 | if ( text == placeholder ) SetText(""); 14 | } else if ( evt.value == 0 ) { 15 | TriggerEvent( VUI_EVENT_UNFOCUS ); 16 | if ( VUI::activeTextField == this ) VUI::activeTextField = NULL; 17 | if ( text == "" ) SetText(placeholder); 18 | } 19 | } 20 | } 21 | 22 | void TextField::_Setup(){ 23 | MakeToggle(); 24 | isTextField = true; 25 | 26 | VUI::textFields.push_back(this); 27 | 28 | ofAddListener( ofEvents().keyPressed, this, &TextField::keyPressed ); 29 | ofAddListener( onValueChange, this, &TextField::_vuiEventHandler ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/VUITextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // xTextField.h 3 | // 4 | // Created by Christopher Miles on 9/27/17. 5 | // 6 | // 7 | 8 | #pragma once 9 | 10 | #ifndef __ofxVui_TextField__ 11 | #define __ofxVui_TextField__ 12 | 13 | #include "ofMain.h" 14 | 15 | namespace VUI { 16 | 17 | 18 | class TextField : public Text 19 | { 20 | friend Text; 21 | 22 | public: 23 | TextField(){}; 24 | ~TextField(){}; 25 | 26 | 27 | TextField( int x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Text(x,y,ss,primarySelector,secondarySelector){ 28 | _Setup(); 29 | } 30 | 31 | TextField( int x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Text(x,y,ss,primarySelector,secondarySelector){ 32 | _Setup(); 33 | } 34 | 35 | TextField( string x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Text(x,y,ss,primarySelector,secondarySelector){ 36 | _Setup(); 37 | } 38 | 39 | TextField( string x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Text(x,y,ss,primarySelector,secondarySelector){ 40 | _Setup(); 41 | } 42 | 43 | ofEvent onSubmit; 44 | 45 | void TriggerSubmit(){ 46 | SetState(VUI_STATE_UP); 47 | 48 | vuiEventArgs args; 49 | args.element = this; 50 | args.eventType = VUI_EVENT_SUBMIT; 51 | args.text = text; 52 | 53 | ofNotifyEvent(onSubmit, args, this); 54 | } 55 | 56 | int textLimit = -1; 57 | 58 | void SetLimit( int limit ){ 59 | textLimit = limit; 60 | } 61 | 62 | void AddText( string t){ 63 | if ( textLimit != -1 ) { 64 | if ( text.size() >= textLimit ) return; 65 | } 66 | 67 | ofRectangle rect = font->getStringBoundingBox(text + t , 0,0); 68 | rect.width += VUI::dpi; 69 | 70 | if ( t == " " ) rect.width += font->getSize() * .85; 71 | 72 | if ( rect.width >= GetInnerWidth() ) return; 73 | 74 | text = text + t; 75 | if ( t == " " ) spaceOffsetX = font->getSize() * .5; 76 | else spaceOffsetX = 0; 77 | 78 | UpdateRect(); 79 | TriggerValueChangeEvent(); 80 | } 81 | 82 | void Backspace(){ 83 | if ( text.size() < 1 ) return; 84 | 85 | text = text.substr(0, text.size()-1); 86 | if ( text.size() > 0 && text.substr(text.size()-1,1) == " " ) spaceOffsetX = font->getSize() * .5; 87 | else spaceOffsetX = 0; 88 | 89 | UpdateRect(); 90 | 91 | TriggerValueChangeEvent(); 92 | } 93 | 94 | void ClearText(){ 95 | text = ""; 96 | UpdateRect(); 97 | TriggerValueChangeEvent(); 98 | _CheckPlaceholder(); 99 | } 100 | 101 | void AddText( char c ){ 102 | AddText( ofToString(c) ); 103 | } 104 | 105 | string placeholder = ""; 106 | 107 | void SetPlaceholderText( string str ){ 108 | placeholder = str; 109 | _CheckPlaceholder(); 110 | } 111 | 112 | 113 | 114 | void TriggerValueChangeEvent(){ 115 | vuiEventArgs args; 116 | args.element = this; 117 | args.eventType = VUI_EVENT_TEXT_CHANGE; 118 | args.text = text; 119 | 120 | ofNotifyEvent(onTextChange, args, this); 121 | } 122 | 123 | void keyPressed(ofKeyEventArgs &key ){ 124 | if ( GetVirtualState() != VUI_STATE_DOWN ) return; 125 | //ofLog() << key.key; 126 | 127 | switch(key.key){ 128 | case OF_KEY_BACKSPACE: 129 | case OF_KEY_DEL: 130 | Backspace(); 131 | return; 132 | break; 133 | case OF_KEY_RETURN: 134 | TriggerSubmit(); 135 | return; 136 | break; 137 | case OF_KEY_ESC: 138 | case OF_KEY_TAB: 139 | case OF_KEY_COMMAND: 140 | case OF_KEY_F1: 141 | case OF_KEY_F2: 142 | case OF_KEY_F3: 143 | case OF_KEY_F4: 144 | case OF_KEY_F5: 145 | case OF_KEY_F6: 146 | case OF_KEY_F7: 147 | case OF_KEY_F8: 148 | case OF_KEY_F9: 149 | case OF_KEY_F10: 150 | case OF_KEY_F11: 151 | case OF_KEY_F12: 152 | case OF_KEY_LEFT: 153 | case OF_KEY_UP: 154 | case OF_KEY_RIGHT: 155 | case OF_KEY_DOWN: 156 | case OF_KEY_PAGE_UP: 157 | case OF_KEY_PAGE_DOWN: 158 | case OF_KEY_HOME: 159 | case OF_KEY_END: 160 | case OF_KEY_INSERT: 161 | case OF_KEY_CONTROL: 162 | case OF_KEY_ALT: 163 | case OF_KEY_SHIFT: 164 | case OF_KEY_LEFT_SHIFT: 165 | case OF_KEY_RIGHT_SHIFT: 166 | case OF_KEY_LEFT_CONTROL: 167 | case OF_KEY_RIGHT_CONTROL: 168 | case OF_KEY_LEFT_ALT: 169 | case OF_KEY_RIGHT_ALT: 170 | case OF_KEY_LEFT_SUPER: 171 | case OF_KEY_RIGHT_SUPER: 172 | return; 173 | break; 174 | } 175 | 176 | if ( ofGetKeyPressed(OF_KEY_SUPER) ) return; 177 | 178 | AddText((char)key.key); 179 | } 180 | 181 | bool IsFocused(){ 182 | if ( GetVirtualState() == VUI_STATE_DOWN ) return true; 183 | return false; 184 | } 185 | 186 | 187 | private: 188 | void _vuiEventHandler(vuiEventArgs& evt); 189 | void _CheckPlaceholder(){ 190 | if ( text == "" ) SetText(placeholder); 191 | } 192 | void _Setup(); 193 | }; 194 | 195 | } 196 | 197 | 198 | #endif 199 | -------------------------------------------------------------------------------- /src/VUIToggleGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // xText.h 3 | // 4 | // Created by Christopher Miles on 9/27/17. 5 | // 6 | // 7 | 8 | #pragma once 9 | 10 | #ifndef __ofxVui_ToggleGroup__ 11 | #define __ofxVui_ToggleGroup__ 12 | 13 | #include "ofMain.h" 14 | 15 | namespace VUI { 16 | 17 | class ToggleGroup : public Element 18 | { 19 | public: 20 | ToggleGroup(){}; 21 | ~ToggleGroup(){}; 22 | 23 | ToggleGroup( int x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Element(x,y,ss,primarySelector,secondarySelector){ 24 | } 25 | 26 | ToggleGroup( int x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Element(x,y,ss,primarySelector,secondarySelector){ 27 | } 28 | 29 | ToggleGroup( string x, int y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Element(x,y,ss,primarySelector,secondarySelector){ 30 | } 31 | 32 | ToggleGroup( string x, string y, StyleSheet *ss = nullptr, string primarySelector = "", string secondarySelector = "" ):Element(x,y,ss,primarySelector,secondarySelector){ 33 | } 34 | 35 | ofEvent onToggleChange; 36 | 37 | void AddToggle(Element* toggle, bool setSelected = false ){ 38 | if ( setSelected ) toggle->SetSelected(); 39 | 40 | AddChild( toggle ); 41 | toggle->MakeToggle(); 42 | toggles.push_back( toggle ); 43 | ofAddListener( toggle->onValueChange, this, &ToggleGroup::_vuiEventHandler ); 44 | ofAddListener( toggle->onMouseClick, this, &ToggleGroup::_vuiEventHandler ); 45 | 46 | if ( shouldSelectOnHover ){ 47 | ofAddListener( toggle->onMouseOver, this, &ToggleGroup::_vuiEventHandler ); 48 | } 49 | } 50 | 51 | void SelectOnHover(){ 52 | shouldSelectOnHover = true; 53 | for ( vector::iterator it = toggles.begin(); it != toggles.end(); it++ ){ 54 | ofAddListener( (*it)->onMouseOver, this, &ToggleGroup::_vuiEventHandler ); 55 | } 56 | } 57 | 58 | void Reset(bool notifyEvent = true){ 59 | for ( vector::iterator it = toggles.begin(); it != toggles.end(); it++ ){ 60 | (*it)->SetSelected(false, notifyEvent); 61 | } 62 | } 63 | 64 | void SelectToggleByIndex( int index ){ 65 | int count = 0; 66 | for ( vector::iterator it = toggles.begin(); it != toggles.end(); it++ ){ 67 | if ( count == index ) (*it)->SetSelected(true); 68 | else (*it)->SetSelected(false); 69 | count++; 70 | } 71 | } 72 | 73 | Element* GetToggleByIndex( int index ) { 74 | return toggles[index]; 75 | } 76 | 77 | private: 78 | 79 | bool shouldSelectOnHover = false; 80 | 81 | vector toggles; 82 | 83 | void _vuiEventHandler(vuiEventArgs& evt){ 84 | 85 | if ( shouldSelectOnHover && evt.eventType == VUI_EVENT_MOUSE_OVER ){ 86 | if ( evt.element->GetVirtualState() != VUI_STATE_DOWN ){ 87 | for ( vector::iterator it = toggles.begin(); it != toggles.end(); it++ ){ 88 | if ( (*it)->GetState() == VUI_STATE_DOWN ) { 89 | (*it)->SetSelected(false); 90 | evt.element->SetSelected(true); 91 | 92 | 93 | return; 94 | } 95 | } 96 | } 97 | return; 98 | } 99 | 100 | if ( evt.eventType == VUI_EVENT_VALUE_CHANGE ){ 101 | vuiEventArgs args; 102 | args.eventType = VUI_EVENT_VALUE_CHANGE; 103 | args.element = evt.element; 104 | args.value = evt.value; 105 | ofNotifyEvent( onToggleChange, args, evt.element ); 106 | 107 | if (evt.value == 1 ){ 108 | for ( vector::iterator it= toggles.begin(); it != toggles.end(); it++){ 109 | if ( (*it) != evt.element ) (*it)->SetSelected(false); 110 | } 111 | 112 | vuiEventArgs args; 113 | args.eventType = VUI_EVENT_TOGGLE_CHANGE; 114 | args.element = evt.element; 115 | args.value = evt.value; 116 | ofNotifyEvent( onToggleChange, args, this ); 117 | } else { 118 | 119 | } 120 | 121 | 122 | 123 | 124 | 125 | } else if ( evt.eventType == VUI_EVENT_MOUSE_CLICK ){ 126 | 127 | /*vuiEventArgs args; 128 | args.eventType = VUI_EVENT_TOGGLE_CHANGE; 129 | args.element = this; 130 | args.value = evt.value; 131 | ofNotifyEvent( onToggleChange, args, this );*/ 132 | } 133 | } 134 | 135 | 136 | }; 137 | 138 | } 139 | 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /src/VUIView.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxVui.h" 2 | #include "VUIView.h" 3 | 4 | namespace VUI { 5 | View::~View() {}; 6 | View::View() {}; 7 | 8 | void View::ExitView() { 9 | VUI::Next(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/VUIView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef __ofxViewManager_View__ 4 | #define __ofxViewManager_View__ 5 | 6 | #include "ofMain.h" 7 | 8 | namespace VUI { 9 | class View { 10 | friend class ViewManagerBridge; 11 | 12 | public: 13 | 14 | virtual ~View(); 15 | View(); 16 | 17 | int mouseX = 0; 18 | int mouseY = 0; 19 | 20 | virtual void OnEnterView() {}; 21 | 22 | /* 23 | if overriding BeforeExitView(), you must call ExitView() 24 | when you're done with what you need to do 25 | */ 26 | virtual void BeforeExitView() { 27 | ExitView(); 28 | }; 29 | 30 | bool IsMouseInside(){ 31 | return _isMouseInside; 32 | }; 33 | 34 | // -------------------------------------------------------- the usual suspects 35 | 36 | virtual void setup() {}; 37 | virtual void draw() {} 38 | virtual void update() {}; 39 | 40 | virtual void windowResized(int w, int h) {} 41 | 42 | virtual void keyPressed(int key) {} 43 | virtual void keyReleased(int key) {} 44 | 45 | virtual void mouseMoved(int x, int y) {} 46 | virtual void mouseDragged(int x, int y, int button) {} 47 | virtual void mousePressed(int x, int y, int button) {} 48 | virtual void mouseReleased(int x, int y, int button) {} 49 | virtual void mouseScrolled(int x, int y, float scrollX, float scrollY) {} 50 | virtual void mouseEntered(int x, int y) {} 51 | virtual void mouseExited(int x, int y) {} 52 | 53 | virtual void dragEvent(ofDragInfo dragInfo) { } 54 | virtual void gotMessage(ofMessage msg) { } 55 | 56 | virtual void touchDown(int x, int y, int id) {}; 57 | virtual void touchMoved(int x, int y, int id) {}; 58 | virtual void touchUp(int x, int y, int id) {}; 59 | 60 | virtual void touchDoubleTap(int x, int y, int id) {}; 61 | virtual void touchCancelled(int x, int y, int id) {}; 62 | 63 | #ifdef USING_ofxTouchPadScroll 64 | virtual void touchPadScroll(int x, int y, int vuiEvent){}; 65 | #endif 66 | 67 | // -------------------------------------------------------- 68 | 69 | void Render() { 70 | draw(); 71 | }; 72 | 73 | protected: 74 | 75 | void UpdateMousePos(int x, int y) { 76 | mouseX = x; 77 | mouseY = y; 78 | } 79 | 80 | bool _didSetup = false; 81 | void _Setup(){ 82 | if (_didSetup) return; 83 | else { 84 | _didSetup = true; 85 | setup(); 86 | } 87 | } 88 | 89 | void _TriggerExitView(){ 90 | ExitView(); 91 | } 92 | 93 | void _SetIsMouseInside(bool b){ 94 | _isMouseInside = b; 95 | } 96 | 97 | void ExitView(); 98 | bool _isMouseInside = false; 99 | }; 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /src/ofxVui.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxVui.h" 2 | #include "VUIElement.h" 3 | #include "VUIView.h" 4 | 5 | namespace VUI { 6 | 7 | StyleSheet* _vuiStyleSheet; 8 | 9 | #ifdef USING_ofxTouchPadScroll 10 | ofxTouchPadScroll tps; 11 | #endif 12 | 13 | map< string, View*> views; 14 | 15 | map< int, ofPoint> touches; 16 | map styleSheets; 17 | vector textFields; 18 | TextField* activeTextField = NULL; 19 | 20 | string nextView; 21 | string currView; 22 | 23 | ofVec2f multCoords(1.0, 1.0); 24 | 25 | ViewManagerBridge PRIVATE; 26 | 27 | bool isListening = false; 28 | 29 | int mouseX; 30 | int mouseY; 31 | float dpi = 1.0; 32 | float divideDpi = 1.0; 33 | float divideRetinaDpi = .5; 34 | float multRetinaDpi = 2.0; 35 | 36 | int vw = -1; 37 | int vh = -1; 38 | float vscale = 1.0; 39 | ofFbo fbo; 40 | 41 | vector visibleViews; 42 | vector hideViews; 43 | 44 | float backgroundOpacity = 0.0; 45 | ofColor backgroundColor = ofColor(255); 46 | 47 | /*void ViewManagerBridge::update(ofEventArgs &e) { 48 | cout << "ViewManagerBridge - update - " << ofRandomf() << endl; 49 | if ( !VUI::currView.empty() ) VUI::GetCurrentView()->update(e); 50 | }*/ 51 | 52 | Tween* Animate( Element* el, float timeSeconds, string params ){ 53 | Tween *t = new Tween(); 54 | t->Start( el, timeSeconds, params ); 55 | 56 | tweens.push_back( t ); 57 | return t; 58 | } 59 | 60 | void ViewManagerBridge::StartView(string name) { 61 | //ofLog() << "name:" << name << " curr:" << VUI::currView << " next:" << VUI::nextView; 62 | /*if (name = VUI::nextView) { 63 | VUI::nextView.clear(); 64 | return; 65 | }*/ 66 | 67 | VUI::currView = VUI::nextView; 68 | 69 | if (!VUI::currView.empty() && VUI::views[VUI::currView] != nullptr) { 70 | VUI::views[VUI::currView]->_Setup(); 71 | VUI::views[VUI::currView]->OnEnterView(); 72 | } 73 | 74 | 75 | if (VUI::IsTouchEnabled()) { 76 | if (!VUI::GetTouchDown()) VUI::GetCurrentEventManager()->Enable(); 77 | } 78 | else { 79 | if (!ofGetMousePressed()) VUI::GetCurrentEventManager()->Enable(); 80 | } 81 | 82 | //ofLog() << "mousePressed: " << ofGetMousePressed(); 83 | 84 | VUI::nextView.clear(); 85 | } 86 | 87 | void ViewManagerBridge::setup(ofEventArgs & args) { 88 | //update(); 89 | 90 | VUI::mouseX = ofGetMouseX()*multCoords.x; 91 | VUI::mouseY = ofGetMouseY()*multCoords.y; 92 | 93 | if (!VUI::currView.empty()) VUI::GetCurrentView()->setup(); 94 | } 95 | 96 | void ViewManagerBridge::update(ofEventArgs & args) { 97 | //update(); 98 | //ofLog() << "ViewManagerBridge::update - " << ofGetMouseX() << "x" << ofGetMouseY() << " - " << ofRandomf() << endl; 99 | 100 | 101 | 102 | if (!VUI::currView.empty()) VUI::GetCurrentView()->update(); 103 | 104 | for (vector::iterator it = hideViews.begin(); it != hideViews.end(); it++) { 105 | VUI::ActualHideView((*it)); 106 | } 107 | 108 | hideViews.clear(); 109 | } 110 | void ViewManagerBridge::draw(ofEventArgs & args) { 111 | //draw(); 112 | //ofLog() << "ViewManagerBridge::draw - " << ofRandomf() << endl; 113 | if (!VUI::currView.empty()) VUI::GetCurrentView()->draw(); 114 | } 115 | 116 | void ViewManagerBridge::windowResized(ofResizeEventArgs & resize) { 117 | //windowResized(resize.width, resize.height); 118 | VUI::vw = resize.width; 119 | VUI::vh = resize.height; 120 | 121 | VUI::GetCurrentEventManager()->vw = resize.width; 122 | VUI::GetCurrentEventManager()->vh = resize.height; 123 | 124 | if (!VUI::currView.empty()) VUI::GetCurrentView()->windowResized(resize.width, resize.height); 125 | } 126 | 127 | void ViewManagerBridge::keyPressed(ofKeyEventArgs & key) { 128 | //keyPressed(key.key); 129 | if (!VUI::currView.empty()) VUI::GetCurrentView()->keyPressed(key.key); 130 | } 131 | void ViewManagerBridge::keyReleased(ofKeyEventArgs & key) { 132 | //keyReleased(key.key); 133 | if (!VUI::currView.empty()) VUI::GetCurrentView()->keyReleased(key.key); 134 | } 135 | 136 | 137 | 138 | 139 | 140 | 141 | void ViewManagerBridge::mouseMoved(ofMouseEventArgs & mouse) { 142 | //mouseX = mouse.x; 143 | //mouseY = mouse.y; 144 | //mouseMoved(mouse.x, mouse.y); 145 | // 146 | VUI::mouseX = mouse.x*multCoords.x; 147 | VUI::mouseY = mouse.y*multCoords.y; 148 | 149 | 150 | 151 | if (!VUI::currView.empty()) { 152 | /*#ifdef USING_ofxSupervui 153 | if ( !VUI::EventManager.active ) return; 154 | #endif*/ 155 | 156 | //cout << VUI::mouseX << "x" << VUI::mouseY << endl; 157 | 158 | if ( mouse.x < 0 || mouse.y < 0 ) VUI::GetCurrentView()->_SetIsMouseInside(false); 159 | else if (mouse.x > VUI::GetWindowWidth() || mouse.y > VUI::GetWindowHeight() ) VUI::GetCurrentView()->_SetIsMouseInside(false); 160 | else VUI::GetCurrentView()->_SetIsMouseInside(true); 161 | 162 | ofMouseEventArgs args(ofMouseEventArgs::Moved, VUI::mouseX, VUI::mouseY); 163 | ofNotifyEvent(onMouseMoved, args, this); 164 | 165 | VUI::GetCurrentView()->UpdateMousePos(VUI::mouseX, VUI::mouseY); 166 | VUI::GetCurrentView()->mouseMoved(VUI::mouseX, VUI::mouseY); 167 | } 168 | } 169 | void ViewManagerBridge::mouseDragged(ofMouseEventArgs & mouse) { 170 | //mouseX = mouse.x; 171 | //mouseY = mouse.y; 172 | //mouseDragged(mouse.x, mouse.y, mouse.button); 173 | VUI::mouseX = mouse.x*multCoords.x; 174 | VUI::mouseY = mouse.y*multCoords.y; 175 | 176 | if (!VUI::currView.empty()) { 177 | if (!VUI::GetCurrentEventManager()->active) return; 178 | 179 | ofMouseEventArgs args(ofMouseEventArgs::Dragged, VUI::mouseX, VUI::mouseY, mouse.button); 180 | ofNotifyEvent(onMouseDragged, args, this); 181 | 182 | VUI::GetCurrentView()->UpdateMousePos(VUI::mouseX, VUI::mouseY); 183 | VUI::GetCurrentView()->mouseDragged(VUI::mouseX, VUI::mouseY, mouse.button); 184 | } 185 | } 186 | void ViewManagerBridge::mousePressed(ofMouseEventArgs & mouse) { 187 | //mouseX = mouse.x; 188 | //mouseY = mouse.y; 189 | //mousePressed(mouse.x, mouse.y, mouse.button); 190 | 191 | VUI::mouseX = mouse.x*multCoords.x; 192 | VUI::mouseY = mouse.y*multCoords.y; 193 | 194 | if (!VUI::currView.empty()) { 195 | if (!VUI::GetCurrentEventManager()->active) return; 196 | 197 | VUI::GetCurrentView()->_SetIsMouseInside(true); 198 | 199 | ofMouseEventArgs args(ofMouseEventArgs::Pressed, VUI::mouseX, VUI::mouseY, mouse.button); 200 | ofNotifyEvent(onMousePressed, args, this); 201 | 202 | VUI::GetCurrentView()->UpdateMousePos(VUI::mouseX, VUI::mouseY); 203 | VUI::GetCurrentView()->mousePressed(VUI::mouseX, VUI::mouseY, mouse.button); 204 | } 205 | } 206 | 207 | void ViewManagerBridge::mouseReleased(ofMouseEventArgs & mouse) { 208 | //mouseX = mouse.x; 209 | //mouseY = mouse.y; 210 | //mouseReleased(mouse.x, mouse.y, mouse.button); 211 | VUI::mouseX = mouse.x*multCoords.x; 212 | VUI::mouseY = mouse.y*multCoords.y; 213 | 214 | if (!VUI::currView.empty()) { 215 | 216 | if (!VUI::GetCurrentEventManager()->active) { 217 | if (VUI::GetCurrentEventManager()->enableOnMouseUp) VUI::GetCurrentEventManager()->DelayEnable(50); 218 | return; 219 | } 220 | 221 | ofMouseEventArgs args(ofMouseEventArgs::Released, VUI::mouseX, VUI::mouseY, mouse.button); 222 | ofNotifyEvent(onMouseReleased, args, this); 223 | 224 | VUI::GetCurrentView()->UpdateMousePos(VUI::mouseX, VUI::mouseY); 225 | VUI::GetCurrentView()->mouseReleased(VUI::mouseX, VUI::mouseY, mouse.button); 226 | } 227 | 228 | if (VUI::GetCurrentEventManager()->enableOnMouseUp) VUI::GetCurrentEventManager()->DelayEnable(50); 229 | 230 | if ( VUI::GetPrevOverElement() == NULL ) VUI::ResetTextFields(); 231 | 232 | } 233 | 234 | 235 | void ViewManagerBridge::mouseScrolled(ofMouseEventArgs & mouse) { 236 | //mouseScrolled(mouse.x, mouse.y, mouse.scrollX, mouse.scrollY); 237 | VUI::mouseX = mouse.x*multCoords.x; 238 | VUI::mouseY = mouse.y*multCoords.y; 239 | 240 | if (!VUI::currView.empty()) { 241 | if (!VUI::GetCurrentEventManager()->active) return; 242 | 243 | ofMouseEventArgs args(ofMouseEventArgs::Scrolled, VUI::mouseX, VUI::mouseY); 244 | args.scrollX = mouse.scrollX; 245 | args.scrollY = mouse.scrollY; 246 | ofNotifyEvent(onMouseScrolled, args, this); 247 | 248 | VUI::GetCurrentView()->mouseScrolled(VUI::mouseX, VUI::mouseY, mouse.scrollX, mouse.scrollY); 249 | } 250 | } 251 | 252 | void ViewManagerBridge::mouseEntered(ofMouseEventArgs & mouse) { 253 | //mouseEntered(mouse.x, mouse.y); 254 | VUI::mouseX = mouse.x*multCoords.x; 255 | VUI::mouseY = mouse.y*multCoords.y; 256 | 257 | if (!VUI::currView.empty()) { 258 | /*#ifdef USING_ofxSupervui 259 | if ( !VUI::EventManager.active ) return; 260 | #endif*/ 261 | 262 | VUI::GetCurrentView()->_SetIsMouseInside(true); 263 | 264 | ofMouseEventArgs args(ofMouseEventArgs::Entered, VUI::mouseX, VUI::mouseY); 265 | ofNotifyEvent(onMouseEntered, args, this); 266 | 267 | VUI::GetCurrentView()->mouseEntered(VUI::mouseX, VUI::mouseY); 268 | } 269 | } 270 | void ViewManagerBridge::mouseExited(ofMouseEventArgs & mouse) { 271 | //mouseExited(mouse.x, mouse.y); 272 | VUI::mouseX = mouse.x*multCoords.x; 273 | VUI::mouseY = mouse.y*multCoords.y; 274 | 275 | if (!VUI::currView.empty()) { 276 | /*#ifdef USING_ofxSupervui 277 | if ( !VUI::EventManager.active ) return; 278 | #endif*/ 279 | VUI::GetCurrentView()->_SetIsMouseInside(false); 280 | 281 | ofMouseEventArgs args(ofMouseEventArgs::Exited, VUI::mouseX, VUI::mouseY); 282 | ofNotifyEvent(onMouseExited, args, this); 283 | 284 | VUI::GetCurrentView()->mouseExited(VUI::mouseX, VUI::mouseY); 285 | } 286 | } 287 | void ViewManagerBridge::dragged(ofDragInfo & drag) { 288 | //dragEvent(drag); 289 | if (!VUI::currView.empty()) VUI::GetCurrentView()->dragEvent(drag); 290 | } 291 | void ViewManagerBridge::messageReceived(ofMessage & message) { 292 | //gotMessage(message); 293 | if (!VUI::currView.empty()) VUI::GetCurrentView()->gotMessage(message); 294 | } 295 | void ViewManagerBridge::touchDown(ofTouchEventArgs & touch) { 296 | //touchDown(touch.x, touch.y, touch.id); 297 | touches[touch.id].x = touch.x*multCoords.x; 298 | touches[touch.id].y = touch.y*multCoords.y; 299 | 300 | if (!VUI::GetCurrentEventManager()->active) return; 301 | 302 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchDown(touch.x*multCoords.x, touch.y*multCoords.y, touch.id); 303 | }; 304 | void ViewManagerBridge::touchMoved(ofTouchEventArgs & touch) { 305 | //touchMoved(touch.x, touch.y, touch.id); 306 | touches[touch.id].x = touch.x*multCoords.x; 307 | touches[touch.id].y = touch.y*multCoords.y; 308 | 309 | if (!VUI::GetCurrentEventManager()->active) return; 310 | 311 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchMoved(touch.x*multCoords.x, touch.y*multCoords.y, touch.id); 312 | }; 313 | void ViewManagerBridge::touchUp(ofTouchEventArgs & touch) { 314 | //touchUp(touch.x, touch.y, touch.id); 315 | map::iterator it; 316 | it = touches.find(touch.id); 317 | if (it != touches.end()) touches.erase(it); 318 | 319 | 320 | if (!VUI::GetCurrentEventManager()->active) { 321 | if (VUI::GetCurrentEventManager()->enableOnMouseUp) VUI::GetCurrentEventManager()->DelayEnable(50); 322 | return; 323 | } 324 | 325 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchUp(touch.x*multCoords.x, touch.y*multCoords.y, touch.id); 326 | }; 327 | void ViewManagerBridge::touchDoubleTap(ofTouchEventArgs & touch) { 328 | //touchDoubleTap(touch.x, touch.y, touch.id); 329 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchDoubleTap(touch.x*multCoords.x, touch.y*multCoords.y, touch.id); 330 | }; 331 | void ViewManagerBridge::touchCancelled(ofTouchEventArgs & touch) { 332 | //touchCancelled(touch.x, touch.y, touch.id); 333 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchCancelled(touch.x*multCoords.x, touch.y*multCoords.y, touch.id); 334 | } 335 | 336 | #ifdef USING_ofxTouchPadScroll 337 | void ViewManagerBridge::touchPadScroll(TouchPadScrollEventArgs& args){ 338 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchPadScroll(args.x, args.y, VUI_EVENT_TOUCHPAD_SCROLL ); 339 | VUI::GetCurrentEventManager()->touchPadScroll(args.x, args.y, VUI_EVENT_TOUCHPAD_SCROLL ); 340 | } 341 | 342 | void ViewManagerBridge::touchPadScrollStart(TouchPadScrollEventArgs& args){ 343 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchPadScroll(args.x, args.y, VUI_EVENT_TOUCHPAD_SCROLL_START ); 344 | VUI::GetCurrentEventManager()->touchPadScroll(args.x, args.y, VUI_EVENT_TOUCHPAD_SCROLL_START ); 345 | } 346 | 347 | void ViewManagerBridge::touchPadScrollEnd(TouchPadScrollEventArgs& args){ 348 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchPadScroll(args.x, args.y, VUI_EVENT_TOUCHPAD_SCROLL_END ); 349 | VUI::GetCurrentEventManager()->touchPadScroll(args.x, args.y, VUI_EVENT_TOUCHPAD_SCROLL_END ); 350 | } 351 | 352 | void ViewManagerBridge::touchPadScrollInertia(TouchPadScrollEventArgs& args){ 353 | if (!VUI::currView.empty()) VUI::GetCurrentView()->touchPadScroll(args.x, args.y, VUI_EVENT_TOUCHPAD_SCROLL_INERTIA ); 354 | VUI::GetCurrentEventManager()->touchPadScroll(args.x, args.y, VUI_EVENT_TOUCHPAD_SCROLL_INERTIA ); 355 | } 356 | #endif 357 | 358 | } 359 | 360 | 361 | 362 | namespace VUI { 363 | Rotate uiRotation = VUI_ROTATE_NONE; 364 | Rotate viewRotation = VUI_ROTATE_NONE; 365 | 366 | bool useViewManager = true; 367 | 368 | map>> fonts; 369 | vector loadedFontSettings; 370 | int fontSize = 16; 371 | 372 | bool useTouch = false; 373 | bool _didInit = false; 374 | 375 | int doubleClickThreshold = 400; 376 | int touchTapThreshold = 180; 377 | 378 | // Tween 379 | 380 | void Tween::Start( Element* el, float timeSeconds, string params ){ 381 | firstStep = true; 382 | active = true; 383 | this->el = el; 384 | el->StopTween(); 385 | el->StoreTween(this); 386 | duration = timeSeconds*1000; 387 | 388 | string s(params); 389 | ofStringReplace(s, "{", " "); 390 | ofStringReplace(s, "}", " "); 391 | ofStringReplace(s, " ", ""); 392 | 393 | cmd = s; 394 | 395 | vector split = ofSplitString(s, "," ); 396 | for ( vector::iterator it = split.begin(); it != split.end(); it++){ 397 | //ofLog() << (*it); 398 | 399 | vector propVal = ofSplitString( (*it), ":" ); 400 | if ( propVal.size() == 2 ){ 401 | //ofLog() << propVal[0] << " => " << propVal[1]; 402 | 403 | if ( propVal[0] == "rotation" || propVal[0] == "x" || propVal[0] == "y" || propVal[0] == "width" || propVal[0] == "height" || propVal[0] == "opacity" || propVal[0] == "scale" ){ 404 | if ( propVal[1].find("+=") != -1 ) { 405 | if ( propVal[0] == "x" ) propVal[1] = ofToString(el->GetPosition(true).x + ofToFloat( ofSplitString( propVal[1], "+=" )[1] )); 406 | else if ( propVal[0] == "y" ) propVal[1] = ofToString(el->GetPosition(true).y + ofToFloat( ofSplitString( propVal[1], "+=" )[1] )); 407 | else if ( propVal[0] == "opacity" ) propVal[1] = ofToString(el->GetOpacity() + ofToFloat( ofSplitString( propVal[1], "+=" )[1] )); 408 | else if ( propVal[0] == "width" ) propVal[1] = ofToString(el->GetWidth() + ofToFloat( ofSplitString( propVal[1], "+=" )[1] )); 409 | else if ( propVal[0] == "height" ) propVal[1] = ofToString(el->GetHeight() + ofToFloat( ofSplitString( propVal[1], "+=" )[1] )); 410 | else if ( propVal[0] == "scale" ) propVal[1] = ofToString(el->GetScale() + ofToFloat( ofSplitString( propVal[1], "+=" )[1] )); 411 | else if ( propVal[0] == "rotation" ) propVal[1] = ofToString(el->GetRotation() + ofToFloat( ofSplitString( propVal[1], "+=" )[1] )); 412 | } else if ( propVal[1].find("-=") != -1 ){ 413 | if ( propVal[0] == "x" ) propVal[1] = ofToString(el->GetPosition(true).x - ofToFloat( ofSplitString( propVal[1], "-=" )[1] )); 414 | else if ( propVal[0] == "y" ) propVal[1] = ofToString(el->GetPosition(true).y - ofToFloat( ofSplitString( propVal[1], "-=" )[1] )); 415 | else if ( propVal[0] == "opacity" ) propVal[1] = ofToString(el->GetOpacity() - ofToFloat( ofSplitString( propVal[1], "-=" )[1] )); 416 | else if ( propVal[0] == "width" ) propVal[1] = ofToString(el->GetWidth() - ofToFloat( ofSplitString( propVal[1], "-=" )[1] )); 417 | else if ( propVal[0] == "height" ) propVal[1] = ofToString(el->GetHeight() - ofToFloat( ofSplitString( propVal[1], "-=" )[1] )); 418 | else if ( propVal[0] == "scale" ) propVal[1] = ofToString(el->GetScale() - ofToFloat( ofSplitString( propVal[1], "-=" )[1] )); 419 | else if ( propVal[0] == "rotation" ) propVal[1] = ofToString(el->GetRotation() - ofToFloat( ofSplitString( propVal[1], "-=" )[1] )); 420 | } else if ( propVal[1].find("*=") != -1 ){ 421 | if ( propVal[0] == "x" ) propVal[1] = ofToString(el->GetPosition(true).x * ofToFloat( ofSplitString( propVal[1], "*=" )[1] )); 422 | else if ( propVal[0] == "y" ) propVal[1] = ofToString(el->GetPosition(true).y * ofToFloat( ofSplitString( propVal[1], "*=" )[1] )); 423 | else if ( propVal[0] == "opacity" ) propVal[1] = ofToString(el->GetOpacity() * ofToFloat( ofSplitString( propVal[1], "*=" )[1] )); 424 | else if ( propVal[0] == "width" ) propVal[1] = ofToString(el->GetWidth() * ofToFloat( ofSplitString( propVal[1], "*=" )[1] )); 425 | else if ( propVal[0] == "height" ) propVal[1] = ofToString(el->GetHeight() * ofToFloat( ofSplitString( propVal[1], "*=" )[1] )); 426 | else if ( propVal[0] == "scale" ) propVal[1] = ofToString(el->GetScale() * ofToFloat( ofSplitString( propVal[1], "*=" )[1] )); 427 | else if ( propVal[0] == "rotation" ) propVal[1] = ofToString(el->GetRotation() * ofToFloat( ofSplitString( propVal[1], "*=" )[1] )); 428 | } else if ( propVal[1].find("%") != -1 && el->HasParent() ){ 429 | if ( propVal[0] == "width" ) propVal[1] = ofToString(el->GetParent()->GetInnerWidth()*VUI::divideDpi * ofToFloat( ofSplitString( propVal[1], "*=" )[0] )*.01 ); 430 | else if ( propVal[0] == "height" ) propVal[1] = ofToString(el->GetParent()->GetInnerHeight()*VUI::divideDpi * ofToFloat( ofSplitString( propVal[1], "*=" )[0] )*.01 ); 431 | } 432 | 433 | StoreValue( propVal[0], propVal[1] ); 434 | } else if ( propVal[0] == "delay" ){ 435 | delay = ofToFloat( propVal[1] ); 436 | } else if ( propVal[0] == "easing" || propVal[0] == "ease" ){ 437 | string e = ofToLower(propVal[1]); 438 | 439 | if ( e == "back.easein" ) ease = ofxeasing::back::easeIn; 440 | else if ( e == "back.easeout" ) ease = ofxeasing::back::easeOut; 441 | else if ( e == "back.easeinout" ) ease = ofxeasing::back::easeInOut; 442 | else if ( e == "bounce.easein" ) ease = ofxeasing::bounce::easeIn; 443 | else if ( e == "bounce.easeout" ) ease = ofxeasing::bounce::easeOut; 444 | else if ( e == "bounce.easeinout" ) ease = ofxeasing::bounce::easeInOut; 445 | else if ( e == "circ.easein" ) ease = ofxeasing::circ::easeIn; 446 | else if ( e == "circ.easeout" ) ease = ofxeasing::circ::easeOut; 447 | else if ( e == "circ.easeinout" ) ease = ofxeasing::circ::easeInOut; 448 | else if ( e == "cubic.easein" ) ease = ofxeasing::cubic::easeIn; 449 | else if ( e == "cubic.easeout" ) ease = ofxeasing::cubic::easeOut; 450 | else if ( e == "cubic.easeinout" ) ease = ofxeasing::cubic::easeInOut; 451 | else if ( e == "elastic.easein" ) ease = ofxeasing::elastic::easeIn; 452 | else if ( e == "elastic.easeout" ) ease = ofxeasing::elastic::easeOut; 453 | else if ( e == "elastic.easeinout" ) ease = ofxeasing::elastic::easeInOut; 454 | else if ( e == "exp.easein" ) ease = ofxeasing::exp::easeIn; 455 | else if ( e == "exp.easeout" ) ease = ofxeasing::exp::easeOut; 456 | else if ( e == "exp.easeinout" ) ease = ofxeasing::exp::easeInOut; 457 | else if ( e == "linear.easein" ) ease = ofxeasing::linear::easeIn; 458 | else if ( e == "linear.easeout" ) ease = ofxeasing::linear::easeOut; 459 | else if ( e == "linear.easeinout" ) ease = ofxeasing::linear::easeInOut; 460 | else if ( e == "linear.easenone" ) ease = ofxeasing::linear::easeNone; 461 | else if ( e == "quad.easein" ) ease = ofxeasing::quad::easeIn; 462 | else if ( e == "quad.easeout" ) ease = ofxeasing::quad::easeOut; 463 | else if ( e == "quad.easeinout" ) ease = ofxeasing::quad::easeInOut; 464 | 465 | } 466 | else if (propVal[0] == "id") { 467 | id = propVal[1]; 468 | } 469 | 470 | } 471 | } 472 | 473 | 474 | startTime = ofGetElapsedTimeMillis() + (delay*1000); 475 | endTime = startTime + duration; 476 | } 477 | 478 | void Tween::StoreStartValues(){ 479 | for ( vector::iterator it = valueNames.begin(); it != valueNames.end(); it++ ){ 480 | if ( (*it) == "x" ){ 481 | startValues[ (*it) ] = el->GetPosition(true).x; 482 | } else if ( (*it) == "y" ){ 483 | startValues[ (*it) ] = el->GetPosition(true).y; 484 | //ofLog() << "sy:" << startValues[ (*it) ]; 485 | } else if ( (*it) == "width" ){ 486 | //ofLog() << "width:" << el->GetWidth(); 487 | startValues[ (*it) ] = el->GetWidth(false)*VUI::divideDpi; 488 | } else if ( (*it) == "height" ){ 489 | //ofLog() << "height:" << el->GetHeight(); 490 | startValues[ (*it) ] = el->GetHeight(false)*VUI::divideDpi; 491 | } else if ( (*it) == "rotation" ){ 492 | startValues[ (*it) ] = el->GetRotation(); 493 | } else if ( (*it) == "opacity" ){ 494 | startValues[ (*it) ] = el->GetOpacity(); 495 | } else if ( (*it) == "scale" ){ 496 | //ofLog() << "scale:" << el->GetScale(); 497 | startValues[ (*it) ] = el->GetScale(); 498 | } 499 | } 500 | } 501 | 502 | void Tween::StoreValue( string param, string val ){ 503 | endValues[ param ] = ofToFloat( val ); 504 | valueNames.push_back( param ); 505 | } 506 | 507 | void Tween::StoreValue( string param, float val ){ 508 | endValues[ param ] = val; 509 | valueNames.push_back( param ); 510 | } 511 | 512 | void Tween::Stop(){ 513 | active = false; 514 | } 515 | 516 | 517 | void Tween::Update(float currTime){ 518 | if ( !active || el == NULL ) return; 519 | 520 | if ( currTime >= startTime && currTime < endTime ){ 521 | 522 | 523 | if ( firstStep ){ 524 | firstStep = false; 525 | StoreStartValues(); 526 | 527 | vuiEventArgs args; 528 | args.element = el; 529 | args.tween = this; 530 | args.eventType = VUI_EVENT_ANIMATE_START; 531 | 532 | ofNotifyEvent( onStart, args, this ); 533 | 534 | //ofLog() << cmd; 535 | } 536 | 537 | perc = (currTime - startTime) / duration; 538 | UpdateValues(); 539 | 540 | vuiEventArgs args; 541 | args.element = el; 542 | args.tween = this; 543 | args.eventType = VUI_EVENT_ANIMATE_STEP; 544 | 545 | ofNotifyEvent( onStep, args, this ); 546 | } else if ( currTime >= endTime ) { 547 | active = false; 548 | 549 | perc = 1; 550 | UpdateValues(); 551 | 552 | vuiEventArgs args2; 553 | args2.element = el; 554 | args2.tween = this; 555 | args2.eventType = VUI_EVENT_ANIMATE_STEP; 556 | 557 | ofNotifyEvent( onStep, args2, this ); 558 | 559 | 560 | vuiEventArgs args; 561 | args.element = el; 562 | args.tween = this; 563 | args.eventType = VUI_EVENT_ANIMATE_COMPLETE; 564 | 565 | ofNotifyEvent( onComplete, args, this ); 566 | 567 | VUI::ShouldDestroyTween(this); 568 | } 569 | } 570 | 571 | void Tween::UpdateValues(){ 572 | if ( valueNames.size() == 0 ) return; 573 | for ( vector::iterator it = valueNames.begin(); it != valueNames.end(); it++ ){ 574 | if ( (*it) == "x" ){ 575 | //x = el->GetPosition().x; 576 | x = ofxeasing::map(perc, 0.0, 1.0, startValues[(*it)], endValues[(*it)], ease); 577 | el->SetPositionX( x ); 578 | } else if ( (*it) == "y" ){ 579 | y = ofxeasing::map(perc, 0.0, 1.0, startValues[(*it)], endValues[(*it)], ease); 580 | el->SetPositionY( y ); 581 | } else if ( (*it) == "width" ){ 582 | width = ofxeasing::map(perc, 0.0, 1.0, startValues[(*it)], endValues[(*it)], ease); 583 | el->SetWidth( width ); 584 | } else if ( (*it) == "height" ){ 585 | height = ofxeasing::map(perc, 0.0, 1.0, startValues[(*it)], endValues[(*it)], ease); 586 | el->SetHeight( height ); 587 | } else if ( (*it) == "rotation" ){ 588 | rotation = ofxeasing::map(perc, 0.0, 1.0, startValues[(*it)], endValues[(*it)], ease); 589 | el->SetRotation( rotation ); 590 | } else if ( (*it) == "opacity" ){ 591 | opacity = ofxeasing::map(perc, 0.0, 1.0, startValues[(*it)], endValues[(*it)], ease); 592 | //if ( el->GetName() == "#ShaveOver" ) ofLog() << opacity; 593 | 594 | el->SetOpacity( ofClamp(opacity, 0, 1) ); 595 | 596 | } else if ( (*it) == "scale" ){ 597 | scale = ofxeasing::map(perc, 0.0, 1.0, startValues[(*it)], endValues[(*it)], ease); 598 | el->SetScale( scale ); 599 | } 600 | } 601 | 602 | } 603 | 604 | 605 | // EventManager 606 | EM EventManager; 607 | EM* currEventManager = NULL; 608 | 609 | vector tweensToDestroy = vector(); 610 | vector tweens = vector(); 611 | 612 | void EM::StoreEvent(Element* el, vuiEvent eventType ){ 613 | //ofLog() << "StoreEvent[" << eventType << "] active:" << active; 614 | if ( !active ) return; 615 | 616 | this->events[ eventType ].push_back( el ); 617 | } 618 | 619 | void EM::StoreOverElement( Element *el){ 620 | overElement = el; 621 | } 622 | 623 | void EM::StoreState( Element *el, State state ){ 624 | if ( !active ) return; 625 | this->states[ state ].push_back( el ); 626 | } 627 | 628 | #ifdef USING_ofxTouchPadScroll 629 | void EM::touchPadScroll(int x, int y, vuiEvent eventType){ 630 | if (!active) return; 631 | 632 | #ifdef USING_ofxWindowManager 633 | if ( this->window != NULL ){ 634 | if ( !this->window->isMouseInside() ) return; 635 | } 636 | #endif 637 | 638 | //ofLog() << "EM::touchPadScroll " << x << "," << y; 639 | if ( prevOverElement != nullptr ) { 640 | vuiEventArgs args = prevOverElement->GetEventArgs(eventType); 641 | args.touchPadScroll.set(x,y); 642 | ofNotifyEvent(prevOverElement->onTouchPadScroll, args, prevOverElement); 643 | } 644 | 645 | vuiEventArgs args2; 646 | args2.eventType = eventType; 647 | args2.touchPadScroll.set(x,y); 648 | ofNotifyEvent(onTouchPadScroll, args2, this); 649 | } 650 | #endif 651 | 652 | void EM::Purge(){ 653 | if ( !active ) return; 654 | 655 | for( vector::iterator it = VUI::evtlist.begin(); it != VUI::evtlist.end(); it++ ){ 656 | this->events[ (*it) ].clear(); 657 | } 658 | 659 | for( vector::iterator it = statelist.begin(); it != statelist.end(); it++ ){ 660 | this->states[ (*it) ].clear(); 661 | } 662 | 663 | VUI::ClearOverElement(); 664 | 665 | //if ( EventManager.overElement != nullptr ) ofLog() << EventManager.overElement->vuiUID; 666 | } 667 | 668 | void EM::Disable() { 669 | //ofLog() << "EventManager::Disable" << endl; 670 | active = false; 671 | 672 | Purge(); 673 | if (ofGetMousePressed()|| VUI::GetTouchDown()) enableOnMouseUp = true; 674 | }; 675 | 676 | void EM::Enable(){ 677 | //ofLog() << "EventManager::Enable" << endl; 678 | active = true; 679 | enableOnMouseUp = false; 680 | shouldEnable = -1; 681 | } 682 | 683 | TM TweenManager; 684 | 685 | void TM::Init(){ 686 | ofAddListener(ofEvents().update, this, &TM::update); 687 | } 688 | 689 | void TM::update(ofEventArgs& args){ 690 | float currTime = ofGetElapsedTimeMillis(); 691 | 692 | //ofLog() << "# tweens: " << tweens.size(); 693 | 694 | int max = tweens.size(); 695 | int i = 0; 696 | for (vector::iterator it = tweens.begin(); it != tweens.end(); it++){ 697 | //if ( i >= 0 && i < max && (*it) != NULL && (*it) != nullptr && (*it)->el != NULL ) (*it)->Update( currTime ); 698 | //else return; 699 | if ( i >= 0 && i < max ) { 700 | if ( (*it) != NULL && (*it)->active && !isnan((*it)->duration) && (*it)->duration != 0.0 ) (*it)->Update( currTime ); 701 | } else { 702 | return; 703 | } 704 | //(*it)->Update( currTime ); 705 | i++; 706 | } 707 | 708 | for (vector::iterator it = tweensToDestroy.begin(); it != tweensToDestroy.end(); it++){ 709 | VUI::DestroyTween( (*it) ); 710 | } 711 | 712 | tweensToDestroy.clear(); 713 | } 714 | 715 | void EM::Init(int windowW, int windowH){ 716 | ofAddListener(ofEvents().update, this, &EM::update); 717 | vw = windowW; 718 | vh = windowH; 719 | VUI::PRIVATE.Listen(); 720 | #ifdef USING_ofxTouchPadScroll 721 | tps.init(); 722 | #endif 723 | } 724 | 725 | #ifdef USING_ofxWindowManager 726 | void EM::Init(ofxAppBaseNewWindow* window){ 727 | this->window = window; 728 | Init(window->getWindowWidth(), window->getWindowHeight()); 729 | } 730 | #endif 731 | 732 | void ClearOverElement() { 733 | GetCurrentEventManager()->prevOverElement = GetCurrentEventManager()->overElement; 734 | GetCurrentEventManager()->overElement = NULL; 735 | //GetCurrentEventManager()->overElement = nullptr; 736 | //if ( GetCurrentEventManager()->prevOverElement != nullptr ) ofLog() << GetCurrentEventManager()->overElement->GetName(); 737 | } 738 | 739 | void EM::update(ofEventArgs & args){ 740 | 741 | if ( shouldEnable != -1 ) { 742 | if ( ofGetElapsedTimeMillis() > shouldEnable ) Enable(); 743 | } 744 | 745 | if ( !active ) { 746 | Purge(); 747 | return; 748 | } 749 | 750 | #ifdef USING_ofxWindowManager 751 | if ( this->window != NULL ){ 752 | if ( !this->window->isMouseInside() ) { 753 | Purge(); 754 | return; 755 | } 756 | } 757 | #endif 758 | 759 | //ofLog() << "EMBridge::Update - " << ofRandomf(); 760 | //if ( EventHasElement(VUI_EVENT_MOUSE_CLICK) ) ofLog() << GetLatestElement(VUI_EVENT_MOUSE_CLICK)->GetName(); 761 | for( vector::iterator it = evtlist.begin(); it != evtlist.end(); it++ ){ 762 | if ( (*it) != VUI_EVENT_MOUSE_EXIT && (*it) != VUI_EVENT_MOUSE_ENTER ) if ( EventHasElement((*it)) ) { 763 | //if ( GetLatestElement((*it))->GetName()[0] != '.' && GetLatestElement((*it))->GetName()[0] != '#' ) continue; 764 | GetLatestElement((*it))->TriggerEvent((*it)); 765 | } 766 | } 767 | 768 | for ( vector::iterator it = this->events[VUI_EVENT_MOUSE_ENTER].begin(); it != this->events[VUI_EVENT_MOUSE_ENTER].end(); it++ ){ 769 | //if ( (*it)->GetName()[0] != '.' && (*it)->GetName()[0] != '#' ) continue; 770 | (*it)->TriggerEvent(VUI_EVENT_MOUSE_ENTER); 771 | } 772 | 773 | for ( vector::iterator it = this->events[VUI_EVENT_MOUSE_EXIT].begin(); it != this->events[VUI_EVENT_MOUSE_EXIT].end(); it++ ){ 774 | //if ( (*it)->GetName()[0] != '.' && (*it)->GetName()[0] != '#' ) continue; 775 | (*it)->TriggerEvent(VUI_EVENT_MOUSE_EXIT); 776 | } 777 | 778 | 779 | 780 | for( vector::iterator it = statelist.begin(); it != statelist.end(); it++ ){ 781 | Element* last = nullptr; 782 | for ( vector::iterator eit = states[(*it)].begin(); eit != states[(*it)].end(); eit++){ 783 | //if ( (*eit) == EventManager.overElement ) (*eit)->SetState( (*it) ); 784 | if ( (*eit) == overElement ) (*eit)->SetState( (*it) ); 785 | //ofLog() << "[" << (*it) << "]" << (*eit)->GetName(); 786 | } 787 | 788 | } 789 | 790 | //if ( EventManager.overElement != nullptr ) EventManager.overElement->SetState( VUI_STATE_OVER ); 791 | 792 | Purge(); 793 | 794 | } 795 | 796 | } 797 | --------------------------------------------------------------------------------