Skip to content

Commit

Permalink
Provides DataWindow::Listener to handle windoClosed()
Browse files Browse the repository at this point in the history
  • Loading branch information
oyeb committed Jul 18, 2016
1 parent a5d8c8b commit 512ba04
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 54 deletions.
4 changes: 2 additions & 2 deletions Source/Plugins/CyclopsStimulator/CyclopsCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ void CyclopsCanvas::resized()
{
int width = getWidth(), height = getHeight();
baudrateCombo->setBounds(width-75, 5, 70, 20);
portCombo->setBounds(width-75-5-60, 5, 60, 20);
refreshButton->setBounds(width-75-5-60-5-20, 5, 20, 20);
portCombo->setBounds(width-75-5-70, 5, 70, 20);
refreshButton->setBounds(width-75-5-70-5-20, 5, 20, 20);
for (int i=0; i < 4; i++){
testButtons[i]->setBounds(jmax(100, width-53), jmax(45, (height/5))*(i+1)-(25/2), 50, 25);
}
Expand Down
46 changes: 31 additions & 15 deletions Source/Plugins/CyclopsStimulator/CyclopsEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "CyclopsEditor.h"
//#include <../../Processors/Visualization/DataWindow.h>

namespace cyclops {

Expand Down Expand Up @@ -52,9 +51,15 @@ CyclopsEditor::CyclopsEditor(GenericProcessor* parentNode, bool useDefaultParame
prepareCanvasCombo(canvasOptions);
canvasCombo->addItemList(canvasOptions, 1);
canvasCombo->setSelectedItemIndex(0);
canvasCombo->setBounds((240-90)/2, 30, 90, 25);
canvasCombo->setBounds((240-85)*5/6, 30, 90, 25);
addAndMakeVisible(canvasCombo);

comboText = new Label("combo label", "Select Device:");
comboText->setBounds(3,27,200,30);
comboText->setFont(Font("Default", 16, Font::plain));
comboText->setColour(Label::textColourId, Colours::black);
addAndMakeVisible(comboText);

// Add LEDs
serialLED->setBounds(169, 6, 12, 12);
readinessLED->setBounds(183, 6, 12, 12);
Expand All @@ -71,6 +76,8 @@ CyclopsEditor::~CyclopsEditor()
if (CyclopsProcessor::getProcessorCount() == 0){
CyclopsCanvas::canvasList.clear(true);
}
if (connectedCanvas->dataWindow != nullptr)
VisualizerEditor::removeWindowListener(connectedCanvas->dataWindow, this);
}


Expand Down Expand Up @@ -101,7 +108,7 @@ void CyclopsEditor::buttonClicked(Button* button)
// have we created a window already?
if (connectedCanvas->dataWindow == nullptr) {
//std::cout << "no win-exists--" << std::flush;
makeNewWindow(true);
makeNewWindow();
// now pass ownership -- very ugly line...
connectedCanvas->dataWindow = dataWindow;
//std::cout << "made win--" << std::flush;
Expand All @@ -128,6 +135,7 @@ void CyclopsEditor::buttonClicked(Button* button)
//std::cout << "show" << std::flush;
}
}
VisualizerEditor::addWindowListener(connectedCanvas->dataWindow, this);
notifyButtons(Notifs::ALL_TAB, false);
}
else if (button == tabSelector) {
Expand Down Expand Up @@ -170,6 +178,11 @@ void CyclopsEditor::buttonClicked(Button* button)
buttonEvent(button);
}

void CyclopsEditor::windowClosed()
{
windowSelector->setToggleState(false, dontSendNotification);
}

