Skip to content

Commit

Permalink
#6 Implement Tree Control Key Event
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Nov 21, 2020
1 parent a8beba7 commit 2509d5c
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 12 deletions.
57 changes: 57 additions & 0 deletions Projects/Editor/Source/GUI/Controls/CTreeControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ namespace Skylicht
m_expandButton = NULL;
m_innerPanel = NULL;
m_row = NULL;
m_expand = true;

m_scrollControl = new CScrollControl(this);
m_scrollControl->dock(EPosition::Fill);
Expand Down Expand Up @@ -91,11 +92,29 @@ namespace Skylicht

bool CTreeControl::onKeyUp(bool down)
{
if (down)
{
CTreeNode *child = selectPrevChild();
if (child != NULL)
{
m_scrollControl->scrollToItem(child->getTextItem());
}
}

return true;
}

bool CTreeControl::onKeyDown(bool down)
{
if (down)
{
CTreeNode *child = selectNextChild();
if (child != NULL)
{
m_scrollControl->scrollToItem(child->getTextItem());
}
}

return true;
}

Expand Down Expand Up @@ -148,6 +167,44 @@ namespace Skylicht
}
return true;
}

bool CTreeControl::onKeyLeft(bool down)
{
if (down)
{
CTreeNode* node = getChildSelected();
if (node != NULL)
{
if (node->haveChild() && node->isExpand())
node->collapse();
else
{
// select parent
CTreeNode *parent = node->getParentNode();
if (parent != NULL)
{
deselectAll();
parent->setSelected(true);
m_scrollControl->scrollToItem(parent->getTextItem());
}
}
}
}
return true;
}

bool CTreeControl::onKeyRight(bool down)
{
if (down)
{
CTreeNode* node = getChildSelected();
if (node != NULL)
{
node->expand();
}
}
return true;
}
}
}
}
4 changes: 4 additions & 0 deletions Projects/Editor/Source/GUI/Controls/CTreeControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ namespace Skylicht
virtual bool onKeyHome(bool down);

virtual bool onKeyEnd(bool down);

virtual bool onKeyLeft(bool down);

virtual bool onKeyRight(bool down);
};
}
}
Expand Down
126 changes: 114 additions & 12 deletions Projects/Editor/Source/GUI/Controls/CTreeNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ namespace Skylicht
m_expand(false),
m_selected(false)
{
m_parentNode = dynamic_cast<CTreeNode*>(parent);

m_row = new CTreeRowItem(this, root);
m_row->OnDown = BIND_LISTENER(&CTreeNode::onDown, this);
m_row->OnDoubleLeftMouseClick = BIND_LISTENER(&CTreeNode::onDoubleClick, this);
Expand Down Expand Up @@ -188,6 +190,28 @@ namespace Skylicht

}

CTreeNode* CTreeNode::getChildSelected()
{
if (m_selected)
return this;

if (m_innerPanel->Children.size() == 0)
return NULL;

for (CBase *c : m_innerPanel->Children)
{
CTreeNode *node = dynamic_cast<CTreeNode*>(c);
if (node && !node->isDisabled())
{
CTreeNode* child = node->getChildSelected();
if (child != NULL)
return child;
}
}

return NULL;
}

CTreeNode* CTreeNode::selectFirstChild()
{
if (m_expand == false)
Expand All @@ -201,18 +225,9 @@ namespace Skylicht
CTreeNode *node = dynamic_cast<CTreeNode*>(c);
if (node && !node->isDisabled())
{
CTreeNode *child = node->selectFirstChild();

if (child == NULL)
{
m_root->deselectAll();
node->setSelected(true);
return node;
}
else
{
return child;
}
m_root->deselectAll();
node->setSelected(true);
return node;
}
}

Expand Down Expand Up @@ -252,6 +267,93 @@ namespace Skylicht
return NULL;
}

CTreeNode* CTreeNode::selectPrevChild()
{
std::list<CTreeNode*> priorityQueue;
priorityQueue.push_back(this);

CTreeNode *lastItem = NULL;

while (priorityQueue.size() > 0)
{
CTreeNode* visit = priorityQueue.front();
priorityQueue.pop_front();

if (visit->isSelected() == true)
{
if (lastItem == NULL)
return NULL;

m_root->deselectAll();
lastItem->setSelected(true);
return lastItem;
}

if (visit->m_expand && visit->m_innerPanel->Children.size() > 0)
{
std::list<CTreeNode*>::iterator i = priorityQueue.begin();

for (CBase *c : visit->m_innerPanel->Children)
{
CTreeNode *node = dynamic_cast<CTreeNode*>(c);
if (node && !node->isDisabled())
{
i = priorityQueue.insert(i, node);
++i;
}
}
}

if (visit != this)
lastItem = visit;
}

return NULL;
}

CTreeNode* CTreeNode::selectNextChild()
{
std::list<CTreeNode*> priorityQueue;
priorityQueue.push_back(this);

bool selectNext = false;

while (priorityQueue.size() > 0)
{
CTreeNode* visit = priorityQueue.front();
priorityQueue.pop_front();

if (selectNext == true)
{
m_root->deselectAll();
visit->setSelected(true);
return visit;
}

if (visit->isSelected() == true)
{
selectNext = true;
}

if (visit->m_expand && visit->m_innerPanel->Children.size() > 0)
{
std::list<CTreeNode*>::iterator i = priorityQueue.begin();

for (CBase *c : visit->m_innerPanel->Children)
{
CTreeNode *node = dynamic_cast<CTreeNode*>(c);
if (node && !node->isDisabled())
{
i = priorityQueue.insert(i, node);
++i;
}
}
}
}

return NULL;
}

void CTreeNode::setSelected(bool b)
{
if (m_selected == b)
Expand Down
17 changes: 17 additions & 0 deletions Projects/Editor/Source/GUI/Controls/CTreeNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace Skylicht
CTreeRowItem *m_row;

CTreeNode *m_root;
CTreeNode *m_parentNode;

bool m_expand;
bool m_selected;
Expand Down Expand Up @@ -97,15 +98,31 @@ namespace Skylicht
invalidate();
}

inline bool haveChild()
{
return m_innerPanel->Children.size() > 0;
}

inline bool isSelected()
{
return m_selected;
}

inline CTreeNode* getParentNode()
{
return m_parentNode;
}

CTreeNode* getChildSelected();

CTreeNode* selectFirstChild();

CTreeNode* selectLastChild();

CTreeNode* selectNextChild();

CTreeNode* selectPrevChild();

void setSelected(bool b);

virtual void deselectAll();
Expand Down

0 comments on commit 2509d5c

Please sign in to comment.