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

957 lines
33 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 "uitemplatecontroller.h"
#if VSTGUI_LIVE_EDITING
#include "../iviewfactory.h"
#include "../uiattributes.h"
#include "../viewcreator/viewcreator.h"
#include "../../lib/controls/ctextedit.h"
#include "../../lib/controls/coptionmenu.h"
#include "../../lib/controls/cscrollbar.h"
#include "../../lib/algorithm.h"
#include "../../lib/cgraphicspath.h"
#include "../../lib/cdropsource.h"
#include "../../lib/coffscreencontext.h"
#include "../../lib/dragging.h"
#include "../../lib/malloc.h"
#include "uieditcontroller.h"
#include "uiselection.h"
#include "uiundomanager.h"
#include "uiactions.h"
#include "uieditmenucontroller.h"
#include <cassert>
namespace VSTGUI {
//----------------------------------------------------------------------------------------------------
class UINavigationDataSource : public GenericStringListDataBrowserSource
{
public:
UINavigationDataSource (GenericStringListDataBrowserSourceSelectionChanged* delegate)
: GenericStringListDataBrowserSource (nullptr, delegate) { textInset.x = 4.; }
void dbOnKeyboardEvent (KeyboardEvent& event, CDataBrowser* browser) override
{
if (event.type == EventType::KeyDown &&
dynamic_cast<CTextEdit*> (browser->getFrame ()->getFocusView ()) == nullptr)
{
if (event.virt == VirtualKey::Left)
{
if (auto parent = browser->getParentView ()->asViewContainer ())
{
if (parent->advanceNextFocusView (browser, true))
{
browser->unselectAll ();
event.consumed = true;
return;
}
}
}
else if (event.virt == VirtualKey::Right)
{
if (auto parent = browser->getParentView ()->asViewContainer ())
{
if (parent->advanceNextFocusView (browser, false))
{
if (auto* focusView = browser->getFrame ()->getFocusView ())
{
auto* focusBrowser = dynamic_cast<CDataBrowser*>(focusView);
parent = focusView->getParentView ()->asViewContainer ();
while (!focusBrowser && parent != browser->getFrame ())
{
if (parent->getParentView () == nullptr)
break;
parent = parent->getParentView ()->asViewContainer ();
focusBrowser = dynamic_cast<CDataBrowser*> (parent);
}
if (focusBrowser)
{
if (focusBrowser->getSelectedRow () == CDataBrowser::kNoSelection)
focusBrowser->setSelectedRow (0);
}
}
event.consumed = true;
return;
}
}
}
}
GenericStringListDataBrowserSource::dbOnKeyboardEvent (event, browser);
}
virtual const UTF8String& getHeaderTitle () const { return headerTitle; }
void dbDrawHeader (CDrawContext* context, const CRect& size, int32_t column, int32_t flags, CDataBrowser* browser) override
{
context->setDrawMode (kAliasing);
if (!headerGradient)
{
headerGradient = UIEditController::getEditorDescription ()->getGradient ("shading.light");
UIEditController::getEditorDescription ()->getColor ("shading.light.frame", headerLineColor);
}
if (headerGradient)
{
if (auto path = owned (context->createGraphicsPath ()))
{
path->addRect (size);
context->fillLinearGradient (path, *headerGradient, CPoint (size.left, size.top), CPoint (size.left, size.bottom));
}
}
if (!getHeaderTitle ().empty ())
{
if (headerFont == nullptr)
{
headerFont = makeOwned<CFontDesc> (*drawFont);
headerFont->setStyle (kBoldFace);
headerFont->setSize (headerFont->getSize ()-1);
}
context->setFont (headerFont);
context->setFontColor (fontColor);
context->drawString (getHeaderTitle ().getPlatformString (), size, kCenterText);
}
auto hairlineSize = context->getHairlineSize ();
context->setLineWidth (hairlineSize);
context->setFrameColor (headerLineColor);
context->drawLine (CPoint (size.right-hairlineSize, size.top), CPoint (size.right-hairlineSize, size.bottom));
context->drawLine (CPoint (size.left, size.bottom), CPoint (size.right-hairlineSize, size.bottom));
}
static void drawTriangle (CDrawContext* context, const CRect& size)
{
if (auto path = owned (context->createGraphicsPath ()))
{
CRect r (size);
r.left = r.right - r.getHeight ();
r.inset (4, 4);
path->beginSubpath (r.getTopLeft ());
path->addLine (r.getBottomLeft ());
path->addLine (r.right, r.top + r.getHeight () / 2.);
path->closeSubpath ();
context->setFillColor (CColor (0, 0, 0, 30));
context->drawGraphicsPath (path);
}
}
protected:
mutable UTF8String headerTitle;
CColor headerLineColor {kBlackCColor};
SharedPointer<CFontDesc> headerFont;
SharedPointer<CGradient> headerGradient;
};
//----------------------------------------------------------------------------------------------------
class UITemplatesDataSource : public UINavigationDataSource
{
public:
UITemplatesDataSource (GenericStringListDataBrowserSourceSelectionChanged* delegate, UIDescription* description, IActionPerformer* actionPerformer, const std::string* templateName);
CMouseEventResult dbOnMouseDown (const CPoint& where, const CButtonState& buttons, int32_t row, int32_t column, CDataBrowser* browser) override;
void dbCellTextChanged (int32_t row, int32_t column, UTF8StringPtr newText, CDataBrowser* browser) override;
void dbCellSetupTextEdit (int32_t row, int32_t column, CTextEdit* textEditControl, CDataBrowser* browser) override;
void dbAttached (CDataBrowser* browser) override;
void dbDrawCell (CDrawContext* context, const CRect& size, int32_t row, int32_t column, int32_t flags, CDataBrowser* browser) override;
protected:
SharedPointer<UIDescription> description;
IActionPerformer* actionPerformer;
std::string firstSelectedTemplateName;
};
//----------------------------------------------------------------------------------------------------
class UIViewListDataSource : public UINavigationDataSource, public IUIUndoManagerListener
{
public:
UIViewListDataSource (CViewContainer* view, const IViewFactory* viewFactory, UISelection* selection, UIUndoManager* undoManager ,GenericStringListDataBrowserSourceSelectionChanged* delegate);
~UIViewListDataSource () override;
CViewContainer* getView () const { return view; }
CView* getSubview (int32_t index);
bool setSelectedView (CView* view, bool makeRowVisible = false);
UIViewListDataSource* getNext () const { return next; }
bool update (CViewContainer* vc);
void remove ();
protected:
UTF8String getViewDisplayString (CView* v) const
{
uint32_t outSize = 0;
if (v->getAttributeSize (UIViewCreator::ViewCreator::labelAttrID, outSize))
{
Buffer<char> buffer (outSize);
if (v->getAttribute (UIViewCreator::ViewCreator::labelAttrID, outSize, buffer.data (),
outSize))
{
return buffer.data ();
}
}
if (const auto* vfEditingSupport =
dynamic_cast<const IViewFactoryEditingSupport*> (viewFactory))
return vfEditingSupport->getViewDisplayName (v);
return {};
}
const UTF8String& getHeaderTitle () const override
{
headerTitle = "";
if (view)
{
headerTitle = getViewDisplayString (view);
if (headerTitle.empty () && view->getParentView ())
headerTitle = getViewDisplayString (view->getParentView ());
}
return headerTitle;
}
CCoord calculateSubViewWidth (CViewContainer* view) const;
void dbSelectionChanged (CDataBrowser* browser) override;
CMouseEventResult dbOnMouseDown (const CPoint& where, const CButtonState& buttons, int32_t row,
int32_t column, CDataBrowser* browser) override;
CMouseEventResult dbOnMouseMoved (const CPoint& where, const CButtonState& buttons, int32_t row,
int32_t column, CDataBrowser* browser) override;
void dbOnKeyboardEvent (KeyboardEvent& event, CDataBrowser* browser) override;
void dbDrawCell (CDrawContext* context, const CRect& size, int32_t row, int32_t column, int32_t flags, CDataBrowser* browser) override;
DragOperation dbOnDragEnterCell (int32_t row, int32_t column, const CPoint& where,
IDataPackage* drag, CDataBrowser* browser) override;
DragOperation dbOnDragMoveInCell (int32_t row, int32_t column, const CPoint& where,
IDataPackage* drag, CDataBrowser* browser) override;
void dbOnDragExitCell (int32_t row, int32_t column, IDataPackage* drag,
CDataBrowser* browser) override;
bool dbOnDropInCell (int32_t row, int32_t column, const CPoint& where, IDataPackage* drag,
CDataBrowser* browser) override;
// IUIUndoManagerListener
void onUndoManagerChange () override;
CViewContainer* view;
const IViewFactory* viewFactory;
UIViewListDataSource* next;
SharedPointer<UISelection> selection;
SharedPointer<UIUndoManager> undoManager;
CView* selectedView;
StringVector names;
std::vector<CView*> subviews;
bool inUpdate;
DragStartMouseObserver dragStartMouseObserver;
int32_t dragRow {-1};
int32_t dragDestinationRow {-1};
};
//----------------------------------------------------------------------------------------------------
UITemplateController::UITemplateController (IController* baseController, UIDescription* description, UISelection* selection, UIUndoManager* undoManager, IActionPerformer* actionPerformer)
: DelegationController (baseController)
, editDescription (description)
, selection (selection)
, undoManager (undoManager)
, actionPerformer (actionPerformer)
, templateView (nullptr)
, templateDataBrowser (nullptr)
, mainViewDataSource (nullptr)
, selectedTemplateName (nullptr)
{
editDescription->registerListener (this);
}
//----------------------------------------------------------------------------------------------------
UITemplateController::~UITemplateController ()
{
if (templateDataBrowser)
templateDataBrowser->unregisterViewListener (this);
if (mainViewDataSource)
mainViewDataSource->forget ();
editDescription->unregisterListener (this);
}
//----------------------------------------------------------------------------------------------------
void UITemplateController::setupDataBrowser (CDataBrowser* orignalBrowser, CDataBrowser* dataBrowser)
{
if (orignalBrowser)
{
dataBrowser->setTransparency (orignalBrowser->getTransparency ());
dataBrowser->setBackgroundColor (orignalBrowser->getBackgroundColor ());
dataBrowser->setAutosizeFlags (orignalBrowser->getAutosizeFlags ());
dataBrowser->setStyle (orignalBrowser->getStyle ());
dataBrowser->setScrollbarWidth (orignalBrowser->getScrollbarWidth ());
CScrollbar* sb1 = orignalBrowser->getHorizontalScrollbar ();
CScrollbar* sb2 = dataBrowser->getHorizontalScrollbar ();
if (sb1 && sb2)
{
sb2->setScrollerColor (sb1->getScrollerColor ());
sb2->setBackgroundColor (sb1->getBackgroundColor ());
sb2->setFrameColor (sb1->getFrameColor ());
}
sb1 = orignalBrowser->getVerticalScrollbar ();
sb2 = dataBrowser->getVerticalScrollbar ();
if (sb1 && sb2)
{
sb2->setScrollerColor (sb1->getScrollerColor ());
sb2->setBackgroundColor (sb1->getBackgroundColor ());
sb2->setFrameColor (sb1->getFrameColor ());
}
}
}
//----------------------------------------------------------------------------------------------------
void UITemplateController::selectTemplate (UTF8StringPtr name)
{
if (templateDataBrowser)
{
if (name == nullptr)
{
templateDataBrowser->unselectAll ();
return;
}
int32_t index = 0;
for (auto& templName : templateNames)
{
if (templName == name)
{
templateDataBrowser->setSelectedRow (index, true);
break;
}
index++;
}
}
}
//----------------------------------------------------------------------------------------------------
void UITemplateController::dbSelectionChanged (int32_t selectedRow, GenericStringListDataBrowserSource* source)
{
if (source->getStringList () == &templateNames)
{
UTF8String* newName = nullptr;
if (selectedRow == CDataBrowser::kNoSelection)
newName = nullptr;
else
newName = &templateNames[static_cast<uint32_t> (selectedRow)];
if ((newName == nullptr && selectedTemplateName != nullptr)
|| (newName != nullptr && selectedTemplateName == nullptr)
|| (newName != selectedTemplateName && *newName != *selectedTemplateName))
{
selectedTemplateName = newName;
auto attr = editDescription->getCustomAttributes ("UITemplateController", true);
if (attr)
{
attr->setAttribute ("SelectedTemplate", selectedTemplateName ? selectedTemplateName->getString () : "");
}
forEachListener ([] (IUITemplateControllerListener* l) { l->onTemplateSelectionChanged ();});
}
else if (templateView)
{
selection->setExclusive (templateView);
}
else
selection->clear ();
return;
}
}
//----------------------------------------------------------------------------------------------------
void UITemplateController::onUIDescTemplateChanged (UIDescription* desc)
{
if (!templateDataBrowser)
return;
auto dataSource = dynamic_cast<GenericStringListDataBrowserSource*>(templateDataBrowser->getDelegate ());
if (dataSource)
{
int32_t rowToSelect = templateDataBrowser->getSelectedRow ();
int32_t index = 0;
UTF8String selectedTemplateStr = selectedTemplateName ? selectedTemplateName->data () : "";
templateNames.clear ();
dataSource->setStringList (&templateNames);
std::list<const std::string*> tmp;
editDescription->collectTemplateViewNames (tmp);
tmp.sort (UIEditController::std__stringCompare);
for (auto& name : tmp)
{
templateNames.emplace_back (*name);
if (*name == selectedTemplateStr)
rowToSelect = index;
++index;
}
if (rowToSelect < 0)
rowToSelect = 0;
dataSource->setStringList (&templateNames);
templateDataBrowser->setSelectedRow (rowToSelect, true);
}
}
//----------------------------------------------------------------------------------------------------
void UITemplateController::setTemplateView (CViewContainer* view)
{
if (view != templateView && templateDataBrowser && templateDataBrowser->getParentView ())
{
templateView = view;
if (mainViewDataSource)
{
mainViewDataSource->remove ();
mainViewDataSource->forget ();
mainViewDataSource = nullptr;
}
if (templateView && templateDataBrowser)
{
CViewContainer* parentView = static_cast<CViewContainer*>(templateDataBrowser->getParentView ());
if (parentView)
{
const IViewFactory* viewFactory = editDescription->getViewFactory ();
mainViewDataSource = new UIViewListDataSource (templateView, viewFactory, selection, undoManager, this);
UIEditController::setupDataSource (mainViewDataSource);
CRect r (templateDataBrowser->getViewSize ());
r.offset (r.getWidth (), 0);
CDataBrowser* browser = new CDataBrowser (r, mainViewDataSource);
setupDataBrowser (templateDataBrowser, browser);
parentView->addView (browser);
}
}
}
}
//------------------------------------------------------------------------
void UITemplateController::navigateTo (CView* view)
{
std::list<CView*> parents;
CView* v = view;
while (auto parent = v->getParentView ())
{
if (parent == parent->getFrame ())
return; // view is not a child of the templateView
if (parent == templateView)
break;
if (IViewFactory::getViewName (parent) == nullptr)
{
v = parent;
continue;
}
parents.emplace_front (parent);
v = parent;
}
UIViewListDataSource* dataSource = mainViewDataSource;
for (auto parent : parents)
{
dataSource->setSelectedView (parent, true);
dataSource = dataSource->getNext ();
if (dataSource == nullptr)
break;
}
if (dataSource)
dataSource->setSelectedView (view, true);
}
//----------------------------------------------------------------------------------------------------
void UITemplateController::viewWillDelete (CView* view)
{
if (view == templateDataBrowser)
{
templateDataBrowser->unregisterViewListener (this);
templateDataBrowser = nullptr;
}
}
//----------------------------------------------------------------------------------------------------
CView* UITemplateController::createView (const UIAttributes& attributes, const IUIDescription* description)
{
const std::string* name = attributes.getAttributeValue (IUIDescription::kCustomViewName);
if (name)
{
if (*name == "TemplateBrowser")
{
vstgui_assert (templateDataBrowser == nullptr);
std::list<const std::string*> tmp;
editDescription->collectTemplateViewNames (tmp);
tmp.sort (UIEditController::std__stringCompare);
for (auto& name2 : tmp)
templateNames.emplace_back (*name2);
auto attr = editDescription->getCustomAttributes ("UITemplateController", true);
const std::string* templateName = attr ? attr->getAttributeValue ("SelectedTemplate") : nullptr;
UITemplatesDataSource* dataSource = new UITemplatesDataSource (this, editDescription, actionPerformer, templateName);
dataSource->setStringList (&templateNames);
UIEditController::setupDataSource (dataSource);
templateDataBrowser = new CDataBrowser (CRect (0, 0, 0, 0), dataSource, CDataBrowser::kDrawRowLines|CScrollView::kAutoHideScrollbars|CScrollView::kHorizontalScrollbar|CScrollView::kVerticalScrollbar|CDataBrowser::kDrawHeader);
dataSource->forget ();
templateDataBrowser->registerViewListener (this);
return templateDataBrowser;
}
}
return DelegationController::createView (attributes, description);
}
//----------------------------------------------------------------------------------------------------
CView* UITemplateController::verifyView (CView* view, const UIAttributes& attributes, const IUIDescription* description)
{
return DelegationController::verifyView (view, attributes, description);
}
//----------------------------------------------------------------------------------------------------
IController* UITemplateController::createSubController (UTF8StringPtr name, const IUIDescription* description)
{
return DelegationController::createSubController (name, description);
}
//----------------------------------------------------------------------------------------------------
void UITemplateController::appendContextMenuItems (COptionMenu& contextMenu, CView* view, const CPoint& where)
{
CPoint w (where);
view->localToFrame (w);
templateDataBrowser->frameToLocal (w);
if (!templateDataBrowser->hitTest (w))
return;
auto cell = templateDataBrowser->getCellAt (w);
if (!cell.isValid ())
return;
auto dataSource = dynamic_cast<UITemplatesDataSource*> (templateDataBrowser->getDelegate ());
auto templateName = dataSource->getStringList()->at (static_cast<uint32_t> (cell.row));
vstgui_assert (dataSource);
auto item = new CCommandMenuItem ("Duplicate Template '" + templateName + "'");
item->setActions ([this, cell, dataSource] (CCommandMenuItem*) {
std::list<const std::string*> tmp;
editDescription->collectTemplateViewNames (tmp);
std::string newName (dataSource->getStringList ()->at (static_cast<uint32_t> (cell.row)).data ());
UIEditMenuController::createUniqueTemplateName (tmp, newName);
actionPerformer->performDuplicateTemplate (dataSource->getStringList ()->at (static_cast<uint32_t> (cell.row)).data (), newName.data ());
});
contextMenu.addEntry (item);
item = new CCommandMenuItem ("Delete Template '" + templateName + "'");
item->setActions ([this, cell, dataSource] (CCommandMenuItem*) {
actionPerformer->performDeleteTemplate (dataSource->getStringList ()->at (static_cast<uint32_t> (cell.row)).data ());
});
contextMenu.addEntry (item);
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
UIViewListDataSource::UIViewListDataSource (
CViewContainer* view, const IViewFactory* viewFactory, UISelection* selection,
UIUndoManager* undoManager, GenericStringListDataBrowserSourceSelectionChanged* delegate)
: UINavigationDataSource (delegate)
, view (view)
, viewFactory (viewFactory)
, next (nullptr)
, selection (selection)
, undoManager (undoManager)
, selectedView (nullptr)
, inUpdate (false)
{
update (view);
undoManager->registerListener (this);
}
//----------------------------------------------------------------------------------------------------
UIViewListDataSource::~UIViewListDataSource ()
{
undoManager->unregisterListener (this);
}
//----------------------------------------------------------------------------------------------------
CView* UIViewListDataSource::getSubview (int32_t index)
{
if (index >= 0 && index < (int32_t)subviews.size ())
return subviews[static_cast<uint32_t> (index)];
return nullptr;
}
//----------------------------------------------------------------------------------------------------
bool UIViewListDataSource::update (CViewContainer* vc)
{
inUpdate = true;
names.clear ();
subviews.clear ();
vc->forEachChild ([&] (CView* subview) {
auto viewName = getViewDisplayString (subview);
if (!viewName.empty ())
{
names.emplace_back (std::move (viewName));
subviews.emplace_back (subview);
}
});
if (names.empty () && vc->getNbViews () > 0)
{
ViewIterator it (vc);
while (*it)
{
if (auto subview = (*it)->asViewContainer ())
{
if (update (subview))
{
view = subview;
inUpdate = false;
return true;
}
}
++it;
}
inUpdate = false;
return false;
}
setStringList (&names);
inUpdate = false;
return true;
}
//----------------------------------------------------------------------------------------------------
CCoord UIViewListDataSource::calculateSubViewWidth (CViewContainer* inView) const
{
CCoord result = 0;
inView->forEachChild ([&result] (CView* subView) {
result += subView->getViewSize ().getWidth ();
});
return result;
}
//----------------------------------------------------------------------------------------------------
bool UIViewListDataSource::setSelectedView (CView* newView, bool makeRowVisible)
{
auto index = indexOf (subviews.begin (), subviews.end (), newView);
if (!index)
return false;
selectedView = newView;
dataBrowser->selectRow (*index);
if (makeRowVisible)
dataBrowser->makeRowVisible (dataBrowser->getSelectedRow ());
if (next)
{
next->remove ();
next = nullptr;
}
if (auto container = selectedView ? selectedView->asViewContainer () : nullptr)
{
UIViewListDataSource* dataSource = new UIViewListDataSource (container, viewFactory, selection, undoManager, delegate);
UIEditController::setupDataSource (dataSource);
CRect r (dataBrowser->getViewSize ());
r.offset (r.getWidth (), 0);
CDataBrowser* newDataBrowser = new CDataBrowser (r, dataSource);
UITemplateController::setupDataBrowser (dataBrowser, newDataBrowser);
CViewContainer* parentView = static_cast<CViewContainer*>(dataBrowser->getParentView ());
parentView->addView (newDataBrowser);
next = dataSource;
dataSource->forget ();
CScrollView* scrollView = dynamic_cast<CScrollView*>(parentView->getParentView ());
if (scrollView)
{
CRect containerSize (scrollView->getContainerSize ());
containerSize.right = calculateSubViewWidth (parentView);
scrollView->setContainerSize (containerSize, true);
}
}
return true;
}
//----------------------------------------------------------------------------------------------------
void UIViewListDataSource::dbSelectionChanged (CDataBrowser* browser)
{
CView* subview = getSubview (browser->getSelectedRow ());
if (subview == selectedView || inUpdate)
return;
setSelectedView (subview);
GenericStringListDataBrowserSource::dbSelectionChanged (dataBrowser);
}
//----------------------------------------------------------------------------------------------------
void UIViewListDataSource::remove ()
{
if (next)
{
next->remove ();
next = nullptr;
}
if (dataBrowser)
{
CViewContainer* parentView = static_cast<CViewContainer*>(dataBrowser->getParentView ());
CScrollView* scrollView = dynamic_cast<CScrollView*>(parentView->getParentView ());
parentView->removeView (dataBrowser);
if (scrollView)
{
CRect containerSize (scrollView->getContainerSize ());
containerSize.right = calculateSubViewWidth (parentView);
scrollView->setContainerSize (containerSize, true);
}
}
}
//----------------------------------------------------------------------------------------------------
CMouseEventResult UIViewListDataSource::dbOnMouseDown (const CPoint& where, const CButtonState& buttons, int32_t row, int32_t column, CDataBrowser* browser)
{
if (buttons.isLeftButton ())
{
if (buttons.isDoubleClick ())
{
CView* subview = getSubview (row);
if (subview)
{
if (buttons.getModifierState () & kControl)
{
if (selection->contains (subview))
selection->remove (subview);
else
selection->add (subview);
}
else
selection->setExclusive (subview);
}
}
dragStartMouseObserver.init (where);
}
return kMouseEventHandled;
}
//------------------------------------------------------------------------
CMouseEventResult UIViewListDataSource::dbOnMouseMoved (const CPoint& where,
const CButtonState& buttons, int32_t row,
int32_t column, CDataBrowser* browser)
{
if (row >= 0 && buttons.isLeftButton () && dragStartMouseObserver.shouldStartDrag (where))
{
row = browser->getSelectedRow ();
dragRow = row;
auto cellBounds = browser->getCellBounds ({row, column});
auto offscreen = COffscreenContext::create (cellBounds.getSize (),
browser->getFrame ()->getScaleFactor ());
auto offscreenSize = cellBounds;
offscreenSize.originize ();
offscreen->beginDraw ();
dbDrawCell (offscreen, offscreenSize, row, column, 0, browser);
offscreen->endDraw ();
auto startPos = dragStartMouseObserver.getInitPosition ();
DragDescription dd (CDropSource::create (&row, sizeof (int32_t), IDataPackage::kBinary),
{cellBounds.left - startPos.x, cellBounds.top - startPos.y},
shared (offscreen->getBitmap ()));
auto callbackFunc = makeOwned<DragCallbackFunctions> ();
auto Self = shared (this);
callbackFunc->endedFunc = [Self] (IDraggingSession*, CPoint, DragOperation) {
Self->dragRow = -1;
Self->dragDestinationRow = -1;
};
browser->doDrag (dd, callbackFunc);
return kMouseMoveEventHandledButDontNeedMoreEvents;
}
return kMouseEventHandled;
}
//----------------------------------------------------------------------------------------------------
DragOperation UIViewListDataSource::dbOnDragEnterCell (int32_t row, int32_t column,
const CPoint& where, IDataPackage* drag,
CDataBrowser* browser)
{
if (dragRow >= 0)
{
if (dragDestinationRow >= 0)
browser->invalidateRow (dragDestinationRow);
if (dragRow == row)
{
dragDestinationRow = -1;
}
else
{
dragDestinationRow = row;
browser->invalidateRow (dragDestinationRow);
}
return DragOperation::Move;
}
return DragOperation::None;
}
//----------------------------------------------------------------------------------------------------
DragOperation UIViewListDataSource::dbOnDragMoveInCell (int32_t row, int32_t column,
const CPoint& where, IDataPackage* drag,
CDataBrowser* browser)
{
if (dragRow >= 0)
return DragOperation::Move;
return DragOperation::None;
}
//----------------------------------------------------------------------------------------------------
void UIViewListDataSource::dbOnDragExitCell (int32_t row, int32_t column, IDataPackage* drag,
CDataBrowser* browser)
{
if (dragDestinationRow >= 0)
{
browser->invalidateRow (dragDestinationRow);
dragDestinationRow = -1;
}
}
//----------------------------------------------------------------------------------------------------
bool UIViewListDataSource::dbOnDropInCell (int32_t row, int32_t column, const CPoint& where,
IDataPackage* drag, CDataBrowser* browser)
{
bool result = false;
if (row != dragRow && dragDestinationRow != -1 && row != -1)
{
int32_t dir = dragDestinationRow - dragRow;
undoManager->pushAndPerform (new HierarchyMoveViewOperation (subviews[dragRow], selection, dir));
result = true;
}
dragRow = dragDestinationRow = -1;
browser->invalidateRow (row);
return result;
}
//----------------------------------------------------------------------------------------------------
void UIViewListDataSource::onUndoManagerChange ()
{
update (view);
if (selectedView)
{
if (dataBrowser)
{
if (auto index = indexOf (subviews.begin (), subviews.end (), selectedView))
{
dataBrowser->setSelectedRow (*index, true);
return;
}
}
selectedView = nullptr;
if (next)
{
next->remove ();
next = nullptr;
}
}
}
//----------------------------------------------------------------------------------------------------
void UIViewListDataSource::dbOnKeyboardEvent (KeyboardEvent& event, CDataBrowser* browser)
{
if (event.type == EventType::KeyDown)
{
if (event.virt == VirtualKey::Return)
{
int32_t row = browser->getSelectedRow ();
CView* subview = getSubview (row);
if (subview)
{
selection->setExclusive (subview);
event.consumed = true;
return;
}
}
}
UINavigationDataSource::dbOnKeyboardEvent (event, browser);
}
//----------------------------------------------------------------------------------------------------
void UIViewListDataSource::dbDrawCell (CDrawContext* context, const CRect& size, int32_t row, int32_t column, int32_t flags, CDataBrowser* browser)
{
drawRowBackground (context, size, row, flags, browser);
auto subview = getSubview (row);
if (subview && subview->asViewContainer ())
drawTriangle (context, size);
drawRowString (context, size, row, flags, browser);
if (dragDestinationRow == row)
{
CColor color = kRedCColor;
UIEditController::getEditorDescription ()->getColor ("db.drag.indicator", color);
context->setFrameColor (color);
context->setLineWidth (1.);
auto r = size;
r.top += 1.;
r.bottom -= 2.;
if (dragDestinationRow < dragRow)
context->drawLine (r.getTopLeft (), r.getTopRight ());
else
context->drawLine (r.getBottomLeft (), r.getBottomRight ());
}
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
UITemplatesDataSource::UITemplatesDataSource (GenericStringListDataBrowserSourceSelectionChanged* delegate, UIDescription* description, IActionPerformer* actionPerformer, const std::string* templateName)
: UINavigationDataSource (delegate)
, description (description)
, actionPerformer (actionPerformer)
{
headerTitle = "Templates";
if (templateName)
firstSelectedTemplateName = *templateName;
}
//----------------------------------------------------------------------------------------------------
CMouseEventResult UITemplatesDataSource::dbOnMouseDown (const CPoint& where, const CButtonState& buttons, int32_t row, int32_t column, CDataBrowser* browser)
{
if (buttons.isLeftButton ())
{
if (buttons.isDoubleClick ())
{
browser->beginTextEdit (CDataBrowser::Cell (row, column), getStringList ()->at (static_cast<uint32_t> (row)).data ());
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}
delegate->dbSelectionChanged (row, this);
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}
return UINavigationDataSource::dbOnMouseDown (where, buttons, row, column, browser);
}
//----------------------------------------------------------------------------------------------------
void UITemplatesDataSource::dbCellTextChanged (int32_t row, int32_t column, UTF8StringPtr newText, CDataBrowser* browser)
{
auto oldName = getStringList ()->at (static_cast<uint32_t> (row));
if (oldName != newText)
{
for (auto& name : *getStringList ())
{
if (name == newText)
return;
}
actionPerformer->performTemplateNameChange (oldName.data (), newText);
}
}
//----------------------------------------------------------------------------------------------------
void UITemplatesDataSource::dbCellSetupTextEdit (int32_t row, int32_t column, CTextEdit* textEditControl, CDataBrowser* browser)
{
textEditControl->setBackColor (kWhiteCColor);
textEditControl->setFontColor (fontColor);
textEditControl->setFont (drawFont);
textEditControl->setHoriAlign (kLeftText);
textEditControl->setTextInset (textInset);
}
//----------------------------------------------------------------------------------------------------
void UITemplatesDataSource::dbDrawCell (CDrawContext* context, const CRect& size, int32_t row, int32_t column, int32_t flags, CDataBrowser* browser)
{
drawRowBackground (context, size, row, flags, browser);
drawTriangle (context, size);
drawRowString (context, size, row, flags, browser);
}
//----------------------------------------------------------------------------------------------------
void UITemplatesDataSource::dbAttached (CDataBrowser* browser)
{
UINavigationDataSource::dbAttached (browser);
if (getStringList ())
{
if (firstSelectedTemplateName.empty ())
{
browser->setSelectedRow (0, true);
}
else
{
uint32_t index = 0;
for (auto& name : *getStringList ())
{
if (name == firstSelectedTemplateName)
{
browser->setSelectedRow (static_cast<int32_t> (index), true);
break;
}
index++;
}
}
}
}
} // VSTGUI
#endif // VSTGUI_LIVE_EDITING