📄 guitreeviewctrl.cc
字号:
// Do we want to allow more than one selected item?
//if( !mMultipleSelections )
// clearSelection();
mSelectedItems.push_front(item);
}
void GuiTreeViewCtrl::onItemSelected( Item *item )
{
char buf[16];
dSprintf(buf, 16, "%d", item->mId);
if (item->isInspectorData())
{
Con::executef(this, 2, "onSelect", Con::getIntArg(item->getObject()->getId()));
if (!(item->isParent()) && item->getObject())
Con::executef(this, 2, "onInspect", Con::getIntArg(item->getObject()->getId()));
}
else
{
Con::executef(this, 2, "onSelect", buf);
if (!(item->isParent()))
Con::executef(this, 2, "onInspect", buf);
}
mSelectedItem = item->getID();
}
bool GuiTreeViewCtrl::setItemSelected(S32 itemId, bool select)
{
Item * item = getItem(itemId);
if (select)
{
if (mDebug) Con::printf("setItemSelected called true");
mSelected.push_front(itemId);
}
else
{
if (mDebug) Con::printf("setItemSelected called false");
// remove it from the mSelected list
for (S32 j = 0; j <mSelected.size(); j++)
{
if (item)
{
if (item->isInspectorData())
{
if (item->getObject())
{
if(item->getObject()->getId() == mSelected[j])
{
mSelected.erase(j);
break;
}
}
else
{
// Zombie, kill it!
mSelected.erase(j);
j--;
}
}
}
if (mSelected[j] == itemId)
{
mSelected.erase(j);
break;
}
}
}
if(!item)
{
// maybe what we were passed wasn't an item id but an object id.
for (S32 i = 0; i <mItems.size(); i++)
{
if (mItems[i] != 0)
{
if (mItems[i]->isInspectorData())
{
if (mItems[i]->getObject())
{
if(mItems[i]->getObject()->getId() == itemId)
{
item = mItems[i];
break;
}
}
else
{
// It's a zombie, blast it.
mItems.erase(i);
i--;
}
}
}
}
if (!item)
{
//Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::setItemSelected: invalid item id! Perhaps it isn't visible yet.");
return(false);
}
}
if(select)
{
addSelection( item->mId );
onItemSelected( item );
}
else
{
// unselect the item, if it's present.
item->mState.set(Item::Selected, false);
if (item->isInspectorData())
{
if(item->getObject())
{
Con::executef(this, 2, "onUnSelect", Con::getIntArg(item->getObject()->getId()));
}
}
else
{
Con::executef(this, 2, "onUnSelect", Con::getIntArg(item->mId));
}
// remove it from the selected items list
for (S32 i = 0; i < mSelectedItems.size(); i++)
{
if (mSelectedItems[i] == item)
{
mSelectedItems.erase(i);
break;
}
}
}
setUpdate();
return(true);
}
bool GuiTreeViewCtrl::setItemExpanded(S32 itemId, bool expand)
{
Item * item = getItem(itemId);
if(!item)
{
Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::setItemExpanded: invalid item id!");
return(false);
}
if(item->isExpanded() == expand)
return(true);
// expand parents
if(expand)
{
while(item)
{
if(item->mState.test(Item::VirtualParent))
onVirtualParentExpand(item);
item->setExpanded(true);
item = item->mParent;
}
}
else
{
if(item->mState.test(Item::VirtualParent))
onVirtualParentCollapse(item);
item->setExpanded(false);
}
return(true);
}
bool GuiTreeViewCtrl::setItemValue(S32 itemId, StringTableEntry Value)
{
Item * item = getItem(itemId);
if(!item)
{
Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::setItemValue: invalid item id!");
return(false);
}
item->setValue( ( Value ) ? Value : "" );
return(true);
}
const char * GuiTreeViewCtrl::getItemText(S32 itemId)
{
Item * item = getItem(itemId);
if(!item)
{
Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getItemText: invalid item id!");
return("");
}
return(item->getText() ? item->getText() : "");
}
const char * GuiTreeViewCtrl::getItemValue(S32 itemId)
{
Item * item = getItem(itemId);
if(!item)
{
Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getItemValue: invalid item id!");
return("");
}
if(item->mState.test(Item::InspectorData))
{
// If it's InspectorData, we let people use this call to get an object reference.
return item->mInspectorInfo.mObject->getIdString();
}
else
{
// Just return the script value...
return(item->getValue() ? item->getValue() : "");
}
}
bool GuiTreeViewCtrl::editItem( S32 itemId, const char* newText, const char* newValue )
{
Item* item = getItem( itemId );
if ( !item )
{
Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::editItem: invalid item id!");
return false;
}
if ( item->mState.test(Item::InspectorData) )
{
Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::editItem: item %d is inspector data and may not be modified!", itemId);
return false;
}
delete [] item->getText();
item->setText (new char[dStrlen( newText ) + 1]);
dStrcpy( item->getText(), newText );
delete [] item->getValue();
item->setValue( new char[dStrlen( newValue ) + 1] );
dStrcpy( item->getValue(), newValue );
// Update the widths and such:
buildVisibleTree();
return true;
}
void GuiTreeViewCtrl::deleteSelection()
{
Con::executef(this, 1, "onDeleteSelection");
if (mSelectedItems.empty())
{
for (S32 i = 0; i < mSelected.size(); i++)
{
S32 objectId = mSelected[i];
// find the object
SimObject* obj = Sim::findObject(objectId);
#ifdef TGE_RPG
if(dynamic_cast<SimObject*>(obj))
#endif
obj->deleteObject();
}
}
else
{
while (!mSelectedItems.empty())
{
Item * item = mSelectedItems.last();
setItemSelected(item->mId,false);
if ( item->mParent )
{
deleteItem( item );
// If we're still the last item (ie, haven't removed ourselves)
// then remove it manually.
if(item == mSelectedItems.back())
mSelectedItems.pop_back();
}
}
}
mSelected.clear();
mSelectedItems.clear();
}
//------------------------------------------------------------------------------
// keyboard movement of items is restricted to just one item at a time
// if more than one item is selected then movement operations are not performed
bool GuiTreeViewCtrl::onKeyDown( const GuiEvent& event )
{
if ( !mVisible || !mActive || !mAwake )
return true;
// All the keyboard functionality requires a selected item, so if none exists...
// Deal with enter and delete
if ( event.modifier == 0 )
{
if ( event.keyCode == KEY_RETURN )
{
if ( mAltConsoleCommand[0] )
Con::evaluate( mAltConsoleCommand );
return true;
}
if ( event.keyCode == KEY_DELETE && mFlags.test(IsDeletable))
{
// Don't delete the root!
if (mSelectedItems.empty())
return true;
//this may be fighting with the world editor delete
deleteSelection();
return true;
}
}
// only do operations if only one item is selected
if ( mSelectedItems.empty() || (mSelectedItems.size() > 1))
return true;
Item* item = mSelectedItems.first();
if ( !item )
return true;
// The Alt key lets you move items around!
if ( mFlags.test(IsEditable) && event.modifier & SI_ALT )
{
switch ( event.keyCode )
{
case KEY_UP:
// Move us up.
if ( item->mPrevious )
{
moveItemUp( item->mId );
scrollVisible(item);
}
return true;
case KEY_DOWN:
// Move the item under us up.
if ( item->mNext )
{
moveItemUp( item->mNext->mId );
scrollVisible(item);
}
return true;
case KEY_LEFT:
if ( item->mParent )
{
if ( item->mParent->mParent )
{
// Ok, we have both an immediate parent, and a grandparent.
// The goal of left-arrow alt is to become the child of our
// grandparent, ie, to become a sibling of our parent.
// First, unlink item from its siblings.
if ( item->mPrevious )
item->mPrevious->mNext = item->mNext;
else
item->mParent->mChild = item->mNext;
if ( item->mNext )
item->mNext->mPrevious = item->mPrevious;
// Now, relink as the next sibling of our parent.
item->mPrevious = item->mParent;
item->mNext = item->mParent->mNext;
// If there was already a next sibling, deal with that case.
if ( item->mNext )
item->mNext->mPrevious = item;
item->mParent->mNext = item;
// Snag the current parent set if any...
SimSet *parentSet = NULL;
if(item->mParent->isInspectorData())
parentSet = dynamic_cast<SimSet*>(item->mParent->getObject());
else
{
// parent is probably script data so we search up the tree for a
// set to put our object in
Item * temp = item->mParent;
while (!temp->isInspectorData())
temp = temp->mParent;
// found a ancestor who is an inspectorData
if (temp->isInspectorData())
parentSet = dynamic_cast<SimSet*>(temp->getObject());
else parentSet = NULL;
}
// Get our active SimObject if any
SimObject *simObj = NULL;
if(item->isInspectorData())
simObj = item->getObject();
// Remove from the old parentset...
if(simObj && parentSet) {
if (parentSet->size()>0)
{
SimObject *lastObject = parentSet->last();
parentSet->removeObject(simObj);
parentSet->reOrder(lastObject);
} else
parentSet->removeObject(simObj);
}
// And finally, update our item
item->mParent = item->mParent->mParent;
// Snag the newparent set if any...
SimSet *newParentSet = NULL;
if(item->mParent->isInspectorData())
newParentSet = dynamic_cast<SimSet*>(item->mParent->getObject());
else
{
// parent is probably script data so we search up the tree for a
// set to put our object in
Item * temp = item->mParent;
while (!temp->isInspectorData())
temp = temp->mParent;
// found a ancestor who is an inspectorData
if (temp->isInspectorData())
newParentSet = dynamic_cast<SimSet*>(temp->getObject());
else newParentSet = NULL;
}
if(simObj && newParentSet)
{
newParentSet->addObject(simObj);
Item * temp = item->mNext;
// item->mNext may be script, so find an inspector item to reorder with if any
if (temp) {
do {
if (temp->isInspectorData())
break;
temp = temp->mNext;
} while (temp);
if (temp) //do we still have a item->mNext? If not then don't bother reordering
newParentSet->reOrder(item->getObject(), temp->getObject());
}
} else if (!simObj&&newParentSet) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -