void JObjectTree::Traverse( TraverseCallback callback, void* pContext ) const { if (!m_pRoot) return; float nodeW = m_NodeWidth; float nodeVisH = m_NodeHeight; Frame ext( m_RootPos.x, m_RootPos.y, nodeW, nodeVisH ); // find node path for tree expansion static std::vector<int> nodePath; nodePath.clear(); JObject* pCurObj = m_pExpanded; if (pCurObj) nodePath.push_back( 0 ); while (pCurObj && pCurObj != m_pRoot) { JObject* pParent = pCurObj->GetParent(); if (!pParent) break; nodePath.push_back( pParent->GetChildIndex( pCurObj ) ); pCurObj = pParent; } // traverse root node (which is never collapsed) if ((this->*callback)( ext, m_pRoot, (m_pExpanded != NULL), pContext ) == false) return; // traverse along expansion path pCurObj = m_pRoot; for (int i = nodePath.size() - 1; i >= 0; i--) { int childIdx = nodePath[i]; if (!pCurObj) break; int nCh = pCurObj->GetNChildren(); if (childIdx >= nCh) break; float blockH = float( nCh )*nodeVisH; ext.y = ext.y - blockH*0.5f + nodeVisH*0.5f; ext.x += nodeW; float cY = ext.y; for (int j = 0; j < nCh; j++) { JObject* pChild = pCurObj->GetChild( j ); Frame chExt( ext ); chExt.y = cY; bool bExpanded = (j == childIdx)&&(pCurObj != m_pExpanded); if ((this->*callback)( chExt, pChild, bExpanded, pContext ) == false) { return; } cY += nodeVisH; } pCurObj = pCurObj->GetChild( childIdx ); ext.y += float( childIdx )*nodeVisH; } } // JObjectTree::Traverse
bool JObjectTree::DeleteNode() { if (!m_pSelected) return false; JObject* pParent = m_pSelected->GetParent(); if (!pParent) return false; int idx = pParent->GetChildIndex( m_pSelected ); pParent->RemoveChild( m_pSelected ); if (idx >= pParent->GetNChildren()) idx = pParent->GetNChildren() - 1; if (idx < 0) idx = 0; m_pSelected = pParent->GetChild( idx ); if (!m_pSelected) m_pSelected = pParent; m_pExpanded = m_pSelected; return true; } // JObjectTree::DeleteNode
int JLuaServer::FnChildren( lua_State* pLua ) { if (lua_gettop( pLua ) != 1) { rlog.err( "LUA: Incorrect command usage: <children>. " "Function takes 1 argument (<objectRef>|<objectName>), but %d is provided", lua_gettop( pLua ) ); lua_settop( pLua, 0 ); lua_pushnil( pLua ); return 1; } JObject* pObj = NULL; const char* pPath = lua_tostring( pLua, -1 ); if (pPath) { JLuaThread* pThread = reinterpret_cast<JLuaThread*>( pLua->userdata ); assert( pThread->m_pLua == pLua ); JObject* pRootObj = pThread->m_pRootObj; pObj = g_pObjectServer->FindObject( pPath, NULL, pRootObj ); } else { pObj = reinterpret_cast<JObject*>( lua_touserdata( pLua, -1 ) ); } if (!pObj) { lua_pushnil( pLua ); return 1; } // return table with children int nCh = pObj->GetNChildren(); lua_createtable( pLua, nCh, 0 ); lua_newtable( pLua ); for (int i = 0; i < nCh; i++) { // key lua_pushnumber( pLua, i + 1 ); // value (child pointer) lua_pushlightuserdata( pLua, pObj->GetChild( i ) ); lua_settable( pLua, -3 ); } return 1; } // JLuaServer::FnChildren
void JBoundsEditor::CreateEditor( JObject* pEdited ) { JObject* pTemplates = g_pObjectServer->FindObject( "templates", this ); JObject* pEditors = GetEditorsGroup(); if (pTemplates == NULL || pEditors == NULL) { return; } int nTemplates = pTemplates->GetNChildren(); JString editorName; for (int i = 0; i < nTemplates; i++) { JWidget* pTemplate = obj_cast<JWidget>( pTemplates->GetChild( i ) ); if (pTemplate && is_a( pEdited, pTemplate->GetName() )) { // this object can be edited with this editor template editorName = pEdited->GetName(); editorName += "_"; editorName += pTemplate->GetName(); editorName += "_editor"; JObject* pEditor = pTemplate->Clone( pEditors, editorName.c_str(), true ); pEditors->AddChild( pEditor ); JBoundsEditContext ctx; ctx.m_pEdited = pEdited; ctx.m_pEditor = pEditor; pEdited->GetPath( ctx.m_Path ); m_Edited.push_back( ctx ); // parse property connections from text field JString propcfg( pTemplate->GetText() ); char* propConfig = (char*)propcfg.c_str(); while (propConfig && *propConfig != 0) { char* editedVal = propConfig; char* editorVal = propConfig + strcspn( propConfig, "<|" ); char& ch = *editorVal; if (ch == '|') { ch = 0; editorVal = "value"; } else if (ch == '<') { *editorVal = 0; editorVal++; propConfig = editorVal + strcspn( editorVal, "|" ); if (*propConfig == '|') { *propConfig = 0; propConfig++; } } else if (ch == 0) { propConfig = 0; editorVal = "value"; } g_pSignalServer->Connect( pEditor, editorVal, pEdited, editedVal ); g_pSignalServer->Connect( pEdited, editedVal, pEditor, editorVal ); pEdited->SendSignal( editedVal ); g_pSignalServer->Connect( pEdited, "visible", pEditor, "visible" ); pEdited->SendSignal( "visible" ); } } } }