Files
hot-step-cpp-ROCm/engine/vendor/vst3sdk/vstgui4/vstgui/uidescription/editing/uigradientscontroller.cpp
T
2026-08-16 18:24:52 +07:00

890 lines
30 KiB
C++

// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "uigradientscontroller.h"
#if VSTGUI_LIVE_EDITING
#include "uibasedatasource.h"
#include "iaction.h"
#include "uieditcontroller.h"
#include "uidialogcontroller.h"
#include "uicolorchoosercontroller.h"
#include "uicolor.h"
#include "../../lib/cgradientview.h"
#include "../../lib/ifocusdrawing.h"
#include "../../lib/cgraphicspath.h"
#include "../../lib/cdrawcontext.h"
#include "../../lib/events.h"
#include "../../lib/controls/coptionmenu.h"
#include <algorithm>
namespace VSTGUI {
//------------------------------------------------------------------------
struct IUIColorStopEditViewListener
{
virtual ~IUIColorStopEditViewListener () noexcept = default;
virtual void onChange () = 0;
};
//------------------------------------------------------------------------
class UIColorStopEditView
: public CView,
protected ListenerProvider<UIColorStopEditView, IUIColorStopEditViewListener>,
public IFocusDrawing,
public UIColorListenerAdapter
{
public:
UIColorStopEditView (UIColor* editColor);
~UIColorStopEditView () override;
void setGradient (CGradient* gradient);
void selectNextColorStop ();
void selectPrevColorStop ();
void setEditColor (CColor color);
void setCurrentStartOffset (double startOffset);
double getSelectedColorStart () const { return editStartOffset; }
const GradientColorStopMap& getColorStopMap () const { return colorStopMap; }
using ListenerProvider<UIColorStopEditView, IUIColorStopEditViewListener>::registerListener;
using ListenerProvider<UIColorStopEditView, IUIColorStopEditViewListener>::unregisterListener;
private:
void draw (CDrawContext* context) override;
bool drawFocusOnTop () override;
bool getFocusPath (CGraphicsPath& outPath) override;
void onKeyboardEvent (KeyboardEvent& event) override;
CMouseEventResult onMouseDown (CPoint& where, const CButtonState& buttons) override;
CMouseEventResult onMouseUp (CPoint& where, const CButtonState& buttons) override;
CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override;
void uiColorChanged (UIColor* c) override;
double gradientStartPosFromMousePos (const CPoint& where) const;
void addColorStop (double startOffset);
void removeColorStop (double startOffset);
SharedPointer<UIColor> editColor;
SharedPointer<CGradient> gradient;
GradientColorStopMap colorStopMap;
double editStartOffset;
CCoord stopWidth;
double mouseDownStartPosOffset;
};
//----------------------------------------------------------------------------------------------------
UIColorStopEditView::UIColorStopEditView (UIColor* editColor)
: CView (CRect (0, 0, 0, 0))
, editColor (editColor)
, editStartOffset (-1.)
, mouseDownStartPosOffset (0.)
{
editColor->registerListener (this);
setWantsFocus (true);
stopWidth = 12.;
}
//----------------------------------------------------------------------------------------------------
UIColorStopEditView::~UIColorStopEditView ()
{
editColor->unregisterListener (this);
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::selectNextColorStop ()
{
auto pos = colorStopMap.find (getSelectedColorStart ());
pos++;
if (pos == colorStopMap.end ())
{
pos = colorStopMap.begin ();
}
editStartOffset = pos->first;
*editColor = pos->second;
forEachListener ([] (IUIColorStopEditViewListener* l) { l->onChange (); });
invalid ();
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::selectPrevColorStop ()
{
auto pos = colorStopMap.find (getSelectedColorStart ());
if (pos == colorStopMap.begin ())
pos = colorStopMap.end ();
pos--;
editStartOffset = pos->first;
*editColor = pos->second;
forEachListener ([] (IUIColorStopEditViewListener* l) { l->onChange (); });
invalid ();
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::setEditColor (CColor color)
{
if (editColor)
{
editColor->beginEdit ();
*editColor = color;
editColor->endEdit ();
}
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::setCurrentStartOffset (double startOffset)
{
if (startOffset < 0.)
startOffset = 0.;
else if (startOffset > 1.)
startOffset = 1.;
auto pos = colorStopMap.find (getSelectedColorStart ());
if (pos != colorStopMap.end () && pos->first != startOffset)
{
CColor color = pos->second;
colorStopMap.erase (pos);
colorStopMap.emplace (startOffset, color);
editStartOffset = startOffset;
forEachListener ([] (IUIColorStopEditViewListener* l) { l->onChange (); });
invalid ();
}
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::addColorStop (double startOffset)
{
colorStopMap.emplace (startOffset, editColor->base ());
editStartOffset = startOffset;
forEachListener ([] (IUIColorStopEditViewListener* l) { l->onChange (); });
invalid ();
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::removeColorStop (double startOffset)
{
if (colorStopMap.size () < 3)
return;
if (getSelectedColorStart () == startOffset)
selectNextColorStop ();
colorStopMap.erase (startOffset);
forEachListener ([] (IUIColorStopEditViewListener* l) { l->onChange (); });
invalid ();
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::onKeyboardEvent (KeyboardEvent& event)
{
if (event.type != EventType::KeyDown)
return;
switch (event.virt)
{
case VirtualKey::Left:
{
if (event.modifiers.empty ())
{
selectPrevColorStop ();
event.consumed = true;
}
else if (event.modifiers.is (ModifierKey::Alt))
{
setCurrentStartOffset (editStartOffset - 0.001);
event.consumed = true;
}
break;
}
case VirtualKey::Right:
{
if (event.modifiers.empty ())
{
selectNextColorStop ();
event.consumed = true;
}
else if (event.modifiers.is(ModifierKey::Alt))
{
setCurrentStartOffset (editStartOffset + 0.001);
event.consumed = true;
}
break;
}
case VirtualKey::Back:
{
if (event.modifiers.empty ())
{
removeColorStop (getSelectedColorStart ());
event.consumed = true;
}
break;
}
default:
break;
}
}
//----------------------------------------------------------------------------------------------------
double UIColorStopEditView::gradientStartPosFromMousePos (const CPoint& where) const
{
return (where.x - (getViewSize ().left + (stopWidth / 2.))) / (getWidth () - stopWidth);
}
//----------------------------------------------------------------------------------------------------
CMouseEventResult UIColorStopEditView::onMouseDown (CPoint& where, const CButtonState& buttons)
{
if (buttons.isDoubleClick ())
{
double pos = gradientStartPosFromMousePos (where);
if (pos >= 0. && pos <= 1.)
{
addColorStop (pos);
}
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}
else if (buttons.isLeftButton ())
{
getFrame ()->setFocusView (this);
double pos = gradientStartPosFromMousePos (where);
double range = (stopWidth / getWidth ()) / 2.;
for (auto& colorStop : colorStopMap)
{
if (pos >= colorStop.first - range && pos <= colorStop.first + range)
{
if (buttons.getModifierState () == kAlt)
{
removeColorStop (colorStop.first);
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}
if (editStartOffset != colorStop.first)
{
editStartOffset = colorStop.first;
*editColor = colorStop.second;
forEachListener ([] (IUIColorStopEditViewListener* l) { l->onChange (); });
}
mouseDownStartPosOffset = pos - editStartOffset;
return kMouseEventHandled;
}
}
}
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}
//----------------------------------------------------------------------------------------------------
CMouseEventResult UIColorStopEditView::onMouseUp (CPoint& where, const CButtonState& buttons)
{
return kMouseEventHandled;
}
//----------------------------------------------------------------------------------------------------
CMouseEventResult UIColorStopEditView::onMouseMoved (CPoint& where, const CButtonState& buttons)
{
if (buttons.isLeftButton ())
{
double pos = gradientStartPosFromMousePos (where) - mouseDownStartPosOffset;
setCurrentStartOffset (pos);
return kMouseEventHandled;
}
return kMouseEventNotHandled;
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::uiColorChanged (UIColor* c)
{
invalid ();
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::setGradient (CGradient* inGradient)
{
colorStopMap = inGradient->getColorStops ();
auto it = colorStopMap.find (editStartOffset);
if (it == colorStopMap.end ())
editStartOffset = colorStopMap.begin ()->first;
gradient = inGradient;
}
//----------------------------------------------------------------------------------------------------
void UIColorStopEditView::draw (CDrawContext* context)
{
CDrawContext::Transform t (*context, CGraphicsTransform ().translate (getViewSize ().left, getViewSize ().top));
context->setDrawMode (kAliasing);
SharedPointer<CGraphicsPath> gradientPath = owned (context->createGraphicsPath ());
gradientPath->addRect (CRect (stopWidth / 2., 0., getWidth () - stopWidth / 2., getHeight ()));
context->fillLinearGradient (gradientPath, *gradient, CPoint (stopWidth / 2., 0), CPoint (getWidth () - stopWidth / 2, 0));
CCoord width = getWidth () - stopWidth;
CCoord height = (getHeight () / 2.);
SharedPointer<CGraphicsPath> path = owned (context->createGraphicsPath ());
path->beginSubpath (CPoint (stopWidth / 2., 0));
path->addLine (CPoint (0, height));
path->addLine (CPoint (stopWidth, height));
path->closeSubpath ();
context->setFrameColor (kBlackCColor);
context->setLineWidth (1.1);
context->setLineStyle (kLineSolid);
context->setDrawMode (kAntiAliasing);
CColor selectedColor;
context->setGlobalAlpha (0.5f);
for (auto& colorStop : colorStopMap)
{
if (colorStop.first == getSelectedColorStart ())
{
selectedColor = colorStop.second;
}
else
{
CGraphicsTransform offset;
offset.translate (colorStop.first * width, getHeight () / 4.);
if (colorStop.second.getLuma () < 127)
context->setFrameColor (kWhiteCColor);
else
context->setFrameColor (kBlackCColor);
context->drawGraphicsPath (path, CDrawContext::kPathStroked, &offset);
}
}
context->setGlobalAlpha (1.f);
if (getSelectedColorStart () >= 0.)
{
CGraphicsTransform offset;
offset.translate (getSelectedColorStart () * width, getHeight() / 4.);
if (selectedColor.getLuma () < 127)
context->setFrameColor (kWhiteCColor);
else
context->setFrameColor (kBlackCColor);
context->setFillColor (selectedColor);
context->drawGraphicsPath (path, CDrawContext::kPathFilled, &offset);
context->drawGraphicsPath (path, CDrawContext::kPathStroked, &offset);
}
}
//----------------------------------------------------------------------------------------------------
bool UIColorStopEditView::drawFocusOnTop ()
{
return false;
}
//----------------------------------------------------------------------------------------------------
bool UIColorStopEditView::getFocusPath (CGraphicsPath& outPath)
{
CRect r (getViewSize ());
r.inset (stopWidth / 2 - 1, -1);
outPath.addRect (r);
r.inset (2, 2);
outPath.addRect (r);
return true;
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
class UIGradientEditorController : public NonAtomicReferenceCounted,
public IDialogController,
public UIColorListenerAdapter,
public IUIColorStopEditViewListener,
public IController
{
public:
UIGradientEditorController (const std::string& gradientName, CGradient* gradient, UIDescription* description, IActionPerformer* actionPerformer);
~UIGradientEditorController () override;
void valueChanged (CControl* pControl) override;
CView* verifyView (CView* view, const UIAttributes& attributes, const IUIDescription* description) override;
CView* createView (const UIAttributes& attributes, const IUIDescription* description) override;
IController* createSubController (UTF8StringPtr name, const IUIDescription* description) override;
void onDialogButton1Clicked (UIDialogController*) override;
void onDialogButton2Clicked (UIDialogController*) override;
void onDialogShow (UIDialogController*) override;
protected:
enum
{
kApplyTag = 1,
kPositionTag = 2,
kFunctionMenuTag = 3,
};
void uiColorChanged (UIColor* c) override;
void onChange () override;
void apply ();
void updatePositionEdit ();
SharedPointer<UIDescription> editDescription;
SharedPointer<UIColorStopEditView> colorStopEditView;
SharedPointer<CGradient> gradient;
SharedPointer<UIColor> editColor;
CTextEdit* positionEdit {nullptr};
IActionPerformer* actionPerformer;
std::string gradientName;
};
//----------------------------------------------------------------------------------------------------
UIGradientEditorController::UIGradientEditorController (const std::string& gradientName, CGradient* gradient, UIDescription* description, IActionPerformer* actionPerformer)
: editDescription(description)
, gradient (gradient)
, editColor (makeOwned<UIColor> ())
, actionPerformer(actionPerformer)
, gradientName (gradientName)
{
*editColor = gradient->getColorStops ().begin ()->second;
editColor->registerListener (this);
}
//----------------------------------------------------------------------------------------------------
UIGradientEditorController::~UIGradientEditorController ()
{
colorStopEditView->unregisterListener (this);
editColor->unregisterListener (this);
}
//----------------------------------------------------------------------------------------------------
void UIGradientEditorController::apply ()
{
CGradient* g = editDescription->getGradient (gradientName.data ());
if (g->getColorStops () != gradient->getColorStops ())
actionPerformer->performGradientChange (gradientName.data (), gradient);
}
//----------------------------------------------------------------------------------------------------
void UIGradientEditorController::updatePositionEdit ()
{
if (positionEdit && colorStopEditView)
positionEdit->setValue (static_cast<float> (colorStopEditView->getSelectedColorStart ()));
}
//----------------------------------------------------------------------------------------------------
void UIGradientEditorController::uiColorChanged (UIColor* c)
{
auto colorStopMap = gradient->getColorStops (); // create a copy
auto it = colorStopMap.find (colorStopEditView->getSelectedColorStart ());
if (it != colorStopMap.end () && it->second != editColor->base ())
{
it->second = editColor->base ();
gradient = CGradient::create (colorStopMap);
colorStopEditView->setGradient (gradient);
updatePositionEdit ();
}
}
//----------------------------------------------------------------------------------------------------
void UIGradientEditorController::onChange ()
{
gradient = CGradient::create (colorStopEditView->getColorStopMap ());
colorStopEditView->setGradient (gradient);
updatePositionEdit ();
}
//------------------------------------------------------------------------
void UIGradientEditorController::onDialogButton1Clicked (UIDialogController*)
{
apply ();
}
//------------------------------------------------------------------------
void UIGradientEditorController::onDialogButton2Clicked (UIDialogController*)
{
}
//------------------------------------------------------------------------
void UIGradientEditorController::onDialogShow (UIDialogController*)
{
}
//----------------------------------------------------------------------------------------------------
IController* UIGradientEditorController::createSubController (UTF8StringPtr name, const IUIDescription* description)
{
if (UTF8StringView (name) == "ColorChooserController")
{
return new UIColorChooserController (this, editColor);
}
return nullptr;
}
//----------------------------------------------------------------------------------------------------
void UIGradientEditorController::valueChanged (CControl* pControl)
{
switch (pControl->getTag ())
{
case kApplyTag:
{
if (pControl->getValue () > 0.f)
apply ();
break;
}
case kPositionTag:
{
colorStopEditView->setCurrentStartOffset (pControl->getValue ());
break;
}
}
}
//------------------------------------------------------------------------
SharedPointer<COptionMenu> createColorMenu (IUIDescription& desc,
const std::function<void (CColor)>& callback)
{
std::list<const std::string*> names;
desc.collectColorNames (names);
if (names.empty ())
return {};
auto menu = makeOwned<COptionMenu> ();
std::for_each (names.begin (), names.end (), [&] (const auto& el) {
CColor color;
if (desc.getColor (el->data (), color))
{
auto item = new CCommandMenuItem (UTF8String (*el));
item->setActions ([callback, color] (auto item) { callback (color); });
item->setIcon (createColorIcon (color));
menu->addEntry (item);
}
});
return menu;
}
//----------------------------------------------------------------------------------------------------
CView* UIGradientEditorController::verifyView (CView* view, const UIAttributes& attributes, const IUIDescription* description)
{
if (auto control = dynamic_cast<CTextEdit*>(view))
{
if (control->getTag () == kPositionTag)
{
control->setStringToValueFunction ([] (UTF8StringPtr txt, float& result, CTextEdit*) {
UTF8StringView t (txt);
result = t.toFloat ();
return true;
});
positionEdit = control;
updatePositionEdit ();
}
}
else if (auto menu = dynamic_cast<COptionMenu*> (view))
{
if (menu->getTag () == kFunctionMenuTag)
{
auto item = new CCommandMenuItem ({"Select Next Color Stop"});
item->setActions ([this] (auto) {
if (colorStopEditView)
{
colorStopEditView->selectNextColorStop ();
}
});
menu->addEntry (item);
item = new CCommandMenuItem ({"Select Previous Color Stop"});
item->setActions ([this] (auto) {
if (colorStopEditView)
{
colorStopEditView->selectPrevColorStop ();
}
});
menu->addEntry (item);
menu->addSeparator ();
auto descColorMenu = createColorMenu (*editDescription, [this] (auto color) {
if (colorStopEditView)
{
colorStopEditView->setEditColor (color);
}
});
menu->addEntry (descColorMenu, "Set to Description Color");
auto cssColorMenu = createCSSColorMenu ([this] (auto color) {
if (colorStopEditView)
{
colorStopEditView->setEditColor (color);
}
});
menu->addEntry (cssColorMenu, "Set to CSS Color");
}
}
return view;
}
//----------------------------------------------------------------------------------------------------
CView* UIGradientEditorController::createView (const UIAttributes& attributes, const IUIDescription* description)
{
const std::string* name = attributes.getAttributeValue (IUIDescription::kCustomViewName);
if (name)
{
if (*name == "ColorStopEditView")
{
colorStopEditView = new UIColorStopEditView (editColor);
colorStopEditView->setGradient (gradient);
colorStopEditView->registerListener (this);
return colorStopEditView;
}
}
return nullptr;
}
//----------------------------------------------------------------------------------------------------
class UIGradientsDataSource : public UIBaseDataSource
{
public:
UIGradientsDataSource (UIDescription* description, IActionPerformer* actionPerformer, GenericStringListDataBrowserSourceSelectionChanged* delegate);
~UIGradientsDataSource () override = default;
CGradient* getSelectedGradient ();
std::string getSelectedGradientName ();
protected:
void onUIDescGradientChanged (UIDescription* desc) override;
void update () override;
void getNames (std::list<const std::string*>& names) override;
bool addItem (UTF8StringPtr name) override;
bool removeItem (UTF8StringPtr name) override;
bool performNameChange (UTF8StringPtr oldName, UTF8StringPtr newName) override;
UTF8StringPtr getDefaultsName () override { return "UIGradientsDataSource"; }
void dbDrawCell (CDrawContext* context, const CRect& size, int32_t row, int32_t column, int32_t flags, CDataBrowser* browser) override;
void dbCellSetupTextEdit (int32_t row, int32_t column, CTextEdit* control, CDataBrowser* browser) override;
CMouseEventResult dbOnMouseDown (const CPoint& where, const CButtonState& buttons, int32_t row, int32_t column, CDataBrowser* browser) override;
CCoord getGradientIconWidth ();
};
//----------------------------------------------------------------------------------------------------
UIGradientsDataSource::UIGradientsDataSource (
UIDescription* description, IActionPerformer* actionPerformer,
GenericStringListDataBrowserSourceSelectionChanged* delegate)
: UIBaseDataSource (description, actionPerformer, delegate)
{
}
//----------------------------------------------------------------------------------------------------
void UIGradientsDataSource::onUIDescGradientChanged (UIDescription* desc)
{
onUIDescriptionUpdate ();
}
//----------------------------------------------------------------------------------------------------
CGradient* UIGradientsDataSource::getSelectedGradient ()
{
int32_t selectedRow = dataBrowser ? dataBrowser->getSelectedRow() : CDataBrowser::kNoSelection;
if (selectedRow != CDataBrowser::kNoSelection && selectedRow < (int32_t)names.size ())
return description->getGradient (names.at (static_cast<uint32_t> (selectedRow)).data ());
return nullptr;
}
//------------------------------------------------------------------------
std::string UIGradientsDataSource::getSelectedGradientName ()
{
int32_t selectedRow = dataBrowser ? dataBrowser->getSelectedRow() : CDataBrowser::kNoSelection;
if (selectedRow != CDataBrowser::kNoSelection && selectedRow < (int32_t)names.size ())
return names[static_cast<uint32_t> (selectedRow)].getString ();
return "";
}
//----------------------------------------------------------------------------------------------------
void UIGradientsDataSource::getNames (std::list<const std::string*>& names)
{
description->collectGradientNames (names);
}
//----------------------------------------------------------------------------------------------------
bool UIGradientsDataSource::addItem (UTF8StringPtr name)
{
actionPerformer->performGradientChange (name, CGradient::create (0, 1, kWhiteCColor, kBlackCColor));
return true;
}
//----------------------------------------------------------------------------------------------------
bool UIGradientsDataSource::removeItem (UTF8StringPtr name)
{
actionPerformer->performGradientChange (name, nullptr, true);
return true;
}
//----------------------------------------------------------------------------------------------------
void UIGradientsDataSource::update ()
{
UIBaseDataSource::update ();
if (dataBrowser)
{
dbSelectionChanged (dataBrowser);
dataBrowser->invalid ();
}
}
//----------------------------------------------------------------------------------------------------
CCoord UIGradientsDataSource::getGradientIconWidth ()
{
return dataBrowser ? dbGetRowHeight (dataBrowser) * 2. : 0.;
}
//----------------------------------------------------------------------------------------------------
CMouseEventResult UIGradientsDataSource::dbOnMouseDown (const CPoint& where, const CButtonState& buttons, int32_t row, int32_t column, CDataBrowser* browser)
{
if (buttons.isDoubleClick () && row >= 0 && row < static_cast<int32_t> (names.size ()))
{
auto r = browser->getCellBounds ({row, column});
r.left = r.right - getGradientIconWidth ();
if (r.pointInside (where))
{
delegate->dbRowDoubleClick (row, this);
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}
}
return UIBaseDataSource::dbOnMouseDown (where, buttons, row, column, browser);
}
//----------------------------------------------------------------------------------------------------
void UIGradientsDataSource::dbDrawCell (CDrawContext* context, const CRect& size, int32_t row, int32_t column, int32_t flags, CDataBrowser* browser)
{
GenericStringListDataBrowserSource::drawRowBackground (context, size, row, flags, browser);
CRect r (size);
r.right -= getGradientIconWidth ();
GenericStringListDataBrowserSource::drawRowString (context, r, row, flags, browser);
CGradient* gradient = nullptr;
if ((gradient = description->getGradient (names.at (static_cast<uint32_t> (row)).data ())))
{
context->setFrameColor (kBlackCColor);
context->setLineWidth (context->getHairlineSize ());
context->setLineStyle (kLineSolid);
context->setDrawMode (kAliasing);
r = size;
r.left = r.right - (getGradientIconWidth ());
r.offset (-0.5, -0.5);
r.inset (3, 2);
SharedPointer<CGraphicsPath> path = owned (context->createGraphicsPath ());
path->addRect (r);
path->closeSubpath ();
context->fillLinearGradient (path, *gradient, r.getTopLeft (), r.getTopRight ());
context->drawGraphicsPath (path, CDrawContext::kPathStroked);
}
}
//----------------------------------------------------------------------------------------------------
void UIGradientsDataSource::dbCellSetupTextEdit (int32_t row, int32_t column, CTextEdit* control, CDataBrowser* browser)
{
UIBaseDataSource::dbCellSetupTextEdit(row, column, control, browser);
CRect r (control->getViewSize ());
r.right -= getGradientIconWidth ();
control->setViewSize (r);
}
//----------------------------------------------------------------------------------------------------
bool UIGradientsDataSource::performNameChange (UTF8StringPtr oldName, UTF8StringPtr newName)
{
actionPerformer->performGradientNameChange (oldName, newName);
return true;
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
UIGradientsController::UIGradientsController (IController* baseController, UIDescription* description, IActionPerformer* actionPerformer)
: DelegationController (baseController)
, editDescription (description)
, actionPerformer (actionPerformer)
, dataSource (nullptr)
{
dataSource = new UIGradientsDataSource (editDescription, actionPerformer, this);
UIEditController::setupDataSource (dataSource);
}
//----------------------------------------------------------------------------------------------------
UIGradientsController::~UIGradientsController ()
{
dataSource->forget ();
}
//----------------------------------------------------------------------------------------------------
CView* UIGradientsController::createView (const UIAttributes& attributes, const IUIDescription* description)
{
const std::string* name = attributes.getAttributeValue (IUIDescription::kCustomViewName);
if (name)
{
if (*name == "GradientsBrowser")
{
CDataBrowser* dataBrowser = new CDataBrowser (CRect (0, 0, 0, 0), dataSource, CDataBrowser::kDrawRowLines|CScrollView::kHorizontalScrollbar|CScrollView::kVerticalScrollbar);
return dataBrowser;
}
}
return DelegationController::createView (attributes, description);
}
//----------------------------------------------------------------------------------------------------
CView* UIGradientsController::verifyView (CView* view, const UIAttributes& attributes, const IUIDescription* description)
{
CControl* control = dynamic_cast<CControl*> (view);
if (control)
{
auto searchField = dynamic_cast<CSearchTextEdit*> (control);
if (searchField && searchField->getTag () == kSearchTag)
{
dataSource->setSearchFieldControl (searchField);
return searchField;
}
else if (control->getTag () == kEditTag)
{
editButton = control;
editButton->setMouseEnabled (false);
}
}
return controller->verifyView (view, attributes, description);
}
//----------------------------------------------------------------------------------------------------
IControlListener* UIGradientsController::getControlListener (UTF8StringPtr name)
{
return this;
}
//----------------------------------------------------------------------------------------------------
void UIGradientsController::valueChanged (CControl* pControl)
{
switch (pControl->getTag ())
{
case kAddTag:
{
if (pControl->getValue () == pControl->getMax ())
dataSource->add ();
break;
}
case kRemoveTag:
{
if (pControl->getValue () == pControl->getMax ())
dataSource->remove ();
break;
}
case kEditTag:
{
if (pControl->getValue () == pControl->getMax ())
showEditDialog ();
break;
}
}
}
//----------------------------------------------------------------------------------------------------
void UIGradientsController::dbSelectionChanged (int32_t selectedRow, GenericStringListDataBrowserSource* source)
{
if (dataSource)
{
CGradient* gradient = dataSource->getSelectedGradient ();
if (editButton)
editButton->setMouseEnabled (gradient ? true : false);
}
}
//----------------------------------------------------------------------------------------------------
void UIGradientsController::dbRowDoubleClick (int32_t row, GenericStringListDataBrowserSource* source)
{
showEditDialog ();
}
//----------------------------------------------------------------------------------------------------
void UIGradientsController::showEditDialog ()
{
UIDialogController* dc = new UIDialogController (this, editButton->getFrame ());
auto fsController = makeOwned<UIGradientEditorController> (
dataSource->getSelectedGradientName (), dataSource->getSelectedGradient (), editDescription,
actionPerformer);
dc->run ("gradient.editor", "Gradient Editor", "OK", "Cancel", fsController,
UIEditController::getEditorDescription ());
}
} // VSTGUI
#endif // VSTGUI_LIVE_EDITING