The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1428 lines
50KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-7 by Raw Material Software ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the
  7. GNU General Public License, as published by the Free Software Foundation;
  8. either version 2 of the License, or (at your option) any later version.
  9. JUCE is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with JUCE; if not, visit www.gnu.org/licenses or write to the
  15. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. Boston, MA 02111-1307 USA
  17. ------------------------------------------------------------------------------
  18. If you'd like to release a closed-source product which uses JUCE, commercial
  19. licenses are also available: visit www.rawmaterialsoftware.com/juce for
  20. more information.
  21. ==============================================================================
  22. */
  23. #include "../jucedemo_headers.h"
  24. //==============================================================================
  25. class BouncingBallComponent : public Component,
  26. public Timer
  27. {
  28. Colour colour;
  29. float x, y, dx, dy;
  30. public:
  31. BouncingBallComponent()
  32. {
  33. x = Random::getSystemRandom().nextFloat() * 100.0f;
  34. y = Random::getSystemRandom().nextFloat() * 100.0f;
  35. dx = Random::getSystemRandom().nextFloat() * 8.0f - 4.0f;
  36. dy = Random::getSystemRandom().nextFloat() * 8.0f - 4.0f;
  37. colour = Colour (Random::getSystemRandom().nextInt())
  38. .withAlpha (0.5f)
  39. .withBrightness (0.7f);
  40. int size = 10 + Random::getSystemRandom().nextInt (30);
  41. setSize (size, size);
  42. startTimer (60);
  43. }
  44. ~BouncingBallComponent()
  45. {
  46. }
  47. void paint (Graphics& g)
  48. {
  49. g.setColour (colour);
  50. g.fillEllipse (x - getX(), y - getY(), getWidth() - 2.0f, getHeight() - 2.0f);
  51. }
  52. void timerCallback()
  53. {
  54. x += dx;
  55. y += dy;
  56. if (x < 0)
  57. dx = fabsf (dx);
  58. if (x > getParentWidth())
  59. dx = -fabsf (dx);
  60. if (y < 0)
  61. dy = fabsf (dy);
  62. if (y > getParentHeight())
  63. dy = -fabsf (dy);
  64. setTopLeftPosition ((int) x, (int) y);
  65. }
  66. bool hitTest (int x, int y)
  67. {
  68. return false;
  69. }
  70. };
  71. //==============================================================================
  72. class DragOntoDesktopDemoComp : public Component
  73. {
  74. Component* parent;
  75. ComponentDragger dragger;
  76. public:
  77. DragOntoDesktopDemoComp (Component* p)
  78. : parent (p)
  79. {
  80. // show off semi-transparency if it's supported by the current OS.
  81. setOpaque (! Desktop::canUseSemiTransparentWindows());
  82. for (int i = 3; --i >= 0;)
  83. addAndMakeVisible (new BouncingBallComponent());
  84. }
  85. ~DragOntoDesktopDemoComp()
  86. {
  87. deleteAllChildren();
  88. }
  89. void mouseDown (const MouseEvent& e)
  90. {
  91. dragger.startDraggingComponent (this, 0);
  92. }
  93. void mouseDrag (const MouseEvent& e)
  94. {
  95. if (! parent->isValidComponent())
  96. {
  97. delete this;
  98. }
  99. else
  100. {
  101. MouseEvent e2 (e.getEventRelativeTo (parent));
  102. // if the mouse is inside the parent component, we'll make that the
  103. // parent - otherwise, we'll put this comp on the desktop.
  104. if (e2.x >= 0 && e2.y >= 0 && e2.x < parent->getWidth() && e2.y < parent->getHeight())
  105. {
  106. // re-add this component to a parent component, which will
  107. // remove it from the desktop..
  108. parent->addChildComponent (this);
  109. }
  110. else
  111. {
  112. // add the component to the desktop, which will remove it
  113. // from its current parent component..
  114. addToDesktop (ComponentPeer::windowIsTemporary);
  115. }
  116. dragger.dragComponent (this, e);
  117. }
  118. }
  119. void paint (Graphics& g)
  120. {
  121. if (isOpaque())
  122. g.fillAll (Colours::white);
  123. else
  124. g.fillAll (Colours::blue.withAlpha (0.2f));
  125. String desc (T("drag this box onto the desktop to show how the same component can move from being lightweight to being a separate window"));
  126. g.setFont (15.0f);
  127. g.setColour (Colours::black);
  128. g.drawFittedText (desc, 4, 0, getWidth() - 8, getHeight(), Justification::horizontallyJustified, 5);
  129. g.drawRect (0, 0, getWidth(), getHeight());
  130. }
  131. };
  132. //==============================================================================
  133. class CustomMenuComponent : public PopupMenuCustomComponent,
  134. public Timer
  135. {
  136. int blobX, blobY;
  137. public:
  138. CustomMenuComponent()
  139. : blobX (0),
  140. blobY (0)
  141. {
  142. // set off a timer to move a blob around on this component every
  143. // 300 milliseconds - see the timerCallback() method.
  144. startTimer (300);
  145. }
  146. ~CustomMenuComponent()
  147. {
  148. }
  149. void getIdealSize (int& idealWidth,
  150. int& idealHeight)
  151. {
  152. // tells the menu how big we'd like to be..
  153. idealWidth = 200;
  154. idealHeight = 60;
  155. }
  156. void paint (Graphics& g)
  157. {
  158. g.fillAll (Colours::yellow.withAlpha (0.3f));
  159. g.setColour (Colours::pink);
  160. g.fillEllipse ((float) blobX, (float) blobY, 30.0f, 40.0f);
  161. g.setFont (14.0f, Font::italic);
  162. g.setColour (Colours::black);
  163. g.drawFittedText (T("this is a customised menu item (also demonstrating the Timer class)..."),
  164. 4, 0, getWidth() - 8, getHeight(),
  165. Justification::centred, 3);
  166. }
  167. void timerCallback()
  168. {
  169. blobX = Random::getSystemRandom().nextInt (getWidth());
  170. blobY = Random::getSystemRandom().nextInt (getHeight());
  171. repaint();
  172. }
  173. };
  174. //==============================================================================
  175. /** To demonstrate how sliders can have custom snapping applied to their values,
  176. this simple class snaps the value to 50 if it comes near.
  177. */
  178. class SnappingSlider : public Slider
  179. {
  180. public:
  181. SnappingSlider (const String& name)
  182. : Slider (name)
  183. {
  184. }
  185. double snapValue (double attemptedValue, const bool userIsDragging)
  186. {
  187. if (! userIsDragging)
  188. return attemptedValue; // if they're entering the value in the text-box, don't mess with it.
  189. if (attemptedValue > 40 && attemptedValue < 60)
  190. return 50.0;
  191. else
  192. return attemptedValue;
  193. }
  194. };
  195. /** A TextButton that pops up a colour chooser to change its colours. */
  196. class ColourChangeButton : public TextButton,
  197. public ChangeListener
  198. {
  199. public:
  200. ColourChangeButton()
  201. : TextButton (T("click to change colour..."))
  202. {
  203. setSize (10, 24);
  204. changeWidthToFitText();
  205. }
  206. ~ColourChangeButton()
  207. {
  208. }
  209. void clicked()
  210. {
  211. // create two colour selector components for our background and
  212. // text colour..
  213. ColourSelector colourSelector1;
  214. colourSelector1.setName (T("background"));
  215. colourSelector1.setCurrentColour (findColour (TextButton::buttonColourId));
  216. colourSelector1.addChangeListener (this);
  217. ColourSelector colourSelector2;
  218. colourSelector2.setName (T("text"));
  219. colourSelector2.setCurrentColour (findColour (TextButton::textColourId));
  220. colourSelector2.addChangeListener (this);
  221. // and add the selectors as custom menu items to a PopupMenu, putting
  222. // them in two different sub-menus..
  223. PopupMenu m, sub1, sub2;
  224. sub1.addCustomItem (1234, &colourSelector1, 300, 300, false);
  225. m.addSubMenu (T("background colour"), sub1);
  226. sub2.addCustomItem (1234, &colourSelector2, 300, 300, false);
  227. m.addSubMenu (T("text colour"), sub2);
  228. // and show the menu (modally)..
  229. m.showAt (this);
  230. }
  231. void changeListenerCallback (void* source)
  232. {
  233. ColourSelector* cs = (ColourSelector*) source;
  234. if (cs->getName() == T("text"))
  235. setColour (TextButton::textColourId, cs->getCurrentColour());
  236. else
  237. setColour (TextButton::buttonColourId, cs->getCurrentColour());
  238. }
  239. };
  240. //==============================================================================
  241. // just a component that deletes all its children, to use for the tabbed pages to avoid
  242. // memory leaks when they're deleted
  243. class DemoPageComp : public Component
  244. {
  245. public:
  246. DemoPageComp()
  247. {
  248. }
  249. ~DemoPageComp()
  250. {
  251. deleteAllChildren();
  252. }
  253. };
  254. //==============================================================================
  255. static Component* createSlidersPage()
  256. {
  257. DemoPageComp* page = new DemoPageComp();
  258. const int numSliders = 11;
  259. Slider* sliders [numSliders];
  260. int i;
  261. for (i = 0; i < numSliders; ++i)
  262. {
  263. if (i == 2)
  264. page->addAndMakeVisible (sliders[i] = new SnappingSlider (T("slider")));
  265. else
  266. page->addAndMakeVisible (sliders[i] = new Slider (T("slider")));
  267. sliders[i]->setRange (0.0, 100.0, 0.1);
  268. sliders[i]->setPopupMenuEnabled (true);
  269. sliders[i]->setValue (Random::getSystemRandom().nextDouble() * 100.0, false, false);
  270. }
  271. sliders[0]->setSliderStyle (Slider::LinearVertical);
  272. sliders[0]->setTextBoxStyle (Slider::TextBoxBelow, false, 100, 20);
  273. sliders[0]->setBounds (10, 25, 70, 200);
  274. sliders[0]->setDoubleClickReturnValue (true, 50.0); // double-clicking this slider will set it to 50.0
  275. sliders[0]->setTextValueSuffix (T(" units"));
  276. sliders[1]->setSliderStyle (Slider::LinearVertical);
  277. sliders[1]->setVelocityBasedMode (true);
  278. sliders[1]->setSkewFactor (0.5);
  279. sliders[1]->setTextBoxStyle (Slider::TextBoxAbove, true, 100, 20);
  280. sliders[1]->setBounds (85, 25, 70, 200);
  281. sliders[1]->setTextValueSuffix (T(" rels"));
  282. sliders[2]->setSliderStyle (Slider::LinearHorizontal);
  283. sliders[2]->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
  284. sliders[2]->setBounds (180, 35, 150, 20);
  285. sliders[3]->setSliderStyle (Slider::LinearHorizontal);
  286. sliders[3]->setTextBoxStyle (Slider::NoTextBox, false, 0, 0);
  287. sliders[3]->setBounds (180, 65, 150, 20);
  288. sliders[3]->setPopupDisplayEnabled (true, page);
  289. sliders[3]->setTextValueSuffix (T(" nuns required to change a lightbulb"));
  290. sliders[4]->setSliderStyle (Slider::IncDecButtons);
  291. sliders[4]->setTextBoxStyle (Slider::TextBoxLeft, false, 50, 20);
  292. sliders[4]->setBounds (180, 105, 100, 20);
  293. sliders[4]->setIncDecButtonsMode (Slider::incDecButtonsDraggable_Vertical);
  294. sliders[5]->setSliderStyle (Slider::Rotary);
  295. sliders[5]->setRotaryParameters (float_Pi * 1.2f, float_Pi * 2.8f, false);
  296. sliders[5]->setTextBoxStyle (Slider::TextBoxRight, false, 70, 20);
  297. sliders[5]->setBounds (190, 145, 120, 40);
  298. sliders[5]->setTextValueSuffix (T(" mm"));
  299. sliders[6]->setSliderStyle (Slider::LinearBar);
  300. sliders[6]->setBounds (180, 195, 100, 30);
  301. sliders[6]->setTextValueSuffix (T(" gallons"));
  302. sliders[7]->setSliderStyle (Slider::TwoValueHorizontal);
  303. sliders[7]->setBounds (360, 20, 160, 40);
  304. sliders[8]->setSliderStyle (Slider::TwoValueVertical);
  305. sliders[8]->setBounds (360, 110, 40, 160);
  306. sliders[9]->setSliderStyle (Slider::ThreeValueHorizontal);
  307. sliders[9]->setBounds (360, 70, 160, 40);
  308. sliders[10]->setSliderStyle (Slider::ThreeValueVertical);
  309. sliders[10]->setBounds (440, 110, 40, 160);
  310. for (i = 7; i <= 10; ++i)
  311. {
  312. sliders[i]->setTextBoxStyle (Slider::NoTextBox, false, 0, 0);
  313. sliders[i]->setMinValue (Random::getSystemRandom().nextDouble() * 100.0, false, false);
  314. sliders[i]->setMaxValue (Random::getSystemRandom().nextDouble() * 100.0, false, false);
  315. sliders[i]->setPopupDisplayEnabled (true, page);
  316. }
  317. Label* label = new Label (T("hint"), T("Try right-clicking on a slider for an options menu. \n\nAlso, holding down CTRL while dragging will turn on a slider's velocity-sensitive mode"));
  318. label->setBounds (20, 245, 350, 150);
  319. page->addAndMakeVisible (label);
  320. return page;
  321. }
  322. //==============================================================================
  323. static Component* createRadioButtonPage()
  324. {
  325. DemoPageComp* page = new DemoPageComp();
  326. GroupComponent* group = new GroupComponent (T("group"), T("radio buttons"));
  327. group->setBounds (20, 20, 220, 140);
  328. page->addAndMakeVisible (group);
  329. int i;
  330. for (i = 0; i < 4; ++i)
  331. {
  332. ToggleButton* tb = new ToggleButton (T("radio button #") + String (i + 1));
  333. page->addAndMakeVisible (tb);
  334. tb->setRadioGroupId (1234);
  335. tb->setBounds (45, 46 + i * 22, 180, 22);
  336. tb->setTooltip (T("a set of mutually-exclusive radio buttons"));
  337. if (i == 0)
  338. tb->setToggleState (true, false);
  339. }
  340. for (i = 0; i < 4; ++i)
  341. {
  342. DrawablePath normal, over;
  343. Path p;
  344. p.addStar (0.0f, 0.0f, i + 5, 20.0f, 50.0f, -0.2f);
  345. normal.setPath (p);
  346. normal.setSolidFill (Colours::lightblue);
  347. normal.setOutline (4.0f, Colours::black);
  348. over.setPath (p);
  349. over.setSolidFill (Colours::blue);
  350. over.setOutline (4.0f, Colours::black);
  351. DrawableButton* db = new DrawableButton (String (i + 5) + T(" points"), DrawableButton::ImageAboveTextLabel);
  352. db->setImages (&normal, &over, 0);
  353. page->addAndMakeVisible (db);
  354. db->setClickingTogglesState (true);
  355. db->setRadioGroupId (23456);
  356. const int buttonSize = 50;
  357. db->setBounds (25 + i * buttonSize, 180, buttonSize, buttonSize);
  358. if (i == 0)
  359. db->setToggleState (true, false);
  360. }
  361. for (i = 0; i < 4; ++i)
  362. {
  363. TextButton* tb = new TextButton (T("button ") + String (i + 1));
  364. page->addAndMakeVisible (tb);
  365. tb->setClickingTogglesState (true);
  366. tb->setRadioGroupId (34567);
  367. tb->setColour (TextButton::buttonColourId, Colours::white);
  368. tb->setColour (TextButton::buttonOnColourId, Colours::blueviolet.brighter());
  369. tb->setBounds (20 + i * 55, 260, 55, 24);
  370. tb->setConnectedEdges (((i != 0) ? Button::ConnectedOnLeft : 0)
  371. | ((i != 3) ? Button::ConnectedOnRight : 0));
  372. if (i == 0)
  373. tb->setToggleState (true, false);
  374. }
  375. return page;
  376. }
  377. //==============================================================================
  378. class ButtonsPage : public Component,
  379. public ButtonListener
  380. {
  381. public:
  382. ButtonsPage (ButtonListener* buttonListener)
  383. {
  384. //==============================================================================
  385. // create some drawables to use for our drawable buttons...
  386. DrawablePath normal, over;
  387. Path p;
  388. p.addStar (0.0f, 0.0f, 5, 20.0f, 50.0f, 0.2f);
  389. normal.setPath (p);
  390. normal.setSolidFill (Colours::red);
  391. p.clear();
  392. p.addStar (0.0f, 0.0f, 7, 30.0f, 50.0f, 0.0f);
  393. over.setPath (p);
  394. over.setSolidFill (Colours::pink);
  395. over.setOutline (5.0f, Colours::black);
  396. DrawableImage down;
  397. down.setImage (ImageCache::getFromMemory (BinaryData::juce_png, BinaryData::juce_pngSize), true);
  398. down.setOverlayColour (Colours::black.withAlpha (0.3f));
  399. //==============================================================================
  400. // create an image-above-text button from these drawables..
  401. DrawableButton* db = new DrawableButton (T("Button 1"), DrawableButton::ImageAboveTextLabel);
  402. db->setImages (&normal, &over, &down);
  403. addAndMakeVisible (db);
  404. db->setBounds (10, 30, 80, 80);
  405. db->setTooltip (T("this is a DrawableButton with a label"));
  406. //==============================================================================
  407. // create an image-only button from these drawables..
  408. db = new DrawableButton (T("Button 2"), DrawableButton::ImageFitted);
  409. db->setImages (&normal, &over, &down);
  410. db->setClickingTogglesState (true);
  411. addAndMakeVisible (db);
  412. db->setBounds (90, 30, 80, 80);
  413. db->setTooltip (T("this is an image-only DrawableButton"));
  414. db->addButtonListener (buttonListener);
  415. //==============================================================================
  416. // create an image-on-button-shape button from the same drawables..
  417. db = new DrawableButton (T("Button 3"), DrawableButton::ImageOnButtonBackground);
  418. db->setImages (&normal, 0, 0);
  419. addAndMakeVisible (db);
  420. db->setBounds (200, 30, 110, 25);
  421. db->setTooltip (T("this is a DrawableButton on a standard button background"));
  422. //==============================================================================
  423. db = new DrawableButton (T("Button 4"), DrawableButton::ImageOnButtonBackground);
  424. db->setImages (&normal, &over, &down);
  425. db->setClickingTogglesState (true);
  426. db->setBackgroundColours (Colours::white, Colours::yellow);
  427. addAndMakeVisible (db);
  428. db->setBounds (200, 70, 50, 50);
  429. db->setTooltip (T("this is a DrawableButton on a standard button background"));
  430. db->addButtonListener (buttonListener);
  431. //==============================================================================
  432. HyperlinkButton* hyperlink
  433. = new HyperlinkButton (T("this is a HyperlinkButton"),
  434. URL (T("http://www.rawmaterialsoftware.com/juce")));
  435. hyperlink->setBounds (10, 130, 200, 24);
  436. addAndMakeVisible (hyperlink);
  437. //==============================================================================
  438. ImageButton* imageButton = new ImageButton (T("imagebutton"));
  439. addAndMakeVisible (imageButton);
  440. Image* juceImage = ImageCache::getFromMemory (BinaryData::juce_png, BinaryData::juce_pngSize);
  441. ImageCache::incReferenceCount (juceImage);
  442. ImageCache::incReferenceCount (juceImage);
  443. imageButton->setImages (true, true, true,
  444. juceImage, 0.7f, Colours::transparentBlack,
  445. juceImage, 1.0f, Colours::transparentBlack,
  446. juceImage, 1.0f, Colours::pink.withAlpha (0.8f),
  447. 0.5f);
  448. imageButton->setTopLeftPosition (10, 160);
  449. imageButton->setTooltip (T("image button - showing alpha-channel hit-testing and colour overlay when clicked"));
  450. //==============================================================================
  451. ColourChangeButton* colourChangeButton = new ColourChangeButton();
  452. addAndMakeVisible (colourChangeButton);
  453. colourChangeButton->setTopLeftPosition (350, 30);
  454. //==============================================================================
  455. animateButton = new TextButton (T("click to animate..."));
  456. addAndMakeVisible (animateButton);
  457. animateButton->changeWidthToFitText (24);
  458. animateButton->setTopLeftPosition (350, 70);
  459. animateButton->addButtonListener (this);
  460. }
  461. ~ButtonsPage()
  462. {
  463. deleteAllChildren();
  464. }
  465. void buttonClicked (Button*)
  466. {
  467. for (int i = getNumChildComponents(); --i >= 0;)
  468. {
  469. if (getChildComponent (i) != animateButton)
  470. {
  471. animator.animateComponent (getChildComponent (i),
  472. Rectangle (Random::getSystemRandom().nextInt (getWidth() / 2),
  473. Random::getSystemRandom().nextInt (getHeight() / 2),
  474. 60 + Random::getSystemRandom().nextInt (getWidth() / 3),
  475. 16 + Random::getSystemRandom().nextInt (getHeight() / 6)),
  476. 500 + Random::getSystemRandom().nextInt (2000),
  477. Random::getSystemRandom().nextDouble(),
  478. Random::getSystemRandom().nextDouble());
  479. }
  480. }
  481. }
  482. private:
  483. TextButton* animateButton;
  484. ComponentAnimator animator;
  485. };
  486. //==============================================================================
  487. static Component* createMiscPage()
  488. {
  489. DemoPageComp* page = new DemoPageComp();
  490. TextEditor* textEditor = new TextEditor();
  491. page->addAndMakeVisible (textEditor);
  492. textEditor->setBounds (10, 25, 200, 24);
  493. textEditor->setText (T("single-line text box"));
  494. textEditor = new TextEditor (T("password"), (tchar) 0x2022);
  495. page->addAndMakeVisible (textEditor);
  496. textEditor->setBounds (10, 55, 200, 24);
  497. textEditor->setText (T("password"));
  498. //==============================================================================
  499. ComboBox* comboBox = new ComboBox (T("combo"));
  500. page->addAndMakeVisible (comboBox);
  501. comboBox->setBounds (300, 25, 200, 24);
  502. comboBox->setEditableText (true);
  503. comboBox->setJustificationType (Justification::centred);
  504. int i;
  505. for (i = 1; i < 100; ++i)
  506. comboBox->addItem (T("combo box item ") + String (i), i);
  507. comboBox->setSelectedId (1);
  508. DragOntoDesktopDemoComp* d = new DragOntoDesktopDemoComp (page);
  509. page->addAndMakeVisible (d);
  510. d->setBounds (20, 100, 200, 80);
  511. return page;
  512. }
  513. //==============================================================================
  514. class ToolbarDemoComp : public Component,
  515. public SliderListener,
  516. public ButtonListener
  517. {
  518. public:
  519. ToolbarDemoComp (ApplicationCommandManager* commandManager)
  520. {
  521. // Create and add the toolbar...
  522. addAndMakeVisible (toolbar = new Toolbar());
  523. // And use our item factory to add a set of default icons to it...
  524. toolbar->addDefaultItems (factory);
  525. // Now we'll just create the other sliders and buttons on the demo page, which adjust
  526. // the toolbar's properties...
  527. Label* info = new Label (String::empty,
  528. "As well as showing off toolbars, this demo illustrates how to store "
  529. "a set of SVG files in a Zip file, embed that in your application, and read "
  530. "them back in at runtime.\n\nThe icon images here are taken from the open-source "
  531. "Tango icon project.");
  532. addAndMakeVisible (info);
  533. info->setJustificationType (Justification::topLeft);
  534. info->setBounds (80, 80, 450, 100);
  535. info->setInterceptsMouseClicks (false, false);
  536. addAndMakeVisible (depthSlider = new Slider (T("toolbar depth:")));
  537. depthSlider->setRange (10.0, 200.0, 1.0);
  538. depthSlider->setValue (50, false);
  539. depthSlider->setSliderStyle (Slider::LinearHorizontal);
  540. depthSlider->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
  541. depthSlider->addListener (this);
  542. depthSlider->setBounds (80, 210, 300, 22);
  543. (new Label (depthSlider->getName(), depthSlider->getName()))->attachToComponent (depthSlider, false);
  544. addAndMakeVisible (orientationButton = new TextButton (T("vertical/horizontal")));
  545. orientationButton->addButtonListener (this);
  546. orientationButton->changeWidthToFitText (22);
  547. orientationButton->setTopLeftPosition (depthSlider->getX(), depthSlider->getBottom() + 20);
  548. addAndMakeVisible (customiseButton = new TextButton (T("customise...")));
  549. customiseButton->addButtonListener (this);
  550. customiseButton->changeWidthToFitText (22);
  551. customiseButton->setTopLeftPosition (orientationButton->getRight() + 20, orientationButton->getY());
  552. }
  553. ~ToolbarDemoComp()
  554. {
  555. deleteAllChildren();
  556. }
  557. void resized()
  558. {
  559. if (toolbar->isVertical())
  560. toolbar->setBounds (0, 0, (int) depthSlider->getValue(), getHeight());
  561. else
  562. toolbar->setBounds (0, 0, getWidth(), (int) depthSlider->getValue());
  563. }
  564. void sliderValueChanged (Slider* slider)
  565. {
  566. resized();
  567. }
  568. void buttonClicked (Button* button)
  569. {
  570. if (button == orientationButton)
  571. {
  572. toolbar->setVertical (! toolbar->isVertical());
  573. resized();
  574. }
  575. else if (button == customiseButton)
  576. {
  577. toolbar->showCustomisationDialog (factory);
  578. }
  579. }
  580. private:
  581. Toolbar* toolbar;
  582. Slider* depthSlider;
  583. TextButton* orientationButton;
  584. TextButton* customiseButton;
  585. //==============================================================================
  586. class DemoToolbarItemFactory : public ToolbarItemFactory
  587. {
  588. public:
  589. DemoToolbarItemFactory() {}
  590. ~DemoToolbarItemFactory() {}
  591. //==============================================================================
  592. // Each type of item a toolbar can contain must be given a unique ID. These
  593. // are the ones we'll use in this demo.
  594. enum DemoToolbarItemIds
  595. {
  596. doc_new = 1,
  597. doc_open = 2,
  598. doc_save = 3,
  599. doc_saveAs = 4,
  600. edit_copy = 5,
  601. edit_cut = 6,
  602. edit_paste = 7,
  603. juceLogoButton = 8,
  604. customComboBox = 9
  605. };
  606. void getAllToolbarItemIds (Array <int>& ids)
  607. {
  608. // This returns the complete list of all item IDs that are allowed to
  609. // go in our toolbar. Any items you might want to add must be listed here. The
  610. // order in which they are listed will be used by the toolbar customisation panel.
  611. ids.add (doc_new);
  612. ids.add (doc_open);
  613. ids.add (doc_save);
  614. ids.add (doc_saveAs);
  615. ids.add (edit_copy);
  616. ids.add (edit_cut);
  617. ids.add (edit_paste);
  618. ids.add (juceLogoButton);
  619. ids.add (customComboBox);
  620. // If you're going to use separators, then they must also be added explicitly
  621. // to the list.
  622. ids.add (separatorBarId);
  623. ids.add (spacerId);
  624. ids.add (flexibleSpacerId);
  625. }
  626. void getDefaultItemSet (Array <int>& ids)
  627. {
  628. // This returns an ordered list of the set of items that make up a
  629. // toolbar's default set. Not all items need to be on this list, and
  630. // items can appear multiple times (e.g. the separators used here).
  631. ids.add (doc_new);
  632. ids.add (doc_open);
  633. ids.add (doc_save);
  634. ids.add (doc_saveAs);
  635. ids.add (spacerId);
  636. ids.add (separatorBarId);
  637. ids.add (edit_copy);
  638. ids.add (edit_cut);
  639. ids.add (edit_paste);
  640. ids.add (separatorBarId);
  641. ids.add (flexibleSpacerId);
  642. ids.add (customComboBox);
  643. ids.add (flexibleSpacerId);
  644. ids.add (separatorBarId);
  645. ids.add (juceLogoButton);
  646. }
  647. ToolbarItemComponent* createItem (const int itemId)
  648. {
  649. switch (itemId)
  650. {
  651. case doc_new:
  652. return createButtonFromZipFileSVG (itemId, T("new"), T("document-new.svg"));
  653. case doc_open:
  654. return createButtonFromZipFileSVG (itemId, T("open"), T("document-open.svg"));
  655. case doc_save:
  656. return createButtonFromZipFileSVG (itemId, T("save"), T("document-save.svg"));
  657. case doc_saveAs:
  658. return createButtonFromZipFileSVG (itemId, T("save as"), T("document-save-as.svg"));
  659. case edit_copy:
  660. return createButtonFromZipFileSVG (itemId, T("copy"), T("edit-copy.svg"));
  661. case edit_cut:
  662. return createButtonFromZipFileSVG (itemId, T("cut"), T("edit-cut.svg"));
  663. case edit_paste:
  664. return createButtonFromZipFileSVG (itemId, T("paste"), T("edit-paste.svg"));
  665. case juceLogoButton:
  666. return new ToolbarButton (itemId, T("juce!"), Drawable::createFromImageData (BinaryData::juce_png, BinaryData::juce_pngSize), 0);
  667. case customComboBox:
  668. return new CustomToolbarComboBox (itemId);
  669. default:
  670. break;
  671. }
  672. return 0;
  673. }
  674. private:
  675. StringArray iconNames;
  676. OwnedArray <Drawable> iconsFromZipFile;
  677. // This is a little utility to create a button with one of the SVG images in
  678. // our embedded ZIP file "icons.zip"
  679. ToolbarButton* createButtonFromZipFileSVG (const int itemId, const String& text, const String& filename)
  680. {
  681. if (iconsFromZipFile.size() == 0)
  682. {
  683. // If we've not already done so, load all the images from the zip file..
  684. MemoryInputStream iconsFileStream (BinaryData::icons_zip, BinaryData::icons_zipSize, false);
  685. ZipFile icons (&iconsFileStream, false);
  686. for (int i = 0; i < icons.getNumEntries(); ++i)
  687. {
  688. InputStream* svgFileStream = icons.createStreamForEntry (i);
  689. if (svgFileStream != 0)
  690. {
  691. iconNames.add (icons.getEntry(i)->filename);
  692. iconsFromZipFile.add (Drawable::createFromImageDataStream (*svgFileStream));
  693. delete svgFileStream;
  694. }
  695. }
  696. }
  697. Drawable* image = iconsFromZipFile [iconNames.indexOf (filename)]->createCopy();
  698. return new ToolbarButton (itemId, text, image, 0);
  699. return 0;
  700. }
  701. // Demonstrates how to put a custom component into a toolbar - this one contains
  702. // a ComboBox.
  703. class CustomToolbarComboBox : public ToolbarItemComponent
  704. {
  705. public:
  706. CustomToolbarComboBox (const int toolbarItemId)
  707. : ToolbarItemComponent (toolbarItemId, T("Custom Toolbar Item"), false)
  708. {
  709. addAndMakeVisible (comboBox = new ComboBox (T("demo toolbar combo box")));
  710. for (int i = 1; i < 20; ++i)
  711. comboBox->addItem (T("Toolbar ComboBox item ") + String (i), i);
  712. comboBox->setSelectedId (1);
  713. comboBox->setEditableText (true);
  714. }
  715. ~CustomToolbarComboBox()
  716. {
  717. delete comboBox;
  718. }
  719. bool getToolbarItemSizes (int toolbarDepth,
  720. bool isToolbarVertical,
  721. int& preferredSize, int& minSize, int& maxSize)
  722. {
  723. if (isToolbarVertical)
  724. return false;
  725. preferredSize = 250;
  726. minSize = 80;
  727. maxSize = 300;
  728. return true;
  729. }
  730. void paintButtonArea (Graphics&, int, int, bool, bool)
  731. {
  732. }
  733. void contentAreaChanged (const Rectangle& contentArea)
  734. {
  735. comboBox->setSize (contentArea.getWidth() - 2,
  736. jmin (contentArea.getHeight() - 2, 22));
  737. comboBox->setCentrePosition (contentArea.getCentreX(), contentArea.getCentreY());
  738. }
  739. private:
  740. ComboBox* comboBox;
  741. };
  742. };
  743. DemoToolbarItemFactory factory;
  744. };
  745. //==============================================================================
  746. class DemoTabbedComponent : public TabbedComponent,
  747. public ButtonListener
  748. {
  749. public:
  750. DemoTabbedComponent (ApplicationCommandManager* commandManager)
  751. : TabbedComponent (TabbedButtonBar::TabsAtTop)
  752. {
  753. addTab (T("sliders"), getRandomBrightColour(), createSlidersPage(), true);
  754. addTab (T("toolbars"), getRandomBrightColour(), new ToolbarDemoComp (commandManager), true);
  755. addTab (T("buttons"), getRandomBrightColour(), new ButtonsPage (this), true);
  756. addTab (T("radio buttons"), getRandomBrightColour(), createRadioButtonPage(), true);
  757. addTab (T("misc widgets"), getRandomBrightColour(), createMiscPage(), true);
  758. }
  759. ~DemoTabbedComponent()
  760. {
  761. }
  762. void buttonClicked (Button* button)
  763. {
  764. BubbleMessageComponent* bmc = new BubbleMessageComponent();
  765. if (Desktop::canUseSemiTransparentWindows())
  766. {
  767. bmc->setAlwaysOnTop (true);
  768. bmc->addToDesktop (0);
  769. }
  770. else
  771. {
  772. addChildComponent (bmc);
  773. }
  774. bmc->showAt (button, T("This is a demo of the BubbleMessageComponent, which lets you pop up a message pointing at a component or somewhere on the screen.\n\nThe message bubbles will disappear after a timeout period, or when the mouse is clicked."),
  775. 2000, true, true);
  776. }
  777. static const Colour getRandomBrightColour()
  778. {
  779. return Colour (Random::getSystemRandom().nextFloat(), 0.1f, 0.97f, 1.0f);
  780. }
  781. };
  782. //==============================================================================
  783. class DemoBackgroundThread : public ThreadWithProgressWindow
  784. {
  785. public:
  786. DemoBackgroundThread()
  787. : ThreadWithProgressWindow (T("busy doing some important things..."),
  788. true,
  789. true)
  790. {
  791. setStatusMessage (T("Getting ready..."));
  792. }
  793. ~DemoBackgroundThread()
  794. {
  795. }
  796. void run()
  797. {
  798. const int thingsToDo = 10;
  799. for (int i = 0; i < thingsToDo; ++i)
  800. {
  801. // must check this as often as possible, because this is
  802. // how we know if the user's pressed 'cancel'
  803. if (threadShouldExit())
  804. break;
  805. // this will update the progress bar on the dialog box
  806. setProgress (i / (double) thingsToDo);
  807. wait (500);
  808. setStatusMessage (String (thingsToDo - i) + T(" things left to do..."));
  809. }
  810. }
  811. };
  812. //==============================================================================
  813. /** A DialogWindow containing a ColourSelector component */
  814. class ColourSelectorDialogWindow : public DialogWindow
  815. {
  816. public:
  817. ColourSelectorDialogWindow()
  818. : DialogWindow (T("Colour selector demo"),
  819. Colours::lightgrey,
  820. true)
  821. {
  822. setContentComponent (new ColourSelector());
  823. centreWithSize (400, 400);
  824. setResizable (true, true);
  825. }
  826. ~ColourSelectorDialogWindow()
  827. {
  828. }
  829. void closeButtonPressed()
  830. {
  831. // we expect this component to be run within a modal loop, so when the close
  832. // button is clicked, we can make it invisible to cause the loop to exit and the
  833. // calling code will delete this object.
  834. setVisible (false);
  835. }
  836. };
  837. #if JUCE_MAC
  838. //==============================================================================
  839. /** This pops open a dialog box and waits for you to press keys on your Apple Remote,
  840. which it describes in the box.
  841. */
  842. class AppleRemoteTestWindow : public AlertWindow,
  843. public AppleRemoteDevice
  844. {
  845. public:
  846. AppleRemoteTestWindow()
  847. : AlertWindow ("Apple Remote Control Test!",
  848. "If you've got an Apple Remote, press some buttons now...",
  849. AlertWindow::NoIcon)
  850. {
  851. addButton (T("done"), 0);
  852. // (To open the device in non-exclusive mode, pass 'false' in here)..
  853. if (! start (true))
  854. setMessage ("Couldn't open the remote control device!");
  855. }
  856. ~AppleRemoteTestWindow()
  857. {
  858. stop();
  859. }
  860. void buttonPressed (const ButtonType buttonId, const bool isDown)
  861. {
  862. String desc;
  863. switch (buttonId)
  864. {
  865. case menuButton:
  866. desc = "menu button (short)";
  867. break;
  868. case playButton:
  869. desc = "play button";
  870. break;
  871. case plusButton:
  872. desc = "plus button";
  873. break;
  874. case minusButton:
  875. desc = "minus button";
  876. break;
  877. case rightButton:
  878. desc = "right button (short)";
  879. break;
  880. case leftButton:
  881. desc = "left button (short)";
  882. break;
  883. case rightButton_Long:
  884. desc = "right button (long)";
  885. break;
  886. case leftButton_Long:
  887. desc = "left button (long)";
  888. break;
  889. case menuButton_Long:
  890. desc = "menu button (long)";
  891. break;
  892. case playButtonSleepMode:
  893. desc = "play (sleep mode)";
  894. break;
  895. case switched:
  896. desc = "remote switched";
  897. break;
  898. }
  899. if (isDown)
  900. desc << " -- [down]";
  901. else
  902. desc << " -- [up]";
  903. setMessage (desc);
  904. }
  905. };
  906. #endif
  907. //==============================================================================
  908. const int numGroups = 4;
  909. class WidgetsDemo : public Component,
  910. public ButtonListener
  911. {
  912. TextButton* menuButton;
  913. ToggleButton* enableButton;
  914. DemoTabbedComponent* tabs;
  915. public:
  916. //==============================================================================
  917. WidgetsDemo (ApplicationCommandManager* commandManager)
  918. {
  919. setName (T("Widgets"));
  920. addAndMakeVisible (tabs = new DemoTabbedComponent (commandManager));
  921. //==============================================================================
  922. menuButton = new TextButton (T("click for a popup menu.."),
  923. T("click for a demo of the different types of item you can put into a popup menu..."));
  924. addAndMakeVisible (menuButton);
  925. menuButton->setBounds (10, 10, 200, 24);
  926. menuButton->addButtonListener (this);
  927. menuButton->setTriggeredOnMouseDown (true); // because this button pops up a menu, this lets us
  928. // hold down the button and drag straight onto the menu
  929. //==============================================================================
  930. enableButton = new ToggleButton (T("enable/disable components"));
  931. addAndMakeVisible (enableButton);
  932. enableButton->setBounds (230, 10, 180, 24);
  933. enableButton->setTooltip (T("toggle button"));
  934. enableButton->setToggleState (true, false);
  935. enableButton->addButtonListener (this);
  936. }
  937. ~WidgetsDemo()
  938. {
  939. deleteAllChildren();
  940. }
  941. void resized()
  942. {
  943. tabs->setBounds (10, 40, getWidth() - 20, getHeight() - 50);
  944. }
  945. //==============================================================================
  946. void buttonClicked (Button* button)
  947. {
  948. if (button == enableButton)
  949. {
  950. const bool enabled = enableButton->getToggleState();
  951. menuButton->setEnabled (enabled);
  952. tabs->setEnabled (enabled);
  953. }
  954. else if (button == menuButton)
  955. {
  956. PopupMenu m;
  957. m.addItem (1, T("Normal item"));
  958. m.addItem (2, T("Disabled item"), false);
  959. m.addItem (3, T("Ticked item"), true, true);
  960. m.addColouredItem (4, T("Coloured item"), Colours::green);
  961. m.addSeparator();
  962. m.addCustomItem (5, new CustomMenuComponent());
  963. m.addSeparator();
  964. PopupMenu tabsMenu;
  965. tabsMenu.addItem (1001, T("Show tabs at the top"), true, tabs->getOrientation() == TabbedButtonBar::TabsAtTop);
  966. tabsMenu.addItem (1002, T("Show tabs at the bottom"), true, tabs->getOrientation() == TabbedButtonBar::TabsAtBottom);
  967. tabsMenu.addItem (1003, T("Show tabs at the left"), true, tabs->getOrientation() == TabbedButtonBar::TabsAtLeft);
  968. tabsMenu.addItem (1004, T("Show tabs at the right"), true, tabs->getOrientation() == TabbedButtonBar::TabsAtRight);
  969. m.addSubMenu (T("Tab position"), tabsMenu);
  970. m.addSeparator();
  971. PopupMenu dialogMenu;
  972. dialogMenu.addItem (100, T("Show a plain alert-window..."));
  973. dialogMenu.addItem (101, T("Show an alert-window with a 'warning' icon..."));
  974. dialogMenu.addItem (102, T("Show an alert-window with an 'info' icon..."));
  975. dialogMenu.addItem (103, T("Show an alert-window with a 'question' icon..."));
  976. dialogMenu.addSeparator();
  977. dialogMenu.addItem (110, T("Show an ok/cancel alert-window..."));
  978. dialogMenu.addSeparator();
  979. dialogMenu.addItem (111, T("Show an alert-window with some extra components..."));
  980. dialogMenu.addSeparator();
  981. dialogMenu.addItem (112, T("Show a ThreadWithProgressWindow demo..."));
  982. m.addSubMenu (T("AlertWindow demonstrations"), dialogMenu);
  983. m.addSeparator();
  984. m.addItem (120, T("Show a colour selector demo..."));
  985. m.addSeparator();
  986. #if JUCE_MAC
  987. m.addItem (140, T("Run the Apple Remote Control test..."));
  988. m.addSeparator();
  989. #endif
  990. PopupMenu nativeFileChoosers;
  991. nativeFileChoosers.addItem (121, T("'Load' file browser..."));
  992. nativeFileChoosers.addItem (124, T("'Load' file browser with an image file preview..."));
  993. nativeFileChoosers.addItem (122, T("'Save' file browser..."));
  994. nativeFileChoosers.addItem (123, T("'Choose directory' file browser..."));
  995. PopupMenu juceFileChoosers;
  996. juceFileChoosers.addItem (131, T("'Load' file browser..."));
  997. juceFileChoosers.addItem (134, T("'Load' file browser with an image file preview..."));
  998. juceFileChoosers.addItem (132, T("'Save' file browser..."));
  999. juceFileChoosers.addItem (133, T("'Choose directory' file browser..."));
  1000. PopupMenu fileChoosers;
  1001. fileChoosers.addSubMenu (T("Operating system dialogs"), nativeFileChoosers);
  1002. fileChoosers.addSubMenu (T("Juce dialogs"), juceFileChoosers);
  1003. m.addSubMenu (T("File chooser dialogs"), fileChoosers);
  1004. int result = m.showAt (menuButton);
  1005. if (result != 0)
  1006. {
  1007. // user chose something from the menu..
  1008. if (result >= 100 && result < 105)
  1009. {
  1010. AlertWindow::AlertIconType icon = AlertWindow::NoIcon;
  1011. if (result == 101)
  1012. icon = AlertWindow::WarningIcon;
  1013. else if (result == 102)
  1014. icon = AlertWindow::InfoIcon;
  1015. else if (result == 103)
  1016. icon = AlertWindow::QuestionIcon;
  1017. AlertWindow::showMessageBox (icon,
  1018. T("This is an AlertWindow"),
  1019. T("And this is the AlertWindow's message. Blah blah blah blah blah blah blah blah blah blah blah blah blah."),
  1020. T("ok"));
  1021. }
  1022. else if (result == 110)
  1023. {
  1024. bool userPickedOk
  1025. = AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon,
  1026. T("This is an ok/cancel AlertWindow"),
  1027. T("And this is the AlertWindow's message. Blah blah blah blah blah blah blah blah blah blah blah blah blah."));
  1028. }
  1029. else if (result == 111)
  1030. {
  1031. AlertWindow w (T("AlertWindow demo.."),
  1032. T("This AlertWindow has a couple of extra components added to show how to add drop-down lists and text entry boxes."),
  1033. AlertWindow::QuestionIcon);
  1034. w.addTextEditor (T("text"), T("enter some text here"), T("text field:"));
  1035. StringArray options;
  1036. options.add (T("option 1"));
  1037. options.add (T("option 2"));
  1038. options.add (T("option 3"));
  1039. options.add (T("option 4"));
  1040. w.addComboBox (T("option"), options, T("some options"));
  1041. w.addButton (T("ok"), 1, KeyPress (KeyPress::returnKey, 0, 0));
  1042. w.addButton (T("cancel"), 0, KeyPress (KeyPress::escapeKey, 0, 0));
  1043. if (w.runModalLoop() != 0) // is they picked 'ok'
  1044. {
  1045. // this is the item they chose in the drop-down list..
  1046. const int optionIndexChosen = w.getComboBoxComponent (T("option"))->getSelectedItemIndex();
  1047. // this is the text they entered..
  1048. String text = w.getTextEditorContents (T("text"));
  1049. }
  1050. }
  1051. else if (result == 112)
  1052. {
  1053. DemoBackgroundThread demoThread;
  1054. if (demoThread.runThread())
  1055. {
  1056. // thread finished normally..
  1057. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  1058. T("Progress window"),
  1059. T("Thread finished ok!"));
  1060. }
  1061. else
  1062. {
  1063. // user pressed the cancel button..
  1064. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  1065. T("Progress window"),
  1066. T("You pressed cancel!"));
  1067. }
  1068. }
  1069. else if (result == 120)
  1070. {
  1071. ColourSelectorDialogWindow colourDialog;
  1072. // this will run an event loop until the dialog's closeButtonPressed()
  1073. // method causes the loop to exit.
  1074. colourDialog.runModalLoop();
  1075. }
  1076. else if (result == 140)
  1077. {
  1078. #if JUCE_MAC
  1079. AppleRemoteTestWindow test;
  1080. test.runModalLoop();
  1081. #endif
  1082. }
  1083. else if (result >= 121 && result < 139)
  1084. {
  1085. const bool useNativeVersion = result < 130;
  1086. if (result > 130)
  1087. result -= 10;
  1088. if (result == 121)
  1089. {
  1090. FileChooser fc (T("Choose a file to open..."),
  1091. File::getCurrentWorkingDirectory(),
  1092. T("*"),
  1093. useNativeVersion);
  1094. if (fc.browseForFileToOpen())
  1095. {
  1096. File chosenFile = fc.getResult();
  1097. AlertWindow::showMessageBox (AlertWindow::InfoIcon,
  1098. T("File Chooser..."),
  1099. T("You picked: ") + chosenFile.getFullPathName());
  1100. }
  1101. }
  1102. else if (result == 124)
  1103. {
  1104. ImagePreviewComponent imagePreview;
  1105. imagePreview.setSize (200, 200);
  1106. FileChooser fc (T("Choose an image to open..."),
  1107. File::getCurrentWorkingDirectory(),
  1108. T("*.jpg;*.jpeg;*.png;*.gif"),
  1109. useNativeVersion);
  1110. if (fc.browseForFileToOpen (&imagePreview))
  1111. {
  1112. File chosenFile = fc.getResult();
  1113. AlertWindow::showMessageBox (AlertWindow::InfoIcon,
  1114. T("File Chooser..."),
  1115. T("You picked: ") + chosenFile.getFullPathName());
  1116. }
  1117. }
  1118. else if (result == 122)
  1119. {
  1120. FileChooser fc (T("Choose a file to save..."),
  1121. File::getCurrentWorkingDirectory(),
  1122. T("*"),
  1123. useNativeVersion);
  1124. if (fc.browseForFileToSave (true))
  1125. {
  1126. File chosenFile = fc.getResult();
  1127. AlertWindow::showMessageBox (AlertWindow::InfoIcon,
  1128. T("File Chooser..."),
  1129. T("You picked: ") + chosenFile.getFullPathName());
  1130. }
  1131. }
  1132. else if (result == 123)
  1133. {
  1134. FileChooser fc (T("Choose a directory..."),
  1135. File::getCurrentWorkingDirectory(),
  1136. T("*"),
  1137. useNativeVersion);
  1138. if (fc.browseForDirectory())
  1139. {
  1140. File chosenDirectory = fc.getResult();
  1141. AlertWindow::showMessageBox (AlertWindow::InfoIcon,
  1142. T("File Chooser..."),
  1143. T("You picked: ") + chosenDirectory.getFullPathName());
  1144. }
  1145. }
  1146. }
  1147. else if (result == 1001)
  1148. {
  1149. tabs->setOrientation (TabbedButtonBar::TabsAtTop);
  1150. }
  1151. else if (result == 1002)
  1152. {
  1153. tabs->setOrientation (TabbedButtonBar::TabsAtBottom);
  1154. }
  1155. else if (result == 1003)
  1156. {
  1157. tabs->setOrientation (TabbedButtonBar::TabsAtLeft);
  1158. }
  1159. else if (result == 1004)
  1160. {
  1161. tabs->setOrientation (TabbedButtonBar::TabsAtRight);
  1162. }
  1163. }
  1164. }
  1165. }
  1166. };
  1167. //==============================================================================
  1168. Component* createWidgetsDemo (ApplicationCommandManager* commandManager)
  1169. {
  1170. return new WidgetsDemo (commandManager);
  1171. }