Skip to content
Snippets Groups Projects
Commit 6217fdd9 authored by Septen's avatar Septen
Browse files

Implemented TiledButtonGroupManager.

* This class position buttons inside itself
  as tiles and has feature which gives
  us fuzzy button selection possibility via
  mouse drag (or SHIFT+mouse drag for deselection).
parent 37d28e2c
No related branches found
No related tags found
No related merge requests found
......@@ -91,7 +91,6 @@ void ButtonGroupManager::addButton (Button* newButton)
if (m_isRadioButtonMode)
{
newButton->setClickingTogglesState (true);
newButton->setRadioGroupId (1);
}
......
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2016 Open Ephys
------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "TiledButtonGroupManager.h"
#include "../MaterialButtonLookAndFeel.h"
#include <algorithm>
TiledButtonGroupManager::TiledButtonGroupManager()
: m_firstSelectedButtonIdx (-1)
, m_lastSelectedButtonIdx (-1)
, m_isToggleOnMode (true)
, m_isDraggingMouseNow (false)
, m_isSelectButtonsByDragging (false)
, m_buttonWidth (0)
, m_buttonHeight (0)
{
setRadioButtonMode (false);
setButtonsLookAndFeel (new MaterialButtonLookAndFeel);
}
void TiledButtonGroupManager::resized()
{
const int width = getWidth();
if (! width)
return;
const int minPadding = 5;
const int numButtonsInTheRow = width / (m_buttonWidth + minPadding);
const int padding = jmax (minPadding, (width - numButtonsInTheRow * m_buttonWidth) / (numButtonsInTheRow - 1));
juce::Rectangle<int> buttonBounds (0, 0, m_buttonWidth, m_buttonHeight);
const int numButtons = m_buttons.size();
for (int i = 0; i < numButtons; ++i)
{
m_buttons[i]->setBounds (buttonBounds);
// Go to the next row
if ( (i + 1) % numButtonsInTheRow == 0)
{
buttonBounds.setX (0);
buttonBounds.translate (0, m_buttonHeight + padding);
}
// Go to the next column
else
{
buttonBounds.translate (m_buttonWidth + padding, 0);
}
}
}
void TiledButtonGroupManager::mouseDown (const MouseEvent& e)
{
}
void TiledButtonGroupManager::mouseUp (const MouseEvent& e)
{
m_isDraggingMouseNow = false;
m_firstSelectedButtonIdx = -1;
m_lastSelectedButtonIdx = -1;
}
void TiledButtonGroupManager::mouseDrag (const MouseEvent& e)
{
if (! m_isSelectButtonsByDragging)
return;
m_isDraggingMouseNow = true;
// Is shift + drag mouse action occurs, then we should toggle on buttons;
// Otherwise - toggle off.
m_isToggleOnMode = ! e.mods.isShiftDown();
const int currentButtonIdx = getIndexOfButtonAtPosition (e.getEventRelativeTo (this).getPosition());
// Remember the first button on which we started dragging
if (m_firstSelectedButtonIdx == -1
&& m_lastSelectedButtonIdx == -1
&& currentButtonIdx >= 0)
{
m_firstSelectedButtonIdx = currentButtonIdx;
}
if (currentButtonIdx != -1
&& currentButtonIdx != m_lastSelectedButtonIdx)
{
m_lastSelectedButtonIdx = currentButtonIdx;
// Get the indices of range which we should to select (get FROM index and TO index)
const int fromIndex = jmin (m_firstSelectedButtonIdx, m_lastSelectedButtonIdx);
const int toIndex = jmax (m_firstSelectedButtonIdx, m_lastSelectedButtonIdx);
for (int i = fromIndex; i <= toIndex; ++i)
{
// Trigger click only if the button still isn't selected/deselected (according to the SHIFT holds)
if (m_buttons[i]->getToggleState() != m_isToggleOnMode)
// Trigger click in the button, this will call buttonClicked() method, where we will
m_buttons[i]->triggerClick();
}
}
}
void TiledButtonGroupManager::buttonClicked (Button* buttonThatWasClicked)
{
// Fast selection enabled and we dragging mouse now to select
if (m_isSelectButtonsByDragging
&& m_isDraggingMouseNow)
{
buttonThatWasClicked->setToggleState (m_isToggleOnMode, dontSendNotification);
}
// Default selection
else
{
buttonThatWasClicked->setToggleState (! buttonThatWasClicked->getToggleState(), dontSendNotification);
}
// Notify the listener
ButtonGroupManager::buttonClicked (buttonThatWasClicked);
}
void TiledButtonGroupManager::addButton (Button* newButton)
{
ButtonGroupManager::addButton (newButton);
// Disable default clicking on button
newButton->addMouseListener (this, false);
}
int TiledButtonGroupManager::getIndexOfButtonAtPosition (Point<int> position)
{
const int numButtons = m_buttons.size();
for (int i = 0; i < numButtons; ++i)
{
if (m_buttons[i]->getBounds().contains (position))
return i;
}
return -1;
}
bool TiledButtonGroupManager::isFastSelectionModeEnabled()
{
return m_isSelectButtonsByDragging;
}
void TiledButtonGroupManager::setFastSelectionModeEnabled (bool isFastSelectionMode)
{
m_isSelectButtonsByDragging = isFastSelectionMode;
}
void TiledButtonGroupManager::setButtonSize (int buttonWidth, int buttonHeight)
{
m_buttonWidth = buttonWidth;
m_buttonHeight = buttonHeight;
std::for_each (m_buttons.begin(), m_buttons.end(),
[=] (Button* button) { button->setSize (buttonWidth, buttonHeight); });
resized();
}
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2016 Open Ephys
------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TILEDBUTTONGROUPMANAGER_H_INCLUDED
#define TILEDBUTTONGROUPMANAGER_H_INCLUDED
#include "../../../JuceLibraryCode/JuceHeader.h"
#include "../../Processors/PluginManager/OpenEphysPlugin.h"
#include "ButtonGroupManager.h"
/**
This class provides possibility to store buttons in several rows having tile-structure.
It is responsible for positioning of buttons, any animations during resizing.
It also have "Fast select" feature which allows as to quickly select many buttons
using mouse drag selection. (mouse drag - to select, shift+mouse drag to deselect)
*/
class PLUGIN_API TiledButtonGroupManager : public ButtonGroupManager
{
public:
TiledButtonGroupManager();
// Component methods
// ===========================================================
void resized() override;
void mouseDown (const MouseEvent& e) override;
void mouseUp (const MouseEvent& e) override;
void mouseDrag (const MouseEvent& e) override;
// ===========================================================
// Button::Listener methods
// ===========================================================
void buttonClicked (Button* buttonThatWasClicked);
/** Returns whether fast selection mode (toggle on or off buttons by dragging mouse) is enabled or not */
bool isFastSelectionModeEnabled();
/** Sets whether fast selection mode (toggle on or off buttons by dragging mouse) will be enabled */
void setFastSelectionModeEnabled (bool isFastSelectionMode);
/** Sets the size of each button */
void setButtonSize (int buttonWidth, int buttonHeight);
/** Add button to the array of buttons to manage it.
This class controls ownership of buttons.
*/
void addButton (Button* newButton);
private:
// Returns the index of button at given position.
// If nothing found at this position - returns -1.
int getIndexOfButtonAtPosition (Point<int> position);
int m_buttonWidth;
int m_buttonHeight;
int m_firstSelectedButtonIdx;
int m_lastSelectedButtonIdx;
bool m_isToggleOnMode;
bool m_isDraggingMouseNow;
bool m_isSelectButtonsByDragging;
// ===========================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TiledButtonGroupManager)
};
#endif //TILEDBUTTONGROUPMANAGER_H_INCLUDED
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment