mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-28 02:30:05 +00:00
Updated CodeEditorComponent to act as an ApplicationCommandTarget
This commit is contained in:
parent
5428554cda
commit
3831af62ef
14 changed files with 187 additions and 154 deletions
|
|
@ -72,6 +72,12 @@ public:
|
|||
commandManager = new ApplicationCommandManager();
|
||||
commandManager->registerAllCommandsForTarget (this);
|
||||
|
||||
{
|
||||
CodeDocument doc;
|
||||
CodeEditorComponent ed (doc, nullptr);
|
||||
commandManager->registerAllCommandsForTarget (&ed);
|
||||
}
|
||||
|
||||
menuModel = new MainMenuModel();
|
||||
|
||||
doExtraInitialisation();
|
||||
|
|
@ -262,13 +268,10 @@ public:
|
|||
menu.addCommandItem (commandManager, StandardApplicationCommandIDs::selectAll);
|
||||
menu.addCommandItem (commandManager, StandardApplicationCommandIDs::deselectAll);
|
||||
menu.addSeparator();
|
||||
menu.addCommandItem (commandManager, CommandIDs::toFront);
|
||||
menu.addCommandItem (commandManager, CommandIDs::toBack);
|
||||
menu.addSeparator();
|
||||
menu.addCommandItem (commandManager, CommandIDs::group);
|
||||
menu.addCommandItem (commandManager, CommandIDs::ungroup);
|
||||
menu.addSeparator();
|
||||
menu.addCommandItem (commandManager, CommandIDs::bringBackLostItems);
|
||||
menu.addCommandItem (commandManager, CommandIDs::showFindPanel);
|
||||
menu.addCommandItem (commandManager, CommandIDs::findSelection);
|
||||
menu.addCommandItem (commandManager, CommandIDs::findNext);
|
||||
menu.addCommandItem (commandManager, CommandIDs::findPrevious);
|
||||
}
|
||||
|
||||
virtual void createViewMenu (PopupMenu& menu)
|
||||
|
|
@ -331,7 +334,6 @@ public:
|
|||
|
||||
const CommandID ids[] = { CommandIDs::newProject,
|
||||
CommandIDs::open,
|
||||
CommandIDs::showPrefs,
|
||||
CommandIDs::closeAllDocuments,
|
||||
CommandIDs::saveAll,
|
||||
CommandIDs::updateModules,
|
||||
|
|
@ -355,11 +357,6 @@ public:
|
|||
result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::showPrefs:
|
||||
result.setInfo ("Preferences...", "Shows the preferences panel.", CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add (KeyPress (',', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::showAppearanceSettings:
|
||||
result.setInfo ("Fonts and Colours...", "Shows the appearance settings window.", CommandCategories::general, 0);
|
||||
break;
|
||||
|
|
@ -394,7 +391,6 @@ public:
|
|||
{
|
||||
case CommandIDs::newProject: createNewProject(); break;
|
||||
case CommandIDs::open: askUserToOpenFile(); break;
|
||||
case CommandIDs::showPrefs: showPrefsPanel(); break;
|
||||
case CommandIDs::saveAll: openDocumentManager.saveAll(); break;
|
||||
case CommandIDs::closeAllDocuments: closeAllDocuments (true); break;
|
||||
case CommandIDs::showUTF8Tool: showUTF8ToolWindow (utf8Window); break;
|
||||
|
|
@ -407,11 +403,6 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void showPrefsPanel()
|
||||
{
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
void createNewProject()
|
||||
{
|
||||
if (makeSureUserHasSelectedModuleFolder())
|
||||
|
|
@ -504,8 +495,7 @@ private:
|
|||
stopTimer();
|
||||
delete this;
|
||||
|
||||
JUCEApplication* app = JUCEApplication::getInstance();
|
||||
if (app != nullptr)
|
||||
if (JUCEApplication* app = JUCEApplication::getInstance())
|
||||
app->systemRequestedQuit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,53 +37,27 @@ namespace CommandIDs
|
|||
|
||||
closeProject = 0x200051,
|
||||
saveProject = 0x200060,
|
||||
saveAll = 0x200080,
|
||||
openInIDE = 0x200072,
|
||||
saveAndOpenInIDE = 0x200073,
|
||||
|
||||
updateModules = 0x200075,
|
||||
showUTF8Tool = 0x200076,
|
||||
showAppearanceSettings = 0x200077,
|
||||
showConfigPanel = 0x200074,
|
||||
showFilePanel = 0x200078,
|
||||
|
||||
saveAll = 0x200080,
|
||||
|
||||
closeWindow = 0x201001,
|
||||
closeAllDocuments = 0x201000,
|
||||
goToPreviousDoc = 0x201002,
|
||||
goToNextDoc = 0x201003,
|
||||
goToCounterpart = 0x201004,
|
||||
deleteSelectedItem = 0x201005,
|
||||
|
||||
toFront = 0x2020a0,
|
||||
toBack = 0x2030a1,
|
||||
showOrHideProperties = 0x2030b0,
|
||||
showOrHideTree = 0x2030b1,
|
||||
showOrHideMarkers = 0x2030b2,
|
||||
toggleSnapping = 0x2030b3,
|
||||
|
||||
makeLineSegment = 0x2030c0,
|
||||
makeCubicSegment = 0x2030c1,
|
||||
breakSegment = 0x2030c2,
|
||||
pointModeCorner = 0x2030c3,
|
||||
pointModeRounded = 0x2030c4,
|
||||
pointModeSymmetric = 0x2030c5,
|
||||
|
||||
group = 0x202170,
|
||||
ungroup = 0x202180,
|
||||
|
||||
showPrefs = 0x2020c0,
|
||||
useTabbedWindows = 0x2020d0,
|
||||
|
||||
showGrid = 0x2020e0,
|
||||
enableSnapToGrid = 0x2020f0,
|
||||
zoomIn = 0x202130,
|
||||
zoomOut = 0x202140,
|
||||
zoomNormal = 0x202150,
|
||||
spaceBarDrag = 0x202160,
|
||||
bringBackLostItems = 0x202120,
|
||||
|
||||
newDocumentBase = 0x322010,
|
||||
newComponentBase = 0x302010,
|
||||
newElementBase = 0x312010
|
||||
showFindPanel = 0x2010a0,
|
||||
findSelection = 0x2010a1,
|
||||
findNext = 0x2010a2,
|
||||
findPrevious = 0x2010a3
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ void MainWindow::showNewProjectWizard()
|
|||
//==============================================================================
|
||||
ApplicationCommandTarget* MainWindow::getNextCommandTarget()
|
||||
{
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MainWindow::getAllCommands (Array <CommandID>& commands)
|
||||
|
|
|
|||
|
|
@ -106,9 +106,7 @@ SourceCodeEditor::~SourceCodeEditor()
|
|||
{
|
||||
getAppSettings().appearance.settings.removeListener (this);
|
||||
|
||||
SourceCodeDocument* doc = dynamic_cast <SourceCodeDocument*> (getDocument());
|
||||
|
||||
if (doc != nullptr)
|
||||
if (SourceCodeDocument* doc = dynamic_cast <SourceCodeDocument*> (getDocument()))
|
||||
doc->updateLastState (*editor);
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +174,7 @@ static CPlusPlusCodeTokeniser cppTokeniser;
|
|||
CppCodeEditorComponent::CppCodeEditorComponent (const File& f, CodeDocument& codeDocument)
|
||||
: CodeEditorComponent (codeDocument, &cppTokeniser), file (f)
|
||||
{
|
||||
setCommandManager (commandManager);
|
||||
}
|
||||
|
||||
void CppCodeEditorComponent::handleReturnKey()
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ void ProjectContentComponent::getAllCommands (Array <CommandID>& commands)
|
|||
CommandIDs::goToPreviousDoc,
|
||||
CommandIDs::goToNextDoc,
|
||||
CommandIDs::goToCounterpart,
|
||||
StandardApplicationCommandIDs::del };
|
||||
CommandIDs::deleteSelectedItem };
|
||||
|
||||
commands.addArray (ids, numElementsInArray (ids));
|
||||
}
|
||||
|
|
@ -655,7 +655,7 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica
|
|||
result.defaultKeypresses.add (KeyPress ('i', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case StandardApplicationCommandIDs::del:
|
||||
case CommandIDs::deleteSelectedItem:
|
||||
result.setInfo ("Delete Selected File", String::empty, CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add (KeyPress (KeyPress::deleteKey, 0, 0));
|
||||
result.defaultKeypresses.add (KeyPress (KeyPress::backspaceKey, 0, 0));
|
||||
|
|
@ -712,7 +712,7 @@ bool ProjectContentComponent::perform (const InvocationInfo& info)
|
|||
|
||||
case CommandIDs::openInIDE: openInIDE(); break;
|
||||
|
||||
case StandardApplicationCommandIDs::del: deleteSelectedTreeItems(); break;
|
||||
case CommandIDs::deleteSelectedItem: deleteSelectedTreeItems(); break;
|
||||
|
||||
case CommandIDs::saveAndOpenInIDE:
|
||||
if (saveProject())
|
||||
|
|
|
|||
|
|
@ -75,12 +75,8 @@ void GroupTreeViewItem::moveSelectedItemsTo (OwnedArray <Project::Item>& selecte
|
|||
void GroupTreeViewItem::checkFileStatus()
|
||||
{
|
||||
for (int i = 0; i < getNumSubItems(); ++i)
|
||||
{
|
||||
ProjectTreeViewBase* p = dynamic_cast <ProjectTreeViewBase*> (getSubItem(i));
|
||||
|
||||
if (p != nullptr)
|
||||
if (ProjectTreeViewBase* p = dynamic_cast <ProjectTreeViewBase*> (getSubItem(i)))
|
||||
p->checkFileStatus();
|
||||
}
|
||||
}
|
||||
|
||||
ProjectTreeViewBase* GroupTreeViewItem::createSubItem (const Project::Item& child)
|
||||
|
|
@ -97,9 +93,7 @@ ProjectTreeViewBase* GroupTreeViewItem::createSubItem (const Project::Item& chil
|
|||
|
||||
void GroupTreeViewItem::showDocument()
|
||||
{
|
||||
ProjectContentComponent* pcc = getProjectContentComponent();
|
||||
|
||||
if (pcc != nullptr)
|
||||
if (ProjectContentComponent* pcc = getProjectContentComponent())
|
||||
pcc->setEditorComponent (new GroupInformationComponent (item), nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -243,8 +237,7 @@ void SourceFileTreeViewItem::showPopupMenu()
|
|||
{
|
||||
PopupMenu m;
|
||||
|
||||
GroupTreeViewItem* parentGroup = dynamic_cast <GroupTreeViewItem*> (getParentProjectItem());
|
||||
if (parentGroup != nullptr)
|
||||
if (GroupTreeViewItem* parentGroup = dynamic_cast <GroupTreeViewItem*> (getParentProjectItem()))
|
||||
{
|
||||
parentGroup->addCreateFileMenuItems (m);
|
||||
m.addSeparator();
|
||||
|
|
@ -267,8 +260,6 @@ void SourceFileTreeViewItem::showPopupMenu()
|
|||
|
||||
void SourceFileTreeViewItem::handlePopupMenuResult (int resultCode)
|
||||
{
|
||||
GroupTreeViewItem* parentGroup = dynamic_cast <GroupTreeViewItem*> (getParentProjectItem());
|
||||
|
||||
switch (resultCode)
|
||||
{
|
||||
case 1: getFile().startAsProcess(); break;
|
||||
|
|
@ -277,7 +268,7 @@ void SourceFileTreeViewItem::handlePopupMenuResult (int resultCode)
|
|||
case 4: triggerAsyncRename (item); break;
|
||||
|
||||
default:
|
||||
if (parentGroup != nullptr)
|
||||
if (GroupTreeViewItem* parentGroup = dynamic_cast <GroupTreeViewItem*> (getParentProjectItem()))
|
||||
parentGroup->processCreateFileMenuItem (resultCode);
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -49,17 +49,10 @@ public:
|
|||
const ModifierKeys mods (ModifierKeys::getCurrentModifiers());
|
||||
|
||||
if (! mods.isAnyMouseButtonDown())
|
||||
{
|
||||
Component* comp = Desktop::getInstance().findComponentAt (screenPos);
|
||||
|
||||
if (comp != nullptr)
|
||||
{
|
||||
ComponentPeer* const peer = comp->getPeer();
|
||||
|
||||
if (peer != nullptr && ! peer->isFocused())
|
||||
peer->handleMouseEvent (0, screenPos - peer->getScreenPosition(), mods, Time::currentTimeMillis());
|
||||
}
|
||||
}
|
||||
if (Component* const comp = Desktop::getInstance().findComponentAt (screenPos))
|
||||
if (ComponentPeer* const peer = comp->getPeer())
|
||||
if (! peer->isFocused())
|
||||
peer->handleMouseEvent (0, screenPos - peer->getScreenPosition(), mods, Time::currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ ApplicationCommandManager::ApplicationCommandManager()
|
|||
: firstTarget (nullptr)
|
||||
{
|
||||
keyMappings = new KeyPressMappingSet (this);
|
||||
|
||||
Desktop::getInstance().addFocusChangeListener (this);
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +64,7 @@ void ApplicationCommandManager::registerCommand (const ApplicationCommandInfo& n
|
|||
}
|
||||
else
|
||||
{
|
||||
// trying to re-register the same command with different parameters?
|
||||
// trying to re-register the same command ID with different parameters?
|
||||
jassert (newCommand.shortName == getCommandForID (newCommand.commandID)->shortName
|
||||
&& (newCommand.description == getCommandForID (newCommand.commandID)->description || newCommand.description.isEmpty())
|
||||
&& newCommand.categoryName == getCommandForID (newCommand.commandID)->categoryName
|
||||
|
|
@ -169,26 +168,24 @@ bool ApplicationCommandManager::invokeDirectly (const CommandID commandID, const
|
|||
return invoke (info, asynchronously);
|
||||
}
|
||||
|
||||
bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::InvocationInfo& info_, const bool asynchronously)
|
||||
bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::InvocationInfo& inf, const bool asynchronously)
|
||||
{
|
||||
// This call isn't thread-safe for use from a non-UI thread without locking the message
|
||||
// manager first..
|
||||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
|
||||
bool ok = false;
|
||||
ApplicationCommandInfo commandInfo (0);
|
||||
ApplicationCommandTarget* const target = getTargetForCommand (info_.commandID, commandInfo);
|
||||
|
||||
if (target == nullptr)
|
||||
return false;
|
||||
if (ApplicationCommandTarget* const target = getTargetForCommand (inf.commandID, commandInfo))
|
||||
{
|
||||
ApplicationCommandTarget::InvocationInfo info (inf);
|
||||
info.commandFlags = commandInfo.flags;
|
||||
|
||||
ApplicationCommandTarget::InvocationInfo info (info_);
|
||||
info.commandFlags = commandInfo.flags;
|
||||
|
||||
sendListenerInvokeCallback (info);
|
||||
|
||||
const bool ok = target->invoke (info, asynchronously);
|
||||
|
||||
commandStatusChanged();
|
||||
sendListenerInvokeCallback (info);
|
||||
ok = target->invoke (info, asynchronously);
|
||||
commandStatusChanged();
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
|
@ -239,9 +236,7 @@ ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget(
|
|||
|
||||
if (c == nullptr)
|
||||
{
|
||||
TopLevelWindow* const activeWindow = TopLevelWindow::getActiveTopLevelWindow();
|
||||
|
||||
if (activeWindow != nullptr)
|
||||
if (TopLevelWindow* const activeWindow = TopLevelWindow::getActiveTopLevelWindow())
|
||||
{
|
||||
c = activeWindow->getPeer()->getLastFocusedSubcomponent();
|
||||
|
||||
|
|
@ -252,16 +247,11 @@ ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget(
|
|||
|
||||
if (c == nullptr && Process::isForegroundProcess())
|
||||
{
|
||||
// getting a bit desperate now - try all desktop comps..
|
||||
// getting a bit desperate now: try all desktop comps..
|
||||
for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
|
||||
{
|
||||
ApplicationCommandTarget* const target
|
||||
= findTargetForComponent (Desktop::getInstance().getComponent (i)
|
||||
->getPeer()->getLastFocusedSubcomponent());
|
||||
|
||||
if (target != nullptr)
|
||||
if (ApplicationCommandTarget* const target = findTargetForComponent (Desktop::getInstance().getComponent (i)
|
||||
->getPeer()->getLastFocusedSubcomponent()))
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
if (c != nullptr)
|
||||
|
|
@ -275,9 +265,7 @@ ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget(
|
|||
if (resizableWindow != nullptr && resizableWindow->getContentComponent() != nullptr)
|
||||
c = resizableWindow->getContentComponent();
|
||||
|
||||
ApplicationCommandTarget* const target = findTargetForComponent (c);
|
||||
|
||||
if (target != nullptr)
|
||||
if (ApplicationCommandTarget* const target = findTargetForComponent (c))
|
||||
return target;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,13 +109,11 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
/** Clears the current list of all commands.
|
||||
|
||||
Note that this will also clear the contents of the KeyPressMappingSet.
|
||||
*/
|
||||
void clearCommands();
|
||||
|
||||
/** Adds a command to the list of registered commands.
|
||||
|
||||
@see registerAllCommandsForTarget
|
||||
*/
|
||||
void registerCommand (const ApplicationCommandInfo& newCommand);
|
||||
|
|
@ -131,7 +129,6 @@ public:
|
|||
void registerAllCommandsForTarget (ApplicationCommandTarget* target);
|
||||
|
||||
/** Removes the command with a specified ID.
|
||||
|
||||
Note that this will also remove any key mappings that are mapped to the command.
|
||||
*/
|
||||
void removeCommand (CommandID commandID);
|
||||
|
|
@ -150,13 +147,11 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
/** Returns the number of commands that have been registered.
|
||||
|
||||
@see registerCommand
|
||||
*/
|
||||
int getNumCommands() const noexcept { return commands.size(); }
|
||||
|
||||
/** Returns the details about one of the registered commands.
|
||||
|
||||
The index is between 0 and (getNumCommands() - 1).
|
||||
*/
|
||||
const ApplicationCommandInfo* getCommandForIndex (int index) const noexcept { return commands [index]; }
|
||||
|
|
@ -195,7 +190,6 @@ public:
|
|||
StringArray getCommandCategories() const;
|
||||
|
||||
/** Returns a list of all the command UIDs in a particular category.
|
||||
|
||||
@see getCommandCategories()
|
||||
*/
|
||||
Array<CommandID> getCommandsInCategory (const String& categoryName) const;
|
||||
|
|
@ -214,7 +208,6 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
/** Invokes the given command directly, sending it to the default target.
|
||||
|
||||
This is just an easy way to call invoke() without having to fill out the InvocationInfo
|
||||
structure.
|
||||
*/
|
||||
|
|
@ -318,7 +311,7 @@ private:
|
|||
ScopedPointer <KeyPressMappingSet> keyMappings;
|
||||
ApplicationCommandTarget* firstTarget;
|
||||
|
||||
void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info);
|
||||
void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo&);
|
||||
void handleAsyncUpdate();
|
||||
void globalFocusChanged (Component*);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,15 +26,14 @@
|
|||
class ApplicationCommandTarget::CommandMessage : public MessageManager::MessageBase
|
||||
{
|
||||
public:
|
||||
CommandMessage (ApplicationCommandTarget* const owner_, const InvocationInfo& info_)
|
||||
: owner (owner_), info (info_)
|
||||
CommandMessage (ApplicationCommandTarget* const target, const InvocationInfo& inf)
|
||||
: owner (target), info (inf)
|
||||
{
|
||||
}
|
||||
|
||||
void messageCallback()
|
||||
{
|
||||
ApplicationCommandTarget* const target = owner;
|
||||
if (target != nullptr)
|
||||
if (ApplicationCommandTarget* const target = owner)
|
||||
target->tryToInvoke (info, false);
|
||||
}
|
||||
|
||||
|
|
@ -69,9 +68,9 @@ bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bo
|
|||
{
|
||||
const bool success = perform (info);
|
||||
|
||||
jassert (success); // hmm - your target should have been able to perform this command. If it can't
|
||||
// do it at the moment for some reason, it should clear the 'isActive' flag when it
|
||||
// returns the command's info.
|
||||
jassert (success); // Hmm.. your target claimed that it could perform this command, but failed to do so.
|
||||
// If it can't do it at the moment for some reason, it should clear the 'isActive' flag
|
||||
// when it returns the command's info.
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
|
@ -81,9 +80,7 @@ bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bo
|
|||
|
||||
ApplicationCommandTarget* ApplicationCommandTarget::findFirstTargetParentComponent()
|
||||
{
|
||||
Component* c = dynamic_cast <Component*> (this);
|
||||
|
||||
if (c != nullptr)
|
||||
if (Component* const c = dynamic_cast <Component*> (this))
|
||||
return c->findParentComponentOfClass<ApplicationCommandTarget>();
|
||||
|
||||
return nullptr;
|
||||
|
|
@ -180,8 +177,8 @@ bool ApplicationCommandTarget::invokeDirectly (const CommandID commandID, const
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
ApplicationCommandTarget::InvocationInfo::InvocationInfo (const CommandID commandID_)
|
||||
: commandID (commandID_),
|
||||
ApplicationCommandTarget::InvocationInfo::InvocationInfo (const CommandID command)
|
||||
: commandID (command),
|
||||
commandFlags (0),
|
||||
invocationMethod (direct),
|
||||
originatingComponent (nullptr),
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
/**
|
||||
Contains contextual details about the invocation of a command.
|
||||
*/
|
||||
struct JUCE_API InvocationInfo
|
||||
{
|
||||
|
|
@ -68,7 +69,6 @@ public:
|
|||
CommandID commandID;
|
||||
|
||||
/** The command's flags.
|
||||
|
||||
See ApplicationCommandInfo for a description of these flag values.
|
||||
*/
|
||||
int commandFlags;
|
||||
|
|
@ -124,7 +124,7 @@ public:
|
|||
that command, this method is used to determine the next target that should
|
||||
be tried.
|
||||
|
||||
It may return 0 if it doesn't know of another target.
|
||||
It may return nullptr if it doesn't know of another target.
|
||||
|
||||
If your target is a Component, you would usually use the findFirstTargetParentComponent()
|
||||
method to return a parent component that might want to handle it.
|
||||
|
|
|
|||
|
|
@ -776,11 +776,8 @@ public:
|
|||
TargetClass* findParentComponentOfClass() const
|
||||
{
|
||||
for (Component* p = parentComponent; p != nullptr; p = p->parentComponent)
|
||||
{
|
||||
TargetClass* const target = dynamic_cast <TargetClass*> (p);
|
||||
if (target != nullptr)
|
||||
if (TargetClass* const target = dynamic_cast <TargetClass*> (p))
|
||||
return target;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,6 +368,7 @@ CodeEditorComponent::CodeEditorComponent (CodeDocument& doc, CodeTokeniser* cons
|
|||
selectionEnd (doc, 0, 0),
|
||||
verticalScrollBar (true),
|
||||
horizontalScrollBar (false),
|
||||
appCommandManager (nullptr),
|
||||
codeTokeniser (tokeniser)
|
||||
{
|
||||
pimpl = new Pimpl (*this);
|
||||
|
|
@ -590,6 +591,7 @@ void CodeEditorComponent::moveCaretTo (const CodeDocument::Position& newPos, con
|
|||
{
|
||||
caretPos = newPos;
|
||||
columnToTryToMaintain = -1;
|
||||
bool selectionWasActive = isHighlightActive();
|
||||
|
||||
if (highlighting)
|
||||
{
|
||||
|
|
@ -639,6 +641,9 @@ void CodeEditorComponent::moveCaretTo (const CodeDocument::Position& newPos, con
|
|||
updateCaretPosition();
|
||||
scrollToKeepCaretOnScreen();
|
||||
updateScrollBars();
|
||||
|
||||
if (appCommandManager != nullptr && selectionWasActive != isHighlightActive())
|
||||
appCommandManager->commandStatusChanged();
|
||||
}
|
||||
|
||||
void CodeEditorComponent::deselectAll()
|
||||
|
|
@ -1142,6 +1147,11 @@ void CodeEditorComponent::newTransaction()
|
|||
pimpl->startTimer (600);
|
||||
}
|
||||
|
||||
void CodeEditorComponent::setCommandManager (ApplicationCommandManager* newManager) noexcept
|
||||
{
|
||||
appCommandManager = newManager;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Range<int> CodeEditorComponent::getHighlightedRegion() const
|
||||
{
|
||||
|
|
@ -1199,22 +1209,82 @@ void CodeEditorComponent::handleEscapeKey()
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void CodeEditorComponent::addPopupMenuItems (PopupMenu& m, const MouseEvent*)
|
||||
ApplicationCommandTarget* CodeEditorComponent::getNextCommandTarget()
|
||||
{
|
||||
m.addItem (StandardApplicationCommandIDs::cut, TRANS("Cut"));
|
||||
m.addItem (StandardApplicationCommandIDs::copy, TRANS("Copy"), ! getHighlightedRegion().isEmpty());
|
||||
m.addItem (StandardApplicationCommandIDs::paste, TRANS("Paste"));
|
||||
m.addItem (StandardApplicationCommandIDs::del, TRANS("Delete"));
|
||||
m.addSeparator();
|
||||
m.addItem (StandardApplicationCommandIDs::selectAll, TRANS("Select All"));
|
||||
m.addSeparator();
|
||||
m.addItem (StandardApplicationCommandIDs::undo, TRANS("Undo"), document.getUndoManager().canUndo());
|
||||
m.addItem (StandardApplicationCommandIDs::redo, TRANS("Redo"), document.getUndoManager().canRedo());
|
||||
return findFirstTargetParentComponent();
|
||||
}
|
||||
|
||||
void CodeEditorComponent::performPopupMenuAction (const int menuItemID)
|
||||
void CodeEditorComponent::getAllCommands (Array <CommandID>& commands)
|
||||
{
|
||||
switch (menuItemID)
|
||||
const CommandID ids[] = { StandardApplicationCommandIDs::cut,
|
||||
StandardApplicationCommandIDs::copy,
|
||||
StandardApplicationCommandIDs::paste,
|
||||
StandardApplicationCommandIDs::del,
|
||||
StandardApplicationCommandIDs::selectAll,
|
||||
StandardApplicationCommandIDs::undo,
|
||||
StandardApplicationCommandIDs::redo };
|
||||
|
||||
commands.addArray (ids, numElementsInArray (ids));
|
||||
}
|
||||
|
||||
void CodeEditorComponent::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
|
||||
{
|
||||
const bool anythingSelected = isHighlightActive();
|
||||
|
||||
switch (commandID)
|
||||
{
|
||||
case StandardApplicationCommandIDs::cut:
|
||||
result.setInfo (TRANS ("Cut"), TRANS ("Copies the currently selected text to the clipboard and deletes it."), "Editing", 0);
|
||||
result.setActive (anythingSelected);
|
||||
result.defaultKeypresses.add (KeyPress ('x', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case StandardApplicationCommandIDs::copy:
|
||||
result.setInfo (TRANS ("Copy"), TRANS ("Copies the currently selected text to the clipboard."), "Editing", 0);
|
||||
result.setActive (anythingSelected);
|
||||
result.defaultKeypresses.add (KeyPress ('c', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case StandardApplicationCommandIDs::paste:
|
||||
result.setInfo (TRANS ("Paste"), TRANS ("Inserts text from the clipboard."), "Editing", 0);
|
||||
result.defaultKeypresses.add (KeyPress ('v', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case StandardApplicationCommandIDs::del:
|
||||
result.setInfo (TRANS ("Delete"), TRANS ("Deletes any selected text."), "Editing", 0);
|
||||
result.setActive (anythingSelected);
|
||||
break;
|
||||
|
||||
case StandardApplicationCommandIDs::selectAll:
|
||||
result.setInfo (TRANS ("Select All"), TRANS ("Selects all the text in the editor."), "Editing", 0);
|
||||
result.defaultKeypresses.add (KeyPress ('a', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case StandardApplicationCommandIDs::undo:
|
||||
result.setInfo (TRANS ("Undo"), TRANS ("Undo"), "Editing", 0);
|
||||
result.defaultKeypresses.add (KeyPress ('z', ModifierKeys::commandModifier, 0));
|
||||
result.setActive (document.getUndoManager().canUndo());
|
||||
break;
|
||||
|
||||
case StandardApplicationCommandIDs::redo:
|
||||
result.setInfo (TRANS ("Redo"), TRANS ("Redo"), "Editing", 0);
|
||||
result.defaultKeypresses.add (KeyPress ('z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));
|
||||
result.setActive (document.getUndoManager().canRedo());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CodeEditorComponent::perform (const InvocationInfo& info)
|
||||
{
|
||||
return performCommand (info.commandID);
|
||||
}
|
||||
|
||||
bool CodeEditorComponent::performCommand (const int commandID)
|
||||
{
|
||||
switch (commandID)
|
||||
{
|
||||
case StandardApplicationCommandIDs::cut: cutToClipboard(); break;
|
||||
case StandardApplicationCommandIDs::copy: copyToClipboard(); break;
|
||||
|
|
@ -1223,8 +1293,29 @@ void CodeEditorComponent::performPopupMenuAction (const int menuItemID)
|
|||
case StandardApplicationCommandIDs::selectAll: selectAll(); break;
|
||||
case StandardApplicationCommandIDs::undo: undo(); break;
|
||||
case StandardApplicationCommandIDs::redo: redo(); break;
|
||||
default: break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void CodeEditorComponent::addPopupMenuItems (PopupMenu& m, const MouseEvent*)
|
||||
{
|
||||
m.addItem (StandardApplicationCommandIDs::cut, TRANS ("Cut"));
|
||||
m.addItem (StandardApplicationCommandIDs::copy, TRANS ("Copy"), ! getHighlightedRegion().isEmpty());
|
||||
m.addItem (StandardApplicationCommandIDs::paste, TRANS ("Paste"));
|
||||
m.addItem (StandardApplicationCommandIDs::del, TRANS ("Delete"));
|
||||
m.addSeparator();
|
||||
m.addItem (StandardApplicationCommandIDs::selectAll, TRANS ("Select All"));
|
||||
m.addSeparator();
|
||||
m.addItem (StandardApplicationCommandIDs::undo, TRANS ("Undo"), document.getUndoManager().canUndo());
|
||||
m.addItem (StandardApplicationCommandIDs::redo, TRANS ("Redo"), document.getUndoManager().canRedo());
|
||||
}
|
||||
|
||||
void CodeEditorComponent::performPopupMenuAction (const int menuItemID)
|
||||
{
|
||||
performCommand (menuItemID);
|
||||
}
|
||||
|
||||
static void codeEditorMenuCallback (int menuResult, CodeEditorComponent* editor)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class CodeTokeniser;
|
|||
files.
|
||||
*/
|
||||
class JUCE_API CodeEditorComponent : public Component,
|
||||
public ApplicationCommandTarget,
|
||||
public TextInputTarget
|
||||
{
|
||||
public:
|
||||
|
|
@ -300,6 +301,15 @@ public:
|
|||
*/
|
||||
virtual void performPopupMenuAction (int menuItemID);
|
||||
|
||||
/** Specifies a commmand-manager which the editor will notify whenever the state
|
||||
of any of its commands changes.
|
||||
If you're making use of the editor's ApplicationCommandTarget interface, then
|
||||
you should also use this to tell it which command manager it should use. Make
|
||||
sure that the manager does not go out of scope while the editor is using it. You
|
||||
can pass a nullptr here to disable this.
|
||||
*/
|
||||
void setCommandManager (ApplicationCommandManager* newManager) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&);
|
||||
|
|
@ -325,6 +335,14 @@ public:
|
|||
bool isTextInputActive() const;
|
||||
/** @internal */
|
||||
void setTemporaryUnderlining (const Array <Range<int> >&);
|
||||
/** @internal */
|
||||
ApplicationCommandTarget* getNextCommandTarget();
|
||||
/** @internal */
|
||||
void getAllCommands (Array<CommandID>&);
|
||||
/** @internal */
|
||||
void getCommandInfo (CommandID, ApplicationCommandInfo&);
|
||||
/** @internal */
|
||||
bool perform (const InvocationInfo&);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
|
|
@ -342,6 +360,7 @@ private:
|
|||
|
||||
ScopedPointer<CaretComponent> caret;
|
||||
ScrollBar verticalScrollBar, horizontalScrollBar;
|
||||
ApplicationCommandManager* appCommandManager;
|
||||
|
||||
class Pimpl;
|
||||
friend class Pimpl;
|
||||
|
|
@ -375,13 +394,13 @@ private:
|
|||
OwnedArray <CodeDocument::Iterator> cachedIterators;
|
||||
void clearCachedIterators (int firstLineToBeInvalid);
|
||||
void updateCachedIterators (int maxLineNum);
|
||||
void getIteratorForPosition (int position, CodeDocument::Iterator& result);
|
||||
void getIteratorForPosition (int position, CodeDocument::Iterator&);
|
||||
|
||||
void moveLineDelta (int delta, bool selecting);
|
||||
int getGutterSize() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
void insertText (const String& textToInsert);
|
||||
void insertText (const String&);
|
||||
void updateCaretPosition();
|
||||
void updateScrollBars();
|
||||
void scrollToLineInternal (int line);
|
||||
|
|
@ -390,6 +409,7 @@ private:
|
|||
void cut();
|
||||
void indentSelectedLines (int spacesToAdd);
|
||||
bool skipBackwardsToPreviousTab();
|
||||
bool performCommand (int);
|
||||
|
||||
int indexToColumn (int line, int index) const noexcept;
|
||||
int columnToIndex (int line, int column) const noexcept;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue