Initial release
This commit is contained in:
+806
@@ -0,0 +1,806 @@
|
||||
// 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 "uieditmenucontroller.h"
|
||||
|
||||
#if VSTGUI_LIVE_EDITING
|
||||
|
||||
#include "uiactions.h"
|
||||
#include "uieditview.h"
|
||||
#include "uieditcontroller.h"
|
||||
#include "../iviewfactory.h"
|
||||
#include "../uiattributes.h"
|
||||
#include "../../lib/cvstguitimer.h"
|
||||
#include "../../lib/events.h"
|
||||
#include "../../lib/controls/coptionmenu.h"
|
||||
#include "../../lib/controls/ctextlabel.h"
|
||||
#include "../detail/uiviewcreatorattributes.h"
|
||||
#include <cctype>
|
||||
|
||||
namespace VSTGUI {
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
UIEditMenuController::UIEditMenuController (IController* baseController, UISelection* selection, UIUndoManager* undoManager, UIDescription* description, IActionPerformer* actionPerformer)
|
||||
: DelegationController (baseController)
|
||||
, selection (selection)
|
||||
, undoManager (undoManager)
|
||||
, description (description)
|
||||
, actionPerformer (actionPerformer)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
UIEditMenuController::~UIEditMenuController () noexcept
|
||||
{
|
||||
if (editMenu)
|
||||
editMenu->unregisterViewListener (this);
|
||||
if (fileMenu)
|
||||
fileMenu->unregisterViewListener (this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
static void addEntriesToMenu (const UIEditing::MenuEntry* entries, COptionMenu* menu, ICommandMenuItemTarget* menuItemTarget, int32_t& index)
|
||||
{
|
||||
while (entries[index].category != nullptr)
|
||||
{
|
||||
if (entries[index].menuFlags & UIEditing::MenuEntry::kSubMenuEnd)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (entries[index].category == UIEditing::kMenuSeparator.category)
|
||||
menu->addSeparator ();
|
||||
else if (entries[index].menuFlags & UIEditing::MenuEntry::kSubMenu)
|
||||
{
|
||||
auto subMenu = makeOwned<COptionMenu> ();
|
||||
if (entries[index].menuFlags & UIEditing::MenuEntry::kSubMenuCheckStyle)
|
||||
subMenu->setStyle (COptionMenu::kMultipleCheckStyle|COptionMenu::kCheckStyle);
|
||||
menu->addEntry (new CMenuItem (entries[index].name, subMenu));
|
||||
index++;
|
||||
addEntriesToMenu(entries, subMenu, menuItemTarget, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMenuItem* item = menu->addEntry (new CCommandMenuItem ({entries[index].name, menuItemTarget, entries[index].category, entries[index].name}));
|
||||
if (entries[index].key)
|
||||
{
|
||||
item->setKey (entries[index].key, entries[index].modifier);
|
||||
}
|
||||
else if (entries[index].virtualKey != VirtualKey::None)
|
||||
{
|
||||
item->setVirtualKey (entries[index].virtualKey, entries[index].modifier);
|
||||
}
|
||||
if (entries[index].menuFlags)
|
||||
{
|
||||
if (entries[index].menuFlags & UIEditing::MenuEntry::kMenuItemIsTitle)
|
||||
{
|
||||
item->setIsTitle (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void UIEditMenuController::createFileMenu (COptionMenu* menu)
|
||||
{
|
||||
int32_t index = 0;
|
||||
addEntriesToMenu (UIEditing::fileMenu, menu, this, index);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void UIEditMenuController::createEditMenu (COptionMenu* menu)
|
||||
{
|
||||
int32_t index = 0;
|
||||
menu->setStyle (menu->getStyle () | COptionMenu::kMultipleCheckStyle);
|
||||
addEntriesToMenu (UIEditing::editMenu, menu, this, index);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool UIEditMenuController::createUniqueTemplateName (std::list<const std::string*>& names, std::string& name)
|
||||
{
|
||||
for (auto& it : names)
|
||||
{
|
||||
if (*it == name)
|
||||
{
|
||||
int32_t count = 0;
|
||||
size_t pos = name.find_last_not_of ("0123456789");
|
||||
if (pos != std::string::npos && pos != name.length () - 1)
|
||||
{
|
||||
std::string numberStr = name.substr (pos);
|
||||
count = static_cast<int32_t> (strtol (numberStr.c_str (), nullptr, 10)) + 1;
|
||||
name.erase (pos+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
while (name.length () && std::isspace (name[name.length ()-1]))
|
||||
name.erase (name.length ()-1);
|
||||
char number[10];
|
||||
snprintf (number, 10, "%d", count);
|
||||
name += ' ';
|
||||
name += number;
|
||||
return createUniqueTemplateName (names, name);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool UIEditMenuController::validateCommandMenuItem (CCommandMenuItem* item)
|
||||
{
|
||||
return validateMenuItem (*item);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool UIEditMenuController::onCommandMenuItemSelected (CCommandMenuItem* item)
|
||||
{
|
||||
return handleCommand (item->getCommandCategory (), item->getCommandName ());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
CMessageResult UIEditMenuController::notify (CBaseObject* sender, IdStringPtr message)
|
||||
{
|
||||
if (message == CVSTGUITimer::kMsgTimer)
|
||||
{
|
||||
editLabel->setTransparency (true);
|
||||
fileLabel->setTransparency (true);
|
||||
highlightTimer = nullptr;
|
||||
}
|
||||
return kMessageUnknown;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool UIEditMenuController::validateMenuItem (CCommandMenuItem& item)
|
||||
{
|
||||
UTF8StringView cmdCategory (item.getCommandCategory ());
|
||||
UTF8StringView cmdName (item.getCommandName ());
|
||||
item.setChecked (false);
|
||||
if (cmdCategory == "Edit")
|
||||
{
|
||||
if (cmdName == "Undo")
|
||||
{
|
||||
if (undoManager->canUndo ())
|
||||
{
|
||||
std::string str ("Undo ");
|
||||
str += undoManager->getUndoName ();
|
||||
item.setTitle (str.c_str ());
|
||||
item.setEnabled (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.setTitle ("Undo");
|
||||
item.setEnabled (false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Redo")
|
||||
{
|
||||
if (undoManager->canRedo ())
|
||||
{
|
||||
std::string str ("Redo ");
|
||||
str += undoManager->getRedoName ();
|
||||
item.setTitle (str.c_str ());
|
||||
item.setEnabled (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.setTitle ("Redo");
|
||||
item.setEnabled (false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Cut")
|
||||
{
|
||||
item.setEnabled (false);
|
||||
}
|
||||
else if (cmdName == "Copy")
|
||||
{
|
||||
item.setEnabled (false);
|
||||
}
|
||||
else if (cmdName == "Paste")
|
||||
{
|
||||
item.setEnabled (false);
|
||||
}
|
||||
else if (cmdName == "Delete")
|
||||
{
|
||||
CView* view = selection->first ();
|
||||
int32_t selectionCount = selection->total ();
|
||||
bool enable = view ? (selectionCount > 1 ? true : dynamic_cast<UIEditView*> (view->getParentView ()) == nullptr) : false;
|
||||
item.setEnabled (enable);
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Add New Template")
|
||||
{
|
||||
if (const auto* factory = dynamic_cast<const IViewFactoryEditingSupport*> (
|
||||
description->getViewFactory ()))
|
||||
{
|
||||
auto submenu = makeOwned<COptionMenu> ();
|
||||
auto viewAndDisplayNames =
|
||||
factory->collectRegisteredViewAndDisplayNames ("CViewContainer");
|
||||
viewAndDisplayNames.sort (
|
||||
[] (const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });
|
||||
for (auto& entry : viewAndDisplayNames)
|
||||
{
|
||||
submenu->addEntry (new CCommandMenuItem (CCommandMenuItem::Desc {
|
||||
entry.second.data (), this, "AddTemplate", entry.first->data ()}));
|
||||
}
|
||||
item.setSubmenu (submenu);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Delete Template")
|
||||
{
|
||||
item.setSubmenu (nullptr);
|
||||
std::list<const std::string*> templateNames;
|
||||
description->collectTemplateViewNames (templateNames);
|
||||
item.setEnabled (templateNames.empty () == false);
|
||||
if (templateNames.empty () == false)
|
||||
{
|
||||
templateNames.sort (UIEditController::std__stringCompare);
|
||||
auto submenu = makeOwned<COptionMenu> ();
|
||||
item.setSubmenu (submenu);
|
||||
for (auto& name : templateNames)
|
||||
{
|
||||
submenu->addEntry (new CCommandMenuItem (CCommandMenuItem::Desc{name->data (), this, "RemoveTemplate", name->data ()}));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Duplicate Template")
|
||||
{
|
||||
item.setSubmenu (nullptr);
|
||||
std::list<const std::string*> templateNames;
|
||||
description->collectTemplateViewNames (templateNames);
|
||||
item.setEnabled (templateNames.empty () == false);
|
||||
if (templateNames.empty () == false)
|
||||
{
|
||||
templateNames.sort (UIEditController::std__stringCompare);
|
||||
auto submenu = makeOwned<COptionMenu> ();
|
||||
item.setSubmenu (submenu);
|
||||
for (auto& name : templateNames)
|
||||
{
|
||||
submenu->addEntry (new CCommandMenuItem (CCommandMenuItem::Desc{name->data (), this, "DuplicateTemplate", name->data ()}));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Embed Into")
|
||||
{
|
||||
item.setSubmenu (nullptr);
|
||||
bool enable = selection->total () > 0;
|
||||
for (auto view : *selection)
|
||||
{
|
||||
if (dynamic_cast<UIEditView*>(view->getParentView()) != nullptr)
|
||||
{
|
||||
enable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
item.setEnabled (enable);
|
||||
if (enable == false)
|
||||
return true;
|
||||
if (const auto* factory = dynamic_cast<const IViewFactoryEditingSupport*> (
|
||||
description->getViewFactory ()))
|
||||
{
|
||||
auto submenu = makeOwned<COptionMenu> ();
|
||||
item.setSubmenu (submenu);
|
||||
auto viewAndDisplayNames =
|
||||
factory->collectRegisteredViewAndDisplayNames ("CViewContainer");
|
||||
viewAndDisplayNames.sort (
|
||||
[] (const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });
|
||||
for (auto& entry : viewAndDisplayNames)
|
||||
{
|
||||
submenu->addEntry (new CCommandMenuItem (CCommandMenuItem::Desc {
|
||||
entry.second.data (), this, "Embed", entry.first->data ()}));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Unembed Views")
|
||||
{
|
||||
bool enabled = false;
|
||||
if (selection->total () == 1)
|
||||
{
|
||||
CViewContainer* container = selection->first ()->asViewContainer ();
|
||||
if (container && container->hasChildren () && dynamic_cast<UIEditView*>(container->getParentView ()) == nullptr)
|
||||
enabled = true;
|
||||
}
|
||||
item.setEnabled (enabled);
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Size To Fit")
|
||||
{
|
||||
item.setEnabled (selection->total() > 0 ? true : false);
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Transform View Type")
|
||||
{
|
||||
item.setSubmenu (nullptr);
|
||||
auto numViewContainers = 0u;
|
||||
auto numNonViewContainers = 0u;
|
||||
for (auto& entry : *selection)
|
||||
{
|
||||
if (entry->asViewContainer ())
|
||||
++numViewContainers;
|
||||
else
|
||||
++numNonViewContainers;
|
||||
}
|
||||
if (numViewContainers != 0 && numNonViewContainers != 0)
|
||||
{
|
||||
item.setEnabled (false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const auto* factory = dynamic_cast<const IViewFactoryEditingSupport*> (
|
||||
description->getViewFactory ()))
|
||||
{
|
||||
auto submenu = makeOwned<COptionMenu> ();
|
||||
item.setSubmenu (submenu);
|
||||
auto viewAndDisplayNames = factory->collectRegisteredViewAndDisplayNames ();
|
||||
viewAndDisplayNames.sort (
|
||||
[] (const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });
|
||||
for (auto& entry : viewAndDisplayNames)
|
||||
{
|
||||
submenu->addEntry (new CCommandMenuItem (CCommandMenuItem::Desc {
|
||||
entry.second.data (), this, "Transform View Type", entry.first->data ()}));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Insert Template")
|
||||
{
|
||||
item.setSubmenu (nullptr);
|
||||
item.setEnabled (selection->total () == 1 && selection->first ()->asViewContainer ());
|
||||
if (item.isEnabled () == false)
|
||||
return true;
|
||||
std::list<const std::string*> templateNames;
|
||||
description->collectTemplateViewNames (templateNames);
|
||||
item.setEnabled (templateNames.empty () == false);
|
||||
if (templateNames.empty () == false)
|
||||
{
|
||||
templateNames.sort (UIEditController::std__stringCompare);
|
||||
auto submenu = makeOwned<COptionMenu> ();
|
||||
item.setSubmenu (submenu);
|
||||
for (auto& name : templateNames)
|
||||
{
|
||||
submenu->addEntry (new CCommandMenuItem (CCommandMenuItem::Desc{name->data (), this, "InsertTemplate", name->data ()}));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (cmdCategory == "Selection")
|
||||
{
|
||||
if (cmdName == "Select Children Of Type")
|
||||
{
|
||||
if (const auto* factory = dynamic_cast<const IViewFactoryEditingSupport*> (
|
||||
description->getViewFactory ()))
|
||||
{
|
||||
auto submenu = makeOwned<COptionMenu> ();
|
||||
item.setSubmenu (submenu);
|
||||
auto viewAndDisplayNames = factory->collectRegisteredViewAndDisplayNames ();
|
||||
viewAndDisplayNames.sort (
|
||||
[] (const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });
|
||||
for (auto& entry : viewAndDisplayNames)
|
||||
{
|
||||
submenu->addEntry (new CCommandMenuItem (
|
||||
CCommandMenuItem::Desc {entry.second.data (), this,
|
||||
"Select Children Of Type", entry.first->data ()}));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (auto obj = dynamic_cast<ICommandMenuItemTarget*> (controller))
|
||||
return obj->validateCommandMenuItem (&item);
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
CCommandMenuItem* UIEditMenuController::findKeyCommandItem (COptionMenu* menu, const KeyboardEvent& event)
|
||||
{
|
||||
for (auto& item : *menu->getItems ())
|
||||
{
|
||||
COptionMenu* subMenu = item->getSubmenu ();
|
||||
if (subMenu)
|
||||
{
|
||||
CCommandMenuItem* result = findKeyCommandItem (subMenu, event);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
CCommandMenuItem* result = item.cast<CCommandMenuItem>();
|
||||
if (result)
|
||||
{
|
||||
int32_t modifier = 0;
|
||||
if (event.modifiers.has (ModifierKey::Shift))
|
||||
modifier |= kShift;
|
||||
if (event.modifiers.has (ModifierKey::Alt))
|
||||
modifier |= kAlt;
|
||||
if (event.modifiers.has (ModifierKey::Control))
|
||||
modifier |= kControl;
|
||||
if (event.modifiers.has (ModifierKey::Super))
|
||||
modifier |= kApple;
|
||||
if (result->getKeyModifiers () == modifier)
|
||||
{
|
||||
if (event.virt != VirtualKey::None && event.virt == result->getVirtualKey ())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
else if (!result->getKeycode ().empty () &&
|
||||
static_cast<char32_t> (result->getKeycode ().getString ()[0]) ==
|
||||
event.character)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool UIEditMenuController::handleCommand (const UTF8StringPtr category, const UTF8StringPtr name)
|
||||
{
|
||||
UTF8StringView cmdCategory (category);
|
||||
UTF8StringView cmdName (name);
|
||||
if (cmdCategory == "Edit")
|
||||
{
|
||||
if (cmdName == "Undo")
|
||||
{
|
||||
if (undoManager->canUndo ())
|
||||
{
|
||||
undoManager->performUndo ();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Redo")
|
||||
{
|
||||
if (undoManager->canRedo ())
|
||||
{
|
||||
undoManager->performRedo ();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Delete")
|
||||
{
|
||||
IAction* action = new DeleteOperation (selection);
|
||||
undoManager->pushAndPerform (action);
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Unembed Views")
|
||||
{
|
||||
IAction* action = new UnembedViewOperation (selection, description->getViewFactory ());
|
||||
undoManager->pushAndPerform (action);
|
||||
return true;
|
||||
}
|
||||
else if (cmdName == "Size To Fit")
|
||||
{
|
||||
IAction* action = new SizeToFitOperation (selection);
|
||||
undoManager->pushAndPerform (action);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (cmdCategory == "AddTemplate")
|
||||
{
|
||||
std::list<const std::string*> tmp;
|
||||
description->collectTemplateViewNames (tmp);
|
||||
std::string templateName (cmdName);
|
||||
if (createUniqueTemplateName (tmp, templateName))
|
||||
{
|
||||
actionPerformer->performCreateNewTemplate (templateName.c_str (), cmdName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdCategory == "RemoveTemplate")
|
||||
{
|
||||
actionPerformer->performDeleteTemplate (cmdName);
|
||||
return kMessageNotified;
|
||||
}
|
||||
else if (cmdCategory == "DuplicateTemplate")
|
||||
{
|
||||
std::list<const std::string*> tmp;
|
||||
description->collectTemplateViewNames (tmp);
|
||||
std::string templateName (cmdName);
|
||||
if (createUniqueTemplateName (tmp, templateName))
|
||||
{
|
||||
actionPerformer->performDuplicateTemplate (cmdName, templateName.c_str ());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdCategory == "Embed")
|
||||
{
|
||||
const IViewFactory* viewFactory = description->getViewFactory ();
|
||||
UIAttributes viewAttr;
|
||||
viewAttr.setAttribute (UIViewCreator::kAttrClass, std::string (cmdName));
|
||||
if (auto newContainer = viewFactory->createView (viewAttr, description)->asViewContainer ())
|
||||
{
|
||||
IAction* action = new EmbedViewOperation (selection, newContainer);
|
||||
undoManager->pushAndPerform (action);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (cmdCategory == "Transform View Type")
|
||||
{
|
||||
undoManager->startGroupAction ("Transform View Type");
|
||||
for (auto& entry : *selection)
|
||||
{
|
||||
IAction* action = new TransformViewTypeOperation (
|
||||
selection, entry, cmdName, description, description->getViewFactory ());
|
||||
undoManager->pushAndPerform (action);
|
||||
}
|
||||
undoManager->endGroupAction ();
|
||||
return true;
|
||||
}
|
||||
else if (cmdCategory == "Select Children Of Type")
|
||||
{
|
||||
const auto* viewFactory = description->getViewFactory ();
|
||||
if (!viewFactory)
|
||||
return false;
|
||||
std::vector<CView*> newSelection;
|
||||
for (auto& entry : *selection)
|
||||
{
|
||||
if (auto viewContainer = entry->asViewContainer ())
|
||||
getChildrenOfType (viewContainer, cmdName, newSelection);
|
||||
}
|
||||
selection->clear ();
|
||||
for (auto& view : newSelection)
|
||||
selection->add (view);
|
||||
return true;
|
||||
}
|
||||
else if (cmdCategory == "InsertTemplate")
|
||||
{
|
||||
if (auto parent = selection->first ()->asViewContainer ())
|
||||
{
|
||||
CView* view = description->createView (cmdName, description->getController ());
|
||||
if (view)
|
||||
{
|
||||
undoManager->pushAndPerform (new InsertViewOperation (parent, view, selection));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (auto obj = dynamic_cast<ICommandMenuItemTarget*> (controller))
|
||||
{
|
||||
CCommandMenuItem item (CCommandMenuItem::Desc{"", 0, nullptr, category, name});
|
||||
if (obj->onCommandMenuItemSelected (&item))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool UIEditMenuController::canHandleCommand (const UTF8StringPtr category, const UTF8StringPtr name) const
|
||||
{
|
||||
CCommandMenuItem item (CCommandMenuItem::Desc{"", 0, nullptr, category, name});
|
||||
if (const_cast<UIEditMenuController*> (this)->validateMenuItem (item))
|
||||
{
|
||||
return item.isEnabled ();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void UIEditMenuController::processKeyCommand (KeyboardEvent& event)
|
||||
{
|
||||
COptionMenu* baseMenu = editMenu;
|
||||
CCommandMenuItem* item = baseMenu ? findKeyCommandItem (baseMenu, event) : nullptr;
|
||||
if (item == nullptr && fileMenu)
|
||||
{
|
||||
baseMenu = fileMenu;
|
||||
item = findKeyCommandItem (baseMenu, event);
|
||||
}
|
||||
if (item && item->getItemTarget ())
|
||||
{
|
||||
item->getItemTarget ()->validateCommandMenuItem (item);
|
||||
if (item->isEnabled ())
|
||||
{
|
||||
CTextLabel* label = nullptr;
|
||||
if (baseMenu)
|
||||
{
|
||||
switch (baseMenu->getTag ())
|
||||
{
|
||||
case kMenuFileTag:
|
||||
{
|
||||
label = fileLabel;
|
||||
break;
|
||||
}
|
||||
case kMenuEditTag:
|
||||
{
|
||||
label = editLabel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (label)
|
||||
{
|
||||
label->setTransparency (false);
|
||||
}
|
||||
item->getItemTarget ()->onCommandMenuItemSelected (item);
|
||||
if (label)
|
||||
{
|
||||
highlightTimer = makeOwned<CVSTGUITimer> (this, 90u, true);
|
||||
}
|
||||
event.consumed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
static void copyMenuItems (COptionMenu* src, COptionMenu* dst)
|
||||
{
|
||||
auto srcItems = src->getItems ();
|
||||
if (!srcItems)
|
||||
return;
|
||||
for (auto& item : *srcItems)
|
||||
{
|
||||
item->remember ();
|
||||
dst->addEntry (item);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void UIEditMenuController::viewRemoved (CView* view)
|
||||
{
|
||||
if (view == editMenu)
|
||||
{
|
||||
view->unregisterViewListener (this);
|
||||
editMenu = nullptr;
|
||||
}
|
||||
else if (view == fileMenu)
|
||||
{
|
||||
view->unregisterViewListener (this);
|
||||
fileMenu = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
CView* UIEditMenuController::verifyView (CView* view, const UIAttributes& attributes, const IUIDescription*)
|
||||
{
|
||||
COptionMenu* menu = dynamic_cast<COptionMenu*>(view);
|
||||
if (menu)
|
||||
{
|
||||
switch (menu->getTag ())
|
||||
{
|
||||
case kMenuEditTag:
|
||||
{
|
||||
if (editMenu)
|
||||
copyMenuItems (editMenu, menu);
|
||||
else
|
||||
{
|
||||
createEditMenu (menu);
|
||||
menu->registerViewListener (this);
|
||||
}
|
||||
editMenu = menu;
|
||||
break;
|
||||
}
|
||||
case kMenuFileTag:
|
||||
{
|
||||
if (fileMenu)
|
||||
copyMenuItems (fileMenu, menu);
|
||||
else
|
||||
{
|
||||
createFileMenu (menu);
|
||||
menu->registerViewListener (this);
|
||||
}
|
||||
fileMenu = menu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CTextLabel* label = dynamic_cast<CTextLabel*>(view);
|
||||
if (label)
|
||||
{
|
||||
switch (label->getTag ())
|
||||
{
|
||||
case kMenuEditTag:
|
||||
{
|
||||
editLabel = label;
|
||||
break;
|
||||
}
|
||||
case kMenuFileTag:
|
||||
{
|
||||
fileLabel = label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void UIEditMenuController::valueChanged (CControl* control)
|
||||
{
|
||||
switch (control->getTag ())
|
||||
{
|
||||
case kMenuFileTag:
|
||||
{
|
||||
if (fileMenu && control->getValue () == control->getMax ())
|
||||
{
|
||||
CRect r (control->getViewSize ());
|
||||
CPoint p = r.getBottomLeft ();
|
||||
control->localToFrame (p);
|
||||
fileMenu->popup (control->getFrame (), p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMenuEditTag:
|
||||
{
|
||||
if (editMenu && control->getValue () == control->getMax ())
|
||||
{
|
||||
CRect r (control->getViewSize ());
|
||||
CPoint p = r.getTopLeft ();
|
||||
control->localToFrame (p);
|
||||
editMenu->popup (control->getFrame (), p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void UIEditMenuController::controlBeginEdit (CControl* pControl)
|
||||
{
|
||||
CTextLabel* label = nullptr;
|
||||
switch (pControl->getTag ())
|
||||
{
|
||||
case kMenuFileTag:
|
||||
{
|
||||
fileMenu->cleanupSeparators (true);
|
||||
label = fileLabel;
|
||||
break;
|
||||
}
|
||||
case kMenuEditTag:
|
||||
{
|
||||
editMenu->cleanupSeparators (true);
|
||||
label = editLabel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (label)
|
||||
label->setTransparency (false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void UIEditMenuController::controlEndEdit (CControl* pControl)
|
||||
{
|
||||
CTextLabel* label = nullptr;
|
||||
switch (pControl->getTag ())
|
||||
{
|
||||
case kMenuFileTag:
|
||||
{
|
||||
label = fileLabel;
|
||||
break;
|
||||
}
|
||||
case kMenuEditTag:
|
||||
{
|
||||
label = editLabel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (label)
|
||||
label->setTransparency (true);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void UIEditMenuController::getChildrenOfType (CViewContainer* container, UTF8StringView type, std::vector<CView*>& result) const
|
||||
{
|
||||
container->forEachChild ([&] (auto view) {
|
||||
if (type == IViewFactory::getViewName (view))
|
||||
result.emplace_back (view);
|
||||
if (auto c = view->asViewContainer ())
|
||||
{
|
||||
getChildrenOfType (c, type, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // VSTGUI
|
||||
|
||||
#endif // VSTGUI_LIVE_EDITING
|
||||
Reference in New Issue
Block a user