1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-13 00:04:19 +00:00

Added Animated App template and examples

This commit is contained in:
Felix Faire 2014-10-29 15:55:23 +00:00
parent fefcf7aca6
commit ff6520a89a
1141 changed files with 438491 additions and 94 deletions

View file

@ -0,0 +1,303 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
struct UndoManager::ActionSet
{
ActionSet (const String& transactionName)
: name (transactionName),
time (Time::getCurrentTime())
{}
bool perform() const
{
for (int i = 0; i < actions.size(); ++i)
if (! actions.getUnchecked(i)->perform())
return false;
return true;
}
bool undo() const
{
for (int i = actions.size(); --i >= 0;)
if (! actions.getUnchecked(i)->undo())
return false;
return true;
}
int getTotalSize() const
{
int total = 0;
for (int i = actions.size(); --i >= 0;)
total += actions.getUnchecked(i)->getSizeInUnits();
return total;
}
OwnedArray<UndoableAction> actions;
String name;
Time time;
};
//==============================================================================
UndoManager::UndoManager (const int maxNumberOfUnitsToKeep,
const int minimumTransactions)
: totalUnitsStored (0),
nextIndex (0),
newTransaction (true),
reentrancyCheck (false)
{
setMaxNumberOfStoredUnits (maxNumberOfUnitsToKeep,
minimumTransactions);
}
UndoManager::~UndoManager()
{
}
//==============================================================================
void UndoManager::clearUndoHistory()
{
transactions.clear();
totalUnitsStored = 0;
nextIndex = 0;
sendChangeMessage();
}
int UndoManager::getNumberOfUnitsTakenUpByStoredCommands() const
{
return totalUnitsStored;
}
void UndoManager::setMaxNumberOfStoredUnits (const int maxNumberOfUnitsToKeep,
const int minimumTransactions)
{
maxNumUnitsToKeep = jmax (1, maxNumberOfUnitsToKeep);
minimumTransactionsToKeep = jmax (1, minimumTransactions);
}
//==============================================================================
bool UndoManager::perform (UndoableAction* const newAction, const String& actionName)
{
if (perform (newAction))
{
if (actionName.isNotEmpty())
setCurrentTransactionName (actionName);
return true;
}
return false;
}
bool UndoManager::perform (UndoableAction* const newAction)
{
if (newAction != nullptr)
{
ScopedPointer<UndoableAction> action (newAction);
if (reentrancyCheck)
{
jassertfalse; // don't call perform() recursively from the UndoableAction::perform()
// or undo() methods, or else these actions will be discarded!
return false;
}
if (action->perform())
{
ActionSet* actionSet = getCurrentSet();
if (actionSet != nullptr && ! newTransaction)
{
if (UndoableAction* const lastAction = actionSet->actions.getLast())
{
if (UndoableAction* const coalescedAction = lastAction->createCoalescedAction (action))
{
action = coalescedAction;
totalUnitsStored -= lastAction->getSizeInUnits();
actionSet->actions.removeLast();
}
}
}
else
{
actionSet = new ActionSet (newTransactionName);
transactions.insert (nextIndex, actionSet);
++nextIndex;
}
totalUnitsStored += action->getSizeInUnits();
actionSet->actions.add (action.release());
newTransaction = false;
clearFutureTransactions();
sendChangeMessage();
return true;
}
}
return false;
}
void UndoManager::clearFutureTransactions()
{
while (nextIndex < transactions.size())
{
totalUnitsStored -= transactions.getLast()->getTotalSize();
transactions.removeLast();
}
while (nextIndex > 0
&& totalUnitsStored > maxNumUnitsToKeep
&& transactions.size() > minimumTransactionsToKeep)
{
totalUnitsStored -= transactions.getFirst()->getTotalSize();
transactions.remove (0);
--nextIndex;
// if this fails, then some actions may not be returning
// consistent results from their getSizeInUnits() method
jassert (totalUnitsStored >= 0);
}
}
void UndoManager::beginNewTransaction() noexcept
{
beginNewTransaction (String());
}
void UndoManager::beginNewTransaction (const String& actionName) noexcept
{
newTransaction = true;
newTransactionName = actionName;
}
void UndoManager::setCurrentTransactionName (const String& newName) noexcept
{
if (newTransaction)
newTransactionName = newName;
else if (ActionSet* action = getCurrentSet())
action->name = newName;
}
//==============================================================================
UndoManager::ActionSet* UndoManager::getCurrentSet() const noexcept { return transactions [nextIndex - 1]; }
UndoManager::ActionSet* UndoManager::getNextSet() const noexcept { return transactions [nextIndex]; }
bool UndoManager::canUndo() const noexcept { return getCurrentSet() != nullptr; }
bool UndoManager::canRedo() const noexcept { return getNextSet() != nullptr; }
bool UndoManager::undo()
{
if (const ActionSet* const s = getCurrentSet())
{
const ScopedValueSetter<bool> setter (reentrancyCheck, true);
if (s->undo())
--nextIndex;
else
clearUndoHistory();
beginNewTransaction();
sendChangeMessage();
return true;
}
return false;
}
bool UndoManager::redo()
{
if (const ActionSet* const s = getNextSet())
{
const ScopedValueSetter<bool> setter (reentrancyCheck, true);
if (s->perform())
++nextIndex;
else
clearUndoHistory();
beginNewTransaction();
sendChangeMessage();
return true;
}
return false;
}
String UndoManager::getUndoDescription() const
{
if (const ActionSet* const s = getCurrentSet())
return s->name;
return String();
}
String UndoManager::getRedoDescription() const
{
if (const ActionSet* const s = getNextSet())
return s->name;
return String();
}
Time UndoManager::getTimeOfUndoTransaction() const
{
if (const ActionSet* const s = getCurrentSet())
return s->time;
return Time();
}
Time UndoManager::getTimeOfRedoTransaction() const
{
if (const ActionSet* const s = getNextSet())
return s->time;
return Time::getCurrentTime();
}
bool UndoManager::undoCurrentTransactionOnly()
{
return newTransaction ? false : undo();
}
void UndoManager::getActionsInCurrentTransaction (Array<const UndoableAction*>& actionsFound) const
{
if (! newTransaction)
if (const ActionSet* const s = getCurrentSet())
for (int i = 0; i < s->actions.size(); ++i)
actionsFound.add (s->actions.getUnchecked(i));
}
int UndoManager::getNumActionsInCurrentTransaction() const
{
if (! newTransaction)
if (const ActionSet* const s = getCurrentSet())
return s->actions.size();
return 0;
}

View file

@ -0,0 +1,239 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_UNDOMANAGER_H_INCLUDED
#define JUCE_UNDOMANAGER_H_INCLUDED
//==============================================================================
/**
Manages a list of undo/redo commands.
An UndoManager object keeps a list of past actions and can use these actions
to move backwards and forwards through an undo history.
To use it, create subclasses of UndoableAction which perform all the
actions you need, then when you need to actually perform an action, create one
and pass it to the UndoManager's perform() method.
The manager also uses the concept of 'transactions' to group the actions
together - all actions performed between calls to beginNewTransaction() are
grouped together and are all undone/redone as a group.
The UndoManager is a ChangeBroadcaster, so listeners can register to be told
when actions are performed or undone.
@see UndoableAction
*/
class JUCE_API UndoManager : public ChangeBroadcaster
{
public:
//==============================================================================
/** Creates an UndoManager.
@param maxNumberOfUnitsToKeep each UndoableAction object returns a value
to indicate how much storage it takes up
(UndoableAction::getSizeInUnits()), so this
lets you specify the maximum total number of
units that the undomanager is allowed to
keep in memory before letting the older actions
drop off the end of the list.
@param minimumTransactionsToKeep this specifies the minimum number of transactions
that will be kept, even if this involves exceeding
the amount of space specified in maxNumberOfUnitsToKeep
*/
UndoManager (int maxNumberOfUnitsToKeep = 30000,
int minimumTransactionsToKeep = 30);
/** Destructor. */
~UndoManager();
//==============================================================================
/** Deletes all stored actions in the list. */
void clearUndoHistory();
/** Returns the current amount of space to use for storing UndoableAction objects.
@see setMaxNumberOfStoredUnits
*/
int getNumberOfUnitsTakenUpByStoredCommands() const;
/** Sets the amount of space that can be used for storing UndoableAction objects.
@param maxNumberOfUnitsToKeep each UndoableAction object returns a value
to indicate how much storage it takes up
(UndoableAction::getSizeInUnits()), so this
lets you specify the maximum total number of
units that the undomanager is allowed to
keep in memory before letting the older actions
drop off the end of the list.
@param minimumTransactionsToKeep this specifies the minimum number of transactions
that will be kept, even if this involves exceeding
the amount of space specified in maxNumberOfUnitsToKeep
@see getNumberOfUnitsTakenUpByStoredCommands
*/
void setMaxNumberOfStoredUnits (int maxNumberOfUnitsToKeep,
int minimumTransactionsToKeep);
//==============================================================================
/** Performs an action and adds it to the undo history list.
@param action the action to perform - this object will be deleted by
the UndoManager when no longer needed
@returns true if the command succeeds - see UndoableAction::perform
@see beginNewTransaction
*/
bool perform (UndoableAction* action);
/** Performs an action and also gives it a name.
@param action the action to perform - this object will be deleted by
the UndoManager when no longer needed
@param actionName if this string is non-empty, the current transaction will be
given this name; if it's empty, the current transaction name will
be left unchanged. See setCurrentTransactionName()
@returns true if the command succeeds - see UndoableAction::perform
@see beginNewTransaction
*/
bool perform (UndoableAction* action, const String& actionName);
/** Starts a new group of actions that together will be treated as a single transaction.
All actions that are passed to the perform() method between calls to this
method are grouped together and undone/redone together by a single call to
undo() or redo().
*/
void beginNewTransaction() noexcept;
/** Starts a new group of actions that together will be treated as a single transaction.
All actions that are passed to the perform() method between calls to this
method are grouped together and undone/redone together by a single call to
undo() or redo().
@param actionName a description of the transaction that is about to be
performed
*/
void beginNewTransaction (const String& actionName) noexcept;
/** Changes the name stored for the current transaction.
Each transaction is given a name when the beginNewTransaction() method is
called, but this can be used to change that name without starting a new
transaction.
*/
void setCurrentTransactionName (const String& newName) noexcept;
//==============================================================================
/** Returns true if there's at least one action in the list to undo.
@see getUndoDescription, undo, canRedo
*/
bool canUndo() const noexcept;
/** Returns the name of the transaction that will be rolled-back when undo() is called.
@see undo
*/
String getUndoDescription() const;
/** Tries to roll-back the last transaction.
@returns true if the transaction can be undone, and false if it fails, or
if there aren't any transactions to undo
*/
bool undo();
/** Tries to roll-back any actions that were added to the current transaction.
This will perform an undo() only if there are some actions in the undo list
that were added after the last call to beginNewTransaction().
This is useful because it lets you call beginNewTransaction(), then
perform an operation which may or may not actually perform some actions, and
then call this method to get rid of any actions that might have been done
without it rolling back the previous transaction if nothing was actually
done.
@returns true if any actions were undone.
*/
bool undoCurrentTransactionOnly();
/** Returns a list of the UndoableAction objects that have been performed during the
transaction that is currently open.
Effectively, this is the list of actions that would be undone if undoCurrentTransactionOnly()
were to be called now.
The first item in the list is the earliest action performed.
*/
void getActionsInCurrentTransaction (Array<const UndoableAction*>& actionsFound) const;
/** Returns the number of UndoableAction objects that have been performed during the
transaction that is currently open.
@see getActionsInCurrentTransaction
*/
int getNumActionsInCurrentTransaction() const;
/** Returns the time to which the state would be restored if undo() was to be called.
If an undo isn't currently possible, it'll return Time().
*/
Time getTimeOfUndoTransaction() const;
/** Returns the time to which the state would be restored if redo() was to be called.
If a redo isn't currently possible, it'll return Time::getCurrentTime().
*/
Time getTimeOfRedoTransaction() const;
//==============================================================================
/** Returns true if there's at least one action in the list to redo.
@see getRedoDescription, redo, canUndo
*/
bool canRedo() const noexcept;
/** Returns the name of the transaction that will be redone when redo() is called.
@see redo
*/
String getRedoDescription() const;
/** Tries to redo the last transaction that was undone.
@returns true if the transaction can be redone, and false if it fails, or
if there aren't any transactions to redo
*/
bool redo();
private:
//==============================================================================
struct ActionSet;
friend struct ContainerDeletePolicy<ActionSet>;
OwnedArray<ActionSet> transactions;
String newTransactionName;
int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex;
bool newTransaction, reentrancyCheck;
ActionSet* getCurrentSet() const noexcept;
ActionSet* getNextSet() const noexcept;
void clearFutureTransactions();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager)
};
#endif // JUCE_UNDOMANAGER_H_INCLUDED