/**
The listener methods that reacts to the button click. The same method is called for all buttons
on the editor, so the button variable, which cointains a pointer to the button that called the method
Expand Down Expand Up @@ -228,21 +241,24 @@ void CyclopsEditor::updateSettings()
;
}

void CyclopsEditor::notifyButtons(Notifs component, bool state)
void CyclopsEditor::notifyButtons(Notifs whichComponents, bool state)
{
if (component == Notifs::ALL_WINDOW) {
for (auto& editor : connectedCanvas->getRegisteredEditors())
for (auto& editor : connectedCanvas->getRegisteredEditors())
{
switch (whichComponents)
{
case Notifs::ALL_WINDOW :
editor->windowSelector->setToggleState(state, dontSendNotification);
}
else {// if (component == Notifs::ALL_WINDOW)
for (auto& editor : connectedCanvas->getRegisteredEditors())
editor->tabSelector->setToggleState(state, dontSendNotification);
}
}
break;

void CyclopsEditor::windowClosed()
{
CyclopsEditor::notifyButtons(Notifs::ALL_WINDOW, false);
case Notifs::ALL_TAB :
editor->tabSelector->setToggleState(state, dontSendNotification);
break;

default:
break;
}
}
}

void CyclopsEditor::saveEditorParameters(XmlElement* xmlNode)
Expand Down
18 changes: 14 additions & 4 deletions Source/Plugins/CyclopsStimulator/CyclopsEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ namespace cyclops{

enum class Notifs{
ALL_WINDOW,
ALL_TAB
ALL_TAB,
ALL_BUT_THIS_WINDOW,
ALL_BUT_THIS_TAB,
};

class CyclopsProcessor;
Expand All @@ -64,6 +66,14 @@ class CyclopsEditor : public VisualizerEditor
Visualizer* createNewCanvas();

void buttonClicked(Button* button);

/**
* @brief Called when the shared window is closed. Used to update the
* SelectorButton state of _other_ CyclopsEditors.
* @details Does not delete instance of DataWindow.
*/
void windowClosed();

/** This method executes whenever a custom button is pressed */
void buttonEvent(Button* button);

Expand All @@ -88,8 +98,7 @@ class CyclopsEditor : public VisualizerEditor
It's called after the processors' same named method.
*/
void updateSettings();
void notifyButtons(Notifs component, bool state);
void windowClosed();
void notifyButtons(Notifs whichComponents, bool state);

void saveEditorParameters(XmlElement* xmlNode);
void loadEditorParameters(XmlElement* xmlNode);
Expand All @@ -101,7 +110,8 @@ class CyclopsEditor : public VisualizerEditor
CyclopsCanvas* connectedCanvas; /**< Pointer to the canvas which this editor connects */
ScopedPointer<ComboBox> canvasCombo; /**< Cyclops Board chooser drop-down */
CyclopsProcessor* processor; /**< Parent Processor node */

ScopedPointer<Label> comboText;

ScopedPointer<IndicatorLED> serialLED;
ScopedPointer<IndicatorLED> readinessLED;

Expand Down
30 changes: 20 additions & 10 deletions Source/Processors/Editors/VisualizerEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ VisualizerEditor::~VisualizerEditor()
{
AccessClass::getDataViewport()->destroyTab(tabIndex);
}

if (dataWindow != nullptr)
dataWindow->removeListener(this);
deleteAllChildren();

}
Expand Down Expand Up @@ -194,6 +195,7 @@ void VisualizerEditor::buttonClicked(Button* button)
dataWindow = new DataWindow(windowSelector, tabText);
dataWindow->setContentNonOwned(canvas, false);
dataWindow->setVisible(true);
dataWindow->addListener(this);
//canvas->refreshState();

}
Expand Down Expand Up @@ -313,6 +315,10 @@ void VisualizerEditor::loadCustomParameters(XmlElement* xml)
}
}

void VisualizerEditor::windowClosed()
{
std::cout<<"closing ve"<<std::endl;
}

void VisualizerEditor::saveVisualizerParameters(XmlElement* xml)
{
Expand All @@ -324,22 +330,26 @@ void VisualizerEditor::loadVisualizerParameters(XmlElement* xml)

}

void VisualizerEditor::makeNewWindow(bool enableCallback)
void VisualizerEditor::makeNewWindow()
{
if (enableCallback)
// used by CyclopsEditor to consistently update windowSelector buttons
// even when window is closed.
dataWindow = new DataWindow(windowSelector, this, tabText);
else
dataWindow = new DataWindow(windowSelector, tabText);
dataWindow = new DataWindow(windowSelector, tabText);
}

void VisualizerEditor::windowClosed()
void VisualizerEditor::addWindowListener(DataWindow* dw, DataWindow::Listener* newListener)
{
if (dw != nullptr && newListener != nullptr){
dw->addListener(newListener);
}
}

void VisualizerEditor::removeWindowListener(DataWindow* dw, DataWindow::Listener* oldListener)
{
if (dw != nullptr && oldListener != nullptr){
dw->removeListener(oldListener);
}
}

Component* VisualizerEditor::getActiveTabContentComponent()
Component* VisualizerEditor::getActiveTabContentComponent() const
{
return AccessClass::getDataViewport()->getCurrentContentComponent();
}
Expand Down
25 changes: 15 additions & 10 deletions Source/Processors/Editors/VisualizerEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class PLUGIN_API SelectorButton : public Button
*/

class PLUGIN_API VisualizerEditor : public GenericEditor
, public DataWindow::Listener
{
public:
/**
Expand All @@ -91,6 +92,17 @@ class PLUGIN_API VisualizerEditor : public GenericEditor
*/
void buttonClicked(Button* button);

/**
* @brief Called when the window is closed.
* @details It is safe to "delete" a DataWindow instance from this
* callback/listener. This would (typically) not be done,
* because instances of DataWindow are (typically) "owned" by
* Editors, and will be deleted when the Editor dies.
* @note VisualizerEditor owns DataWindow instance. See cyclops::CyclopsEditor
* for a use case.
*/
void windowClosed();

/**
* @brief All additional buttons that you create _for the editor_ should be handled here.
*/
Expand All @@ -104,8 +116,6 @@ class PLUGIN_API VisualizerEditor : public GenericEditor
virtual void enable();
virtual void disable();

virtual void windowClosed();

void editorWasClicked();

void updateVisualizer();
Expand All @@ -131,15 +141,10 @@ class PLUGIN_API VisualizerEditor : public GenericEditor
* @details Use this to make a new DataWindow. If needed, you can
* transfer ownership of the new object from
* VisualizerEditor::dataWindow to _your_ own ScopedPointer.
*
* @param[in] enableCallbacks **When** ``true``, it passes "``this``" to
* constructor of the DataWindow and
* VisualizerEditor::windowClosed() is invoked
* when window is closed. **When** ``false``,
* ``this`` is not passed and callback does not
* happen.
*/
void makeNewWindow(bool enableCallbacks = false);
void makeNewWindow();
static void addWindowListener(DataWindow* dw, DataWindow::Listener* newListener);
static void removeWindowListener(DataWindow* dw, DataWindow::Listener* oldListener);

/**
* @brief Use this to efficiently compare or find what is on the
Expand Down
27 changes: 18 additions & 9 deletions Source/Processors/Visualization/DataWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,13 @@ DataWindow::DataWindow(Button* cButton, String name)
Colours::black,
DocumentWindow::allButtons)
, controlButton(cButton)
, vizEditor(nullptr)

{
centreWithSize(800,500);
setUsingNativeTitleBar(true);
setResizable(true,false);
}

DataWindow::DataWindow(Button* button, VisualizerEditor* editor, String name)
: DataWindow(button, name)
{
vizEditor = editor;
}

DataWindow::~DataWindow()
{

Expand All @@ -53,7 +46,23 @@ void DataWindow::closeButtonPressed()
setContentNonOwned(0,false);
setVisible(false);
controlButton->setToggleState(false, dontSendNotification);
if (vizEditor != nullptr){
dynamic_cast<VisualizerEditor*>(vizEditor)->windowClosed();
// with the BailOutChecker, it is safe to "delete" a DataWindow instance
// from this callback/listener. This would (typically) not be done, because instances
// of DataWindow are (typically) "owned" by Editors, and will be deleted
// when the Editor dies.
//
Component::BailOutChecker checker (this);
if (! checker.shouldBailOut()){
closeWindowListeners.callChecked (checker, &DataWindow::Listener::windowClosed);
}
}

void DataWindow::addListener (DataWindow::Listener* const newListener)
{
closeWindowListeners.add (newListener);
}

void DataWindow::removeListener (DataWindow::Listener* const listener)
{
closeWindowListeners.remove (listener);
}
27 changes: 23 additions & 4 deletions Source/Processors/Visualization/DataWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#define __DATAWINDOW_H_FDDAB8D0__

#include "../../../JuceLibraryCode/JuceHeader.h"
#include "../Editors/VisualizerEditor.h"

/**
Expand All @@ -34,21 +33,41 @@
@see DataViewport
*/
class VisualizerEditor;

class DataWindow : public DocumentWindow
{
public:
DataWindow(Button* button, String name);
DataWindow(Button* button, VisualizerEditor* editor, String name);
~DataWindow();

void closeButtonPressed();
class Listener
{
public:
/** Destructor. */
virtual ~Listener() {}

/** Called when the window is closed. */
virtual void windowClosed () = 0;
};

/**
* @brief Registers a listener to receive event when this is closed. If
* the listener is already registered, this will not register it
* again.
*/
void addListener (Listener* newListener);

/**
* @brief Removes a previously-registered DataWindow listener
*/
void removeListener (Listener* listener);

private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DataWindow);

Button* controlButton;
VisualizerEditor* vizEditor;
ListenerList<Listener> closeWindowListeners;
};


Expand Down

0 comments on commit 512ba04

Please sign in to comment.