805 lines
22 KiB
C++
805 lines
22 KiB
C++
#ifndef RESOURCE_PICKER_IMPLEMENTATION_INCLUDED
|
|
#define RESOURCE_PICKER_IMPLEMENTATION_INCLUDED
|
|
|
|
|
|
#include "ResourcePicker.h"
|
|
#include "resourceDatabase.h"
|
|
#include "resourceManager.h"
|
|
#include "usageDatabase.h"
|
|
#include "speechHints.h"
|
|
#include "Room.h"
|
|
#include "imageCache.h"
|
|
|
|
|
|
#include "minorGems/util/stringUtils.h"
|
|
#include "minorGems/util/log/AppLog.h"
|
|
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
extern TextGL *largeTextFixed;
|
|
|
|
|
|
template <class ResourceType>
|
|
ResourcePicker<ResourceType>::ResourcePicker(
|
|
double inAnchorX, double inAnchorY,
|
|
SimpleVector<uniqueID> *inStack )
|
|
: BorderPanel( inAnchorX, inAnchorY, 70, 93,
|
|
new Color( 0, 0, 0, 1 ),
|
|
new Color( 0.35, 0.35, 0.35, 1 ),
|
|
1 ),
|
|
mNumResourcesOnScreen( 0 ),
|
|
mSearchResultOffset( 0 ),
|
|
mNumSearchResults( 0 ),
|
|
mStackMode( false ),
|
|
mStack( inStack ) {
|
|
|
|
double tileSpace = P;
|
|
|
|
// room for button borders
|
|
double buttonSpace = tileSpace + 4;
|
|
|
|
// use same separation for both x and y
|
|
double buttonSeparation =
|
|
( mWidth - buttonSpace * mGridW ) / (mGridW + 1);
|
|
|
|
|
|
// put left and right at very bottom
|
|
mLeftButton = new LeftButtonGL( mAnchorX + buttonSeparation,
|
|
mAnchorY + buttonSeparation,
|
|
8, 8 );
|
|
add( mLeftButton );
|
|
mLeftButton->setEnabled( false );
|
|
mLeftButton->addActionListener( this );
|
|
|
|
|
|
mRightButton = new RightButtonGL( mAnchorX + mWidth - buttonSeparation - 8,
|
|
mAnchorY + buttonSeparation,
|
|
8, 8 );
|
|
add( mRightButton );
|
|
mRightButton->setEnabled( false );
|
|
mRightButton->addActionListener( this );
|
|
|
|
|
|
// centered above picker
|
|
mStackSearchButton = new StackSearchButtonGL( mAnchorX + (mWidth-8)/3 - 1,
|
|
mAnchorY + 1,
|
|
8, 8 );
|
|
add( mStackSearchButton );
|
|
mStackSearchButton->addActionListener( this );
|
|
|
|
|
|
double baseY = mAnchorY + buttonSeparation + 8;
|
|
|
|
|
|
|
|
double topButtonY = baseY + buttonSeparation +
|
|
mGridH * ( buttonSpace + buttonSeparation ) - buttonSpace;
|
|
|
|
|
|
for( int y=0; y<mGridH; y++ ) {
|
|
for( int x=0; x<mGridW; x++ ) {
|
|
|
|
mButtonGrid[y][x] = new DraggableTwoSpriteButtonGL(
|
|
NULL, NULL,
|
|
1,
|
|
mAnchorX + buttonSeparation +
|
|
(buttonSpace + buttonSeparation) * x,
|
|
topButtonY - buttonSeparation -
|
|
(buttonSpace + buttonSeparation) * y,
|
|
buttonSpace,
|
|
buttonSpace );
|
|
|
|
add( mButtonGrid[y][x] );
|
|
|
|
mButtonGrid[y][x]->setEnabled( false );
|
|
|
|
mButtonGrid[y][x]->addActionListener( this );
|
|
}
|
|
}
|
|
|
|
mLastActionFromPress = false;
|
|
|
|
|
|
|
|
int fieldHeight = 8;
|
|
int fieldWidth = 8 * 8;
|
|
|
|
const char *defaultSearch = "";
|
|
|
|
double fieldAnchorY = topButtonY + buttonSpace + 1;
|
|
|
|
mSearchField = new TextFieldGL( mAnchorX + 2,
|
|
fieldAnchorY,
|
|
fieldWidth,
|
|
fieldHeight,
|
|
1,
|
|
defaultSearch,
|
|
largeTextFixed,
|
|
new Color( 0.75, 0.75, 0.75 ),
|
|
new Color( 0.75, 0.75, 0.75 ),
|
|
new Color( 0.15, 0.15, 0.15 ),
|
|
new Color( 0.75, 0.75, 0.75 ),
|
|
8,
|
|
false );
|
|
add( mSearchField );
|
|
|
|
mSearchField->setFocus( false );
|
|
//mSearchField->lockFocus( true );
|
|
|
|
mSearchField->setCursorPosition( strlen( defaultSearch ) );
|
|
|
|
mSearchField->addActionListener( this );
|
|
|
|
|
|
|
|
|
|
mSelectedResourceButton = new DraggableTwoSpriteButtonGL(
|
|
NULL,
|
|
NULL,
|
|
1,
|
|
mAnchorX + mWidth - buttonSpace - 2,
|
|
mAnchorY + mHeight - buttonSpace - 2,
|
|
buttonSpace,
|
|
buttonSpace );
|
|
|
|
add( mSelectedResourceButton );
|
|
mSelectedResourceButton->setEnabled( true );
|
|
mSelectedResourceButton->addActionListener( this );
|
|
|
|
refreshSelectedResourceSprite();
|
|
|
|
|
|
|
|
mDeleteButton = new DeleteButtonGL(
|
|
mSelectedResourceButton->getAnchorX() - 8,
|
|
mAnchorY + mHeight - 10,
|
|
8, 8 );
|
|
add( mDeleteButton );
|
|
mDeleteButton->addActionListener( this );
|
|
mDeleteButton->setEnabled( false );
|
|
|
|
// concatonate
|
|
char *tipKey = autoSprintf( "tip_delete_%s",
|
|
ResourceType::getResourceType() );
|
|
|
|
mDeleteButton->setToolTip( tipKey );
|
|
delete [] tipKey;
|
|
|
|
|
|
|
|
EightPixelLabel *tileLabel =
|
|
new EightPixelLabel( mAnchorX + 2,
|
|
mAnchorY + mHeight - 8 - 2,
|
|
(char*)( ResourceType::getResourceType() ) );
|
|
add( tileLabel );
|
|
|
|
|
|
mSearchLabel = new EightPixelLabel( mAnchorX + 2,
|
|
fieldAnchorY +
|
|
fieldHeight + 1,
|
|
"search" );
|
|
add( mSearchLabel );
|
|
|
|
mStackLabel = new EightPixelLabel( mAnchorX + 2,
|
|
fieldAnchorY +
|
|
fieldHeight + 1,
|
|
"stack" );
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
ResourcePicker<ResourceType>::~ResourcePicker() {
|
|
|
|
if( !contains( mSearchLabel ) ) {
|
|
delete mSearchLabel;
|
|
}
|
|
if( !contains( mSearchField ) ) {
|
|
delete mSearchField;
|
|
}
|
|
if( !contains( mStackLabel ) ) {
|
|
delete mStackLabel;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
ResourceType ResourcePicker<ResourceType>::getSelectedResource() {
|
|
return mSelectedResource;
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
uniqueID ResourcePicker<ResourceType>::getSelectedResourceID() {
|
|
return mSelectedResource.getUniqueID();
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::refreshSelectedResourceSprite() {
|
|
Sprite *backgroundSprite = getButtonGridBackground();
|
|
|
|
char useTrans = false;
|
|
if( backgroundSprite != NULL ) {
|
|
useTrans = true;
|
|
}
|
|
|
|
|
|
mSelectedResourceButton->setFrontSprite(
|
|
mSelectedResource.getSprite( useTrans ) );
|
|
|
|
mSelectedResourceButton->setSprite( backgroundSprite );
|
|
|
|
char *tip = mSelectedResource.getName();
|
|
mSelectedResourceButton->setToolTip( tip, false );
|
|
delete [] tip;
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::recheckDeletable() {
|
|
if( equal( mSelectedResource.getUniqueID(),
|
|
ResourceType::getDefaultResource().getUniqueID() ) ) {
|
|
|
|
// can't delete blank
|
|
mDeleteButton->setEnabled( false );
|
|
}
|
|
else if( isUsed( mSelectedResource.getUniqueID() ) ) {
|
|
uniqueID user = getUser( mSelectedResource.getUniqueID() );
|
|
|
|
char *userName = getResourceName( user );
|
|
|
|
char *tip;
|
|
|
|
char *resourceName = mSelectedResource.getName();
|
|
|
|
if( userName != NULL ) {
|
|
|
|
tip = autoSprintf( "%s (used in %s)",
|
|
resourceName,
|
|
userName );
|
|
}
|
|
else {
|
|
tip = autoSprintf( "%s (used in current edit)",
|
|
resourceName );
|
|
}
|
|
delete [] resourceName;
|
|
|
|
|
|
mSelectedResourceButton->setToolTip( tip, false );
|
|
delete [] tip;
|
|
|
|
// can't delete a resource used elsewhere
|
|
mDeleteButton->setEnabled( false );
|
|
}
|
|
else {
|
|
// not default, and not used anywhere. Deletable!
|
|
mDeleteButton->setEnabled( true );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::setSelectedResource(
|
|
ResourceType inResource, char inForceResultRefresh, char inFireEvent ) {
|
|
|
|
if( !equal( mSelectedResource.getUniqueID(), inResource.getUniqueID() ) ) {
|
|
|
|
// a change
|
|
|
|
mSelectedResource = inResource;
|
|
|
|
refreshSelectedResourceSprite();
|
|
|
|
|
|
// remove from lower in stack
|
|
uniqueID id = mSelectedResource.getUniqueID();
|
|
char found = false;
|
|
int stackSize = mStack->size();
|
|
for( int i=0; i<stackSize && !found; i++ ) {
|
|
if( equal( id, *( mStack->getElement( i ) ) ) ) {
|
|
mStack->deleteElement( i );
|
|
found = true;
|
|
}
|
|
}
|
|
mStack->push_back( id );
|
|
|
|
if( mStack->size() > 256 ) {
|
|
// size limit reached
|
|
|
|
// delete oldest
|
|
mStack->deleteElement( 0 );
|
|
}
|
|
|
|
|
|
recheckDeletable();
|
|
|
|
|
|
if( mStackMode ) {
|
|
// back to top whenever top changes
|
|
mSearchResultOffset = 0;
|
|
}
|
|
|
|
|
|
if( inForceResultRefresh ) {
|
|
newSearch( true );
|
|
}
|
|
else if( mStackMode ) {
|
|
if( found ) {
|
|
// just stack order changed
|
|
getFreshResults();
|
|
}
|
|
else {
|
|
// something new added to stack... maybe a size change
|
|
newSearch( false );
|
|
}
|
|
}
|
|
|
|
|
|
if( inFireEvent ) {
|
|
mLastActionFromPress = false;
|
|
fireActionPerformed( this );
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::forceNewSearch() {
|
|
newSearch( false );
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::newSearch( char inPreservePageOffset,
|
|
char inMoveBackward ) {
|
|
|
|
char *search = stringDuplicate( mSearchField->getText() );
|
|
|
|
int numResults;
|
|
|
|
if( !mStackMode ) {
|
|
numResults = countSearchResults( ResourceType::getResourceType(),
|
|
search );
|
|
}
|
|
else {
|
|
numResults = countStackResults();
|
|
}
|
|
|
|
//printf( "New resource search, %d results\n", numResults );
|
|
|
|
delete [] search;
|
|
|
|
|
|
int oldOffset = mSearchResultOffset;
|
|
|
|
|
|
mNumSearchResults = numResults;
|
|
mSearchResultOffset = 0;
|
|
|
|
|
|
if( inPreservePageOffset ) {
|
|
if( oldOffset < numResults ) {
|
|
// still in range
|
|
mSearchResultOffset = oldOffset;
|
|
}
|
|
}
|
|
|
|
|
|
if( numResults > mNumResourcesDisplayedMax ) {
|
|
// scroll
|
|
numResults = mNumResourcesDisplayedMax;
|
|
mLeftButton->setEnabled( true );
|
|
mRightButton->setEnabled( true );
|
|
}
|
|
else {
|
|
// only one page
|
|
mLeftButton->setEnabled( false );
|
|
mRightButton->setEnabled( false );
|
|
}
|
|
|
|
getFreshResults( inMoveBackward );
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
Sprite *ResourcePicker<ResourceType>::getButtonGridBackground() {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::getFreshResults( char inMoveBackward ) {
|
|
uniqueID ids[mNumResourcesDisplayedMax];
|
|
|
|
|
|
// clear old sprites
|
|
int i;
|
|
for( i=0; i<mNumResourcesDisplayedMax; i++ ) {
|
|
int y = i / mGridW;
|
|
int x = i % mGridW;
|
|
|
|
mButtonGrid[y][x]->setEnabled( false );
|
|
}
|
|
|
|
|
|
char *search = stringDuplicate( mSearchField->getText() );
|
|
|
|
|
|
//printf( "Fresh results with offset %d from %d results\n",
|
|
// mSearchResultOffset, mNumSearchResults );
|
|
|
|
if( !mStackMode ) {
|
|
mNumResourcesOnScreen = getSearchResults(
|
|
ResourceType::getResourceType(),
|
|
search,
|
|
mSearchResultOffset,
|
|
mNumResourcesDisplayedMax,
|
|
ids );
|
|
|
|
|
|
}
|
|
else {
|
|
mNumResourcesOnScreen = getStackResults( mSearchResultOffset,
|
|
mNumResourcesDisplayedMax,
|
|
ids );
|
|
}
|
|
|
|
delete [] search;
|
|
|
|
Sprite *backgroundSprite = getButtonGridBackground();
|
|
|
|
char useTrans = false;
|
|
if( backgroundSprite != NULL ) {
|
|
useTrans = true;
|
|
|
|
// delete this test sprite, because we need to add a copy
|
|
// to every button below
|
|
delete backgroundSprite;
|
|
}
|
|
|
|
|
|
char badResultCount = 0;
|
|
|
|
for( i=0; i<mNumResourcesOnScreen; i++ ) {
|
|
ResourceType r( ids[i] );
|
|
|
|
mResourcesDisplayed[i] = r;
|
|
|
|
int y = i / mGridW;
|
|
int x = i % mGridW;
|
|
|
|
mButtonGrid[y][x]->setEnabled( true );
|
|
mButtonGrid[y][x]->setFrontSprite( r.getSprite( useTrans ) );
|
|
mButtonGrid[y][x]->setSprite( getButtonGridBackground() );
|
|
|
|
char *tip = r.getName();
|
|
mButtonGrid[y][x]->setToolTip( tip, false );
|
|
delete [] tip;
|
|
|
|
if( ! equal( ids[i], r.getUniqueID() ) ) {
|
|
// this resource failed to load (bogus search result in index,
|
|
// and it will be removed by resourceManager)
|
|
|
|
|
|
// it will show up as a "default" resource with blank sprite,
|
|
// even if the current search does not match the word "default",
|
|
// which is confusing.
|
|
badResultCount++;
|
|
|
|
// abandon this search and start a brand new one, attempting
|
|
// to maintain the page offset
|
|
|
|
// however, finish loading rest of resources in this batch
|
|
// in case it contains multiple bad ones (they are only removed
|
|
// by resourceManager when they are loaded), instead of removing
|
|
// them one-by-one with several newSearches (slow)
|
|
}
|
|
}
|
|
|
|
|
|
if( badResultCount > 0 ) {
|
|
|
|
if( inMoveBackward ) {
|
|
// when moving backward through results,
|
|
// the removal of bad results can cause the left button
|
|
// to appear to have no effect
|
|
|
|
// account for this
|
|
mNumSearchResults -= badResultCount;
|
|
mSearchResultOffset -= badResultCount;
|
|
lowerBoundSearchOffset();
|
|
}
|
|
|
|
newSearch( true, inMoveBackward );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::lowerBoundSearchOffset() {
|
|
if( mSearchResultOffset < 0 ) {
|
|
// roll back to last page
|
|
int numOnLastPage = mNumSearchResults % mNumResourcesDisplayedMax;
|
|
|
|
mSearchResultOffset = mNumSearchResults - numOnLastPage;
|
|
if( numOnLastPage == 0 ) {
|
|
// an even number of full pages
|
|
|
|
// show last page
|
|
mSearchResultOffset =
|
|
mSearchResultOffset - mNumResourcesDisplayedMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::actionPerformed( GUIComponent *inTarget ) {
|
|
if( inTarget == mSearchField ) {
|
|
// search changed
|
|
newSearch();
|
|
}
|
|
else if( inTarget == mDeleteButton ) {
|
|
// confirmed delete!
|
|
|
|
uniqueID id = mSelectedResource.getUniqueID();
|
|
|
|
deleteResource( ResourceType::getResourceType(), id );
|
|
|
|
removeUsages( id );
|
|
|
|
// delete from stack, too
|
|
char found = false;
|
|
int stackSize = mStack->size();
|
|
// walk backward... most likely at top of stack (right?)
|
|
for( int i=stackSize-1; i>=0 && !found; i-- ) {
|
|
if( equal( id, *( mStack->getElement( i ) ) ) ) {
|
|
AppLog::detail( "Found element to delete in stack\n" );
|
|
mStack->deleteElement( i );
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
// delete from image cache, too
|
|
clearCachedImages( id );
|
|
|
|
// also hint no longer needed
|
|
clearSpeechHint( id );
|
|
|
|
|
|
|
|
// refresh results (in case they show the deleted tile)
|
|
newSearch( true );
|
|
|
|
if( !mStackMode || mStack->size() == 0 ) {
|
|
// set to default
|
|
setSelectedResource( ResourceType::getDefaultResource() );
|
|
}
|
|
else {
|
|
// take next top of stack
|
|
ResourceType r( *( mStack->getElement( mStack->size() - 1 ) ) );
|
|
setSelectedResource( r );
|
|
}
|
|
}
|
|
else if( inTarget == mLeftButton ) {
|
|
mSearchResultOffset -= mNumResourcesDisplayedMax;
|
|
lowerBoundSearchOffset();
|
|
getFreshResults( true );
|
|
}
|
|
else if( inTarget == mRightButton ) {
|
|
mSearchResultOffset += mNumResourcesDisplayedMax;
|
|
if( mSearchResultOffset > mNumSearchResults - 1 ) {
|
|
// wrap back around
|
|
mSearchResultOffset = 0;
|
|
}
|
|
getFreshResults();
|
|
}
|
|
else if( inTarget == mStackSearchButton ) {
|
|
mStackMode = mStackSearchButton->getState();
|
|
|
|
|
|
if( mStackMode ) {
|
|
remove( mSearchField );
|
|
remove( mSearchLabel );
|
|
|
|
add( mStackLabel );
|
|
}
|
|
else {
|
|
remove( mStackLabel );
|
|
|
|
add( mSearchLabel );
|
|
add( mSearchField );
|
|
}
|
|
|
|
newSearch();
|
|
}
|
|
else if( inTarget == mSelectedResourceButton ) {
|
|
if( mSelectedResourceButton->mLastActionFromPress ) {
|
|
// event from a press.... start drag and drop?
|
|
mLastActionFromPress = true;
|
|
mCurrentDraggedResource = mSelectedResource;
|
|
|
|
fireActionPerformed( this );
|
|
}
|
|
}
|
|
else {
|
|
// consider a button press
|
|
char found = false;
|
|
for( int i=0; i<mNumResourcesOnScreen && !found; i++ ) {
|
|
int y = i / mGridW;
|
|
int x = i % mGridW;
|
|
|
|
if( inTarget == mButtonGrid[y][x] ) {
|
|
|
|
found = true;
|
|
|
|
if( ! mButtonGrid[y][x]->mLastActionFromPress ) {
|
|
|
|
|
|
|
|
// don't let it fire an event...
|
|
// (because it only fires on item change)
|
|
setSelectedResource( mResourcesDisplayed[ i ], false,
|
|
false );
|
|
// ...we fire our own, even if there's no change
|
|
mLastActionFromPress = false;
|
|
fireActionPerformed( this );
|
|
|
|
|
|
/*
|
|
if( mStackMode ) {
|
|
// show top of stack again
|
|
mSearchResultOffset = 0;
|
|
getFreshResults();
|
|
}
|
|
*/
|
|
}
|
|
else {
|
|
// event from a press.... start drag and drop?
|
|
mLastActionFromPress = true;
|
|
mCurrentDraggedResource = mResourcesDisplayed[ i ];
|
|
|
|
fireActionPerformed( this );
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::setState( ResourceType inSelectedResource,
|
|
char *inSearchString,
|
|
int inResultOffset,
|
|
char inStackMode ) {
|
|
mSearchField->setText( inSearchString );
|
|
mSearchResultOffset = inResultOffset;
|
|
|
|
char stackModeChange = ( mStackMode != inStackMode );
|
|
mStackMode = inStackMode;
|
|
mStackSearchButton->setState( mStackMode );
|
|
|
|
if( stackModeChange ) {
|
|
if( mStackMode ) {
|
|
remove( mSearchField );
|
|
remove( mSearchLabel );
|
|
|
|
add( mStackLabel );
|
|
}
|
|
else {
|
|
remove( mStackLabel );
|
|
|
|
add( mSearchLabel );
|
|
add( mSearchField );
|
|
}
|
|
}
|
|
|
|
setSelectedResource( inSelectedResource );
|
|
|
|
// always do new search after clone (in case selected resource doesn't
|
|
// change, so no new search would be triggered)
|
|
newSearch( true );
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
void ResourcePicker<ResourceType>::cloneState(
|
|
ResourcePicker *inOtherPicker ) {
|
|
|
|
inOtherPicker->setState( mSelectedResource,
|
|
mSearchField->getText(),
|
|
mSearchResultOffset,
|
|
mStackMode );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
int ResourcePicker<ResourceType>::countStackResults() {
|
|
return mStack->size();
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
int ResourcePicker<ResourceType>::getStackResults( int inNumToSkip,
|
|
int inNumToGet,
|
|
uniqueID *outIDs ) {
|
|
int numGotten = 0;
|
|
|
|
int stackSize = mStack->size();
|
|
|
|
int end = inNumToSkip + inNumToGet;
|
|
if( end > stackSize ) {
|
|
end = stackSize;
|
|
}
|
|
|
|
for( int i=inNumToSkip; i<end; i++ ) {
|
|
// reverse order (end of vector is top of stack
|
|
outIDs[ numGotten ] = *( mStack->getElement( stackSize - i - 1 ) );
|
|
numGotten++;
|
|
}
|
|
|
|
return numGotten;
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
char ResourcePicker<ResourceType>::wasLastActionFromPress() {
|
|
return mLastActionFromPress;
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
ResourceType ResourcePicker<ResourceType>::getDraggedResource() {
|
|
|
|
return mCurrentDraggedResource;
|
|
}
|
|
|
|
|
|
|
|
template <class ResourceType>
|
|
char ResourcePicker<ResourceType>::isSearchFieldFocused() {
|
|
return mSearchField->isFocused();
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|