View file

@ -0,0 +1,99 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_UNDOABLEACTION_H_INCLUDED
#define JUCE_UNDOABLEACTION_H_INCLUDED
//==============================================================================
/**
Used by the UndoManager class to store an action which can be done
and undone.
@see UndoManager
*/
class JUCE_API UndoableAction
{
protected:
/** Creates an action. */
UndoableAction() noexcept {}
public:
/** Destructor. */
virtual ~UndoableAction() {}
//==============================================================================
/** Overridden by a subclass to perform the action.
This method is called by the UndoManager, and shouldn't be used directly by
applications.
Be careful not to make any calls in a perform() method that could call
recursively back into the UndoManager::perform() method
@returns true if the action could be performed.
@see UndoManager::perform
*/
virtual bool perform() = 0;
/** Overridden by a subclass to undo the action.
This method is called by the UndoManager, and shouldn't be used directly by
applications.
Be careful not to make any calls in an undo() method that could call
recursively back into the UndoManager::perform() method
@returns true if the action could be undone without any errors.
@see UndoManager::perform
*/
virtual bool undo() = 0;
//==============================================================================
/** Returns a value to indicate how much memory this object takes up.
Because the UndoManager keeps a list of UndoableActions, this is used
to work out how much space each one will take up, so that the UndoManager
can work out how many to keep.
The default value returned here is 10 - units are arbitrary and
don't have to be accurate.
@see UndoManager::getNumberOfUnitsTakenUpByStoredCommands,
UndoManager::setMaxNumberOfStoredUnits
*/
virtual int getSizeInUnits() { return 10; }
/** Allows multiple actions to be coalesced into a single action object, to reduce storage space.
If possible, this method should create and return a single action that does the same job as
this one followed by the supplied action.
If it's not possible to merge the two actions, the method should return zero.
*/
virtual UndoableAction* createCoalescedAction (UndoableAction* nextAction) { (void) nextAction; return nullptr; }
};
#endif // JUCE_UNDOABLEACTION_H_INCLUDED