Mixer.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. ==============================================================================
  3. This is an automatically generated GUI class created by the Introjucer!
  4. Be careful when adding custom code to these files, as only the code within
  5. the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
  6. and re-saved.
  7. Created with Introjucer version: 3.1.0
  8. ------------------------------------------------------------------------------
  9. The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions"
  10. Copyright 2004-13 by Raw Material Software Ltd.
  11. ==============================================================================
  12. */
  13. //[Headers] You can add your own extra header files here...
  14. #include "LinJam.h"
  15. #include "Constants.h"
  16. #include "./Trace/TraceMixer.h"
  17. //[/Headers]
  18. #include "Mixer.h"
  19. //[MiscUserDefs] You can add your own user definitions and misc code here...
  20. //[/MiscUserDefs]
  21. //==============================================================================
  22. Mixer::Mixer ()
  23. {
  24. setName ("Mixer");
  25. //[UserPreSize]
  26. this->masterChannels = new MasterChannels() ;
  27. this->localChannels = new LocalChannels() ;
  28. this->prevScrollButton = new TextButton("prevScrollButton") ;
  29. this->nextScrollButton = new TextButton("nextScrollButton") ;
  30. this->localsResizer = new ResizableEdgeComponent(this->localChannels , nullptr ,
  31. ResizableEdgeComponent::rightEdge) ;
  32. this->mastersResizer = new ResizableEdgeComponent(this->masterChannels , nullptr ,
  33. ResizableEdgeComponent::leftEdge) ;
  34. addChannels( this->masterChannels , GUI::MASTERS_GUI_ID) ;
  35. addChannels( this->localChannels , GUI::LOCALS_GUI_ID) ;
  36. addScrollButton(this->prevScrollButton , "<") ;
  37. addScrollButton(this->nextScrollButton , ">") ;
  38. addResizer( this->localsResizer) ;
  39. addResizer( this->mastersResizer) ;
  40. this->masterChannels ->setAlwaysOnTop(true) ;
  41. this->prevScrollButton->setAlwaysOnTop(true) ;
  42. this->nextScrollButton->setAlwaysOnTop(true) ;
  43. this->localsResizer ->setAlwaysOnTop(true) ;
  44. this->mastersResizer ->setAlwaysOnTop(true) ;
  45. //[/UserPreSize]
  46. setSize (622, 284);
  47. //[Constructor] You can add your own custom stuff here..
  48. this->scrollZ = 1 ;
  49. //[/Constructor]
  50. }
  51. Mixer::~Mixer()
  52. {
  53. //[Destructor_pre]. You can add your own custom destruction code here..
  54. //[/Destructor_pre]
  55. //[Destructor]. You can add your own custom destruction code here..
  56. this->masterChannels = nullptr ;
  57. this->localChannels = nullptr ;
  58. this->prevScrollButton = nullptr ;
  59. this->nextScrollButton = nullptr ;
  60. this->localsResizer = nullptr ;
  61. this->mastersResizer = nullptr ;
  62. deleteAllChildren() ;
  63. //[/Destructor]
  64. }
  65. //==============================================================================
  66. void Mixer::paint (Graphics& g)
  67. {
  68. //[UserPrePaint] Add your own custom painting code here..
  69. //[/UserPrePaint]
  70. g.setColour (Colour (0xff101010));
  71. g.fillRoundedRectangle (0.0f, 0.0f, static_cast<float> (getWidth() - 0), static_cast<float> (getHeight() - 0), 10.000f);
  72. g.setColour (Colours::white);
  73. g.drawRoundedRectangle (0.0f, 0.0f, static_cast<float> (getWidth() - 0), static_cast<float> (getHeight() - 0), 10.000f, 1.000f);
  74. //[UserPaint] Add your own custom painting code here..
  75. //[/UserPaint]
  76. }
  77. void Mixer::resized()
  78. {
  79. //[UserResized] Add your own custom resize handling here..
  80. DEBUG_TRACE_MIXER_COMPONENTS_VB
  81. // master channels
  82. int masters_x = getWidth() - this->masterChannels->getWidth() - GUI::PAD ;
  83. int masters_y = GUI::MIXERGROUP_Y ;
  84. int masters_w = this->masterChannels->getWidth() ;
  85. int masters_h = GUI::MIXERGROUP_H ;
  86. this->masterChannels->setBounds(masters_x , masters_y , masters_w , masters_h) ;
  87. // local and remote channels
  88. int channels_x = GUI::PAD ;
  89. int channels_y = GUI::MIXERGROUP_Y ;
  90. int n_groups = getNumDynamicMixers() ;
  91. for (int group_n = GUI::LOCALS_IDX ; group_n < n_groups ; ++group_n)
  92. {
  93. Channels* channels = (Channels*)getChildComponent(group_n) ;
  94. #ifndef FADE_HIDDEN_REMOTES
  95. // hide scrolled previous remotes
  96. if (group_n > GUI::LOCALS_IDX && group_n < this->scrollZ)
  97. {
  98. channels->setVisible(false) ;
  99. if (group_n == GUI::FIRST_REMOTE_IDX)
  100. channels_x += GUI::CHANNEL_SCROLL_BTN_W + GUI::RESIZER_W - GUI::PAD ;
  101. continue ;
  102. }
  103. // position visible channels and increment next channel position
  104. channels->setTopLeftPosition(channels_x , channels_y) ;
  105. channels_x += GUI::PAD + channels->getWidth() ;
  106. // hide scrolled next remotes
  107. int masters_resizer_x = getMastersResizerNextX() ;
  108. channels->setVisible(channels_x <= masters_resizer_x) ;
  109. #else // FADE_HIDDEN_REMOTES
  110. // hide scrolled previous remotes
  111. if (group_n > GUI::LOCALS_IDX && group_n < this->scrollZ)
  112. {
  113. if (group_n < this->scrollZ - 1)
  114. channels_x += GUI::CHANNEL_SCROLL_BTN_W + GUI::RESIZER_W - GUI::PAD
  115. - GUI::PAD + channels->getWidth() ;
  116. else{ channels->setVisible(false) ; continue ; }
  117. }
  118. // hide scrolled next remotes
  119. int masters_resizer_x = getMastersResizerNextX() ;
  120. channels->setVisible(channels_x <= masters_resizer_x) ;
  121. // position visible channels and increment next channel position
  122. channels->setTopLeftPosition(channels_x , channels_y) ;
  123. channels_x += GUI::PAD + channels->getWidth() ;
  124. #endif // FADE_HIDDEN_REMOTES
  125. }
  126. // resizers
  127. positionResizers() ;
  128. // scroll buttons
  129. int locals_resizer_x = this->localsResizer ->getX() ;
  130. int masters_resizer_x = this->mastersResizer->getX() ;
  131. bool should_show_prev_scroll_button = this->scrollZ > GUI::FIRST_REMOTE_IDX ;
  132. bool should_show_next_scroll_button = (channels_x > masters_resizer_x) ;
  133. if (should_show_prev_scroll_button)
  134. {
  135. int prev_button_x = locals_resizer_x + GUI::RESIZER_W - 1 ;
  136. prevScrollButton->setTopLeftPosition(prev_button_x , GUI::CHANNEL_SCROLL_BTN_Y) ;
  137. }
  138. if (should_show_next_scroll_button)
  139. {
  140. int next_button_x = masters_resizer_x - GUI::CHANNEL_SCROLL_BTN_W + 1 ;
  141. nextScrollButton->setTopLeftPosition(next_button_x , GUI::CHANNEL_SCROLL_BTN_Y) ;
  142. }
  143. prevScrollButton->setVisible(should_show_prev_scroll_button) ;
  144. nextScrollButton->setVisible(should_show_next_scroll_button) ;
  145. //[/UserResized]
  146. }
  147. //[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
  148. /* Mixer class public instence methods */
  149. bool Mixer::addRemoteUser(ValueTree user_store , ValueTree subscriptions)
  150. {
  151. // ensure GUI for this user does not already exist
  152. Identifier user_id = user_store.getType() ; if (getChannels(user_id)) return false ;
  153. // create remote user GUI
  154. addChannels(new RemoteChannels(user_store , subscriptions) , user_id) ;
  155. DEBUG_TRACE_ADD_REMOTE_USER
  156. return true ;
  157. }
  158. bool Mixer::addChannel(Identifier channels_id , ValueTree channel_store)
  159. {
  160. // validate channels group GUI and storage
  161. Channels* channels = getChannels(channels_id) ;
  162. if (!channels || !channel_store.isValid()) return false ;
  163. // create channel GUI and update mixer layout
  164. bool was_added = channels->addChannel(channel_store) ;
  165. if (was_added && channels != this->masterChannels) resized() ;
  166. return was_added ;
  167. }
  168. void Mixer::removeChannel(Identifier channels_id , Identifier channel_id)
  169. {
  170. Channels* channels = getChannels(channels_id) ;
  171. if (channels) channels->removeChannel(channel_id) ;
  172. }
  173. void Mixer::positionResizers()
  174. {
  175. int locals_resizer_x = getLocalsResizerNextX() ;
  176. int masters_resizer_x = getMastersResizerNextX() ;
  177. this->localsResizer ->setTopLeftPosition(locals_resizer_x , GUI::MIXERGROUP_Y) ;
  178. this->mastersResizer->setTopLeftPosition(masters_resizer_x , GUI::MIXERGROUP_Y) ;
  179. }
  180. void Mixer::pruneRemotes(ValueTree active_users)
  181. {
  182. // find GUI elements for parted users
  183. for (int user_n = GUI::FIRST_REMOTE_IDX ; user_n < getNumDynamicMixers() ; ++user_n)
  184. {
  185. RemoteChannels* channels = (RemoteChannels*)getChildComponent(user_n) ;
  186. Identifier user_id = Identifier(channels->getComponentID()) ;
  187. Array<var>* active_channels = active_users[user_id].getArray() ;
  188. if (active_users.hasProperty(user_id))
  189. {
  190. // find GUI elements for removed channels of active user (first is master)
  191. for (int channel_n = 1 ; channel_n < channels->getNumChannels() ; ++channel_n)
  192. {
  193. Component* channel = channels->getChildComponent(channel_n) ;
  194. var channel_id = var(channel->getComponentID()) ;
  195. if (active_channels->contains(channel_id)) continue ;
  196. // delete orphaned GUI elements for removed channel
  197. removeChannel(user_id , Identifier(channel_id.toString())) ; --channel_n ;
  198. }
  199. }
  200. // delete orphaned GUI elements for parted user
  201. else { removeChannels(channels) ; --user_n ; }
  202. }
  203. }
  204. /* Mixer class private instance methods */
  205. void Mixer::buttonClicked(Button* a_button)
  206. {
  207. // shift scroll position by one channels group
  208. int n_remotes = getNumDynamicMixers() - GUI::FIRST_REMOTE_IDX ;
  209. if (a_button == prevScrollButton) --this->scrollZ ;
  210. else if (a_button == nextScrollButton && this->scrollZ < n_remotes) ++this->scrollZ ;
  211. else return ;
  212. // update mixer layout
  213. resized() ;
  214. }
  215. void Mixer::addChannels(Channels* channels , Identifier channels_id)
  216. {
  217. // add channels group to the mixer
  218. addChildAndSetID(channels , String(channels_id)) ; channels->toFront(true) ;
  219. // update mixer layout
  220. resized() ;
  221. }
  222. void Mixer::removeChannels(Channels* channels)
  223. {
  224. DEBUG_REMOVE_CHANNELS
  225. // destroy channels group and update mixer layout
  226. delete channels ; resized() ;
  227. }
  228. void Mixer::addScrollButton(TextButton* scroll_button , String button_text)
  229. {
  230. addChildComponent(scroll_button) ;
  231. scroll_button->addListener(this) ;
  232. scroll_button->setButtonText(button_text) ;
  233. scroll_button->setColour(TextButton::buttonColourId , Colour(0xff004000)) ;
  234. scroll_button->setColour(TextButton::buttonOnColourId , Colours::green) ;
  235. scroll_button->setColour(TextButton::textColourOnId , Colours::lime) ;
  236. scroll_button->setColour(TextButton::textColourOffId , Colours::lime) ;
  237. scroll_button->setSize(GUI::CHANNEL_SCROLL_BTN_W , GUI::CHANNEL_SCROLL_BTN_H) ;
  238. }
  239. void Mixer::addResizer(ResizableEdgeComponent* resizer)
  240. {
  241. addAndMakeVisible(resizer) ;
  242. resizer->setSize(GUI::RESIZER_W , GUI::MIXERGROUP_H) ;
  243. }
  244. Channels* Mixer::getChannels(Identifier channels_id)
  245. {
  246. return (Channels*)findChildWithID(StringRef(String(channels_id))) ;
  247. }
  248. int Mixer::getNumDynamicMixers()
  249. {
  250. return getNumChildComponents() - GUI::N_STATIC_MIXER_CHILDREN ;
  251. }
  252. int Mixer::getLocalsResizerNextX() { return localChannels->getRight() - 1 ; }
  253. int Mixer::getMastersResizerNextX() { return masterChannels->getX() - GUI::RESIZER_W + 1 ; }
  254. //[/MiscUserCode]
  255. //==============================================================================
  256. #if 0
  257. /* -- Introjucer information section --
  258. This is where the Introjucer stores the metadata that describe this GUI layout, so
  259. make changes in here at your peril!
  260. BEGIN_JUCER_METADATA
  261. <JUCER_COMPONENT documentType="Component" className="Mixer" componentName="Mixer"
  262. parentClasses="public Component, public ButtonListener" constructorParams=""
  263. variableInitialisers="" snapPixels="8" snapActive="1" snapShown="1"
  264. overlayOpacity="0.330" fixedSize="0" initialWidth="622" initialHeight="284">
  265. <BACKGROUND backgroundColour="0">
  266. <ROUNDRECT pos="0 0 0M 0M" cornerSize="10" fill="solid: ff101010" hasStroke="1"
  267. stroke="1, mitered, butt" strokeColour="solid: ffffffff"/>
  268. </BACKGROUND>
  269. </JUCER_COMPONENT>
  270. END_JUCER_METADATA
  271. */
  272. #endif
  273. //[EndFile] You can add extra defines here...
  274. //[/EndFile]