implement up/down key handlers for treeviews

This commit is contained in:
gfgtdf 2016-03-07 20:16:01 +01:00
parent 33b8d66b34
commit c357d91a43
4 changed files with 153 additions and 4 deletions

View file

@ -185,6 +185,56 @@ void ttree_view::signal_handler_left_button_down(const event::tevent event)
get_window()->keyboard_capture(this);
}
template<ttree_view_node* (ttree_view_node::*func) ()>
ttree_view_node* ttree_view::get_next_node()
{
ttree_view_node* selected = selected_item();
if(!selected) {
return NULL;
}
ttree_view_node* visible = selected->get_last_visible_parent_node();
if(visible != selected) {
return visible;
}
return (selected->*func)();
}
template<ttree_view_node* (ttree_view_node::*func) ()>
bool ttree_view::handle_up_down_arrow()
{
if(ttree_view_node* next = get_next_node<func>())
{
next->select_node();
SDL_Rect visible = content_visible_area();
SDL_Rect rect = next->get_grid().get_rectangle();
visible.y = rect.y;// - content_grid()->get_y();
visible.h = rect.h;
show_content_rect(visible);
return true;
}
return false;
}
void ttree_view::handle_key_up_arrow(SDLMod modifier, bool& handled)
{
if(handle_up_down_arrow<&ttree_view_node::get_selectable_node_above>()) {
handled = true;
}
else {
tscrollbar_container::handle_key_up_arrow(modifier, handled);
}
}
void ttree_view::handle_key_down_arrow(SDLMod modifier, bool& handled)
{
if(handle_up_down_arrow<&ttree_view_node::get_selectable_node_below>()) {
handled = true;
}
else {
tscrollbar_container::handle_key_down_arrow(modifier, handled);
}
}
void ttree_view::handle_key_left_arrow(SDLMod modifier, bool& handled)
{
@ -201,7 +251,7 @@ void ttree_view::handle_key_right_arrow(SDLMod modifier, bool& handled)
{
ttree_view_node* selected = selected_item();
if(!selected || !selected->is_folded()) {
tscrollbar_container::handle_key_left_arrow(modifier, handled);
tscrollbar_container::handle_key_right_arrow(modifier, handled);
return;
}
selected->unfold();

View file

@ -83,13 +83,12 @@ public:
protected:
/***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
#if 0
/** Inherited from tscrollbar_container. */
void handle_key_up_arrow(SDLMod modifier, bool& handled);
/** Inherited from tscrollbar_container. */
void handle_key_down_arrow(SDLMod modifier, bool& handled);
#endif
/** Inherited from tscrollbar_container. */
void handle_key_left_arrow(SDLMod modifier, bool& handled);
@ -146,6 +145,12 @@ private:
/***** ***** ***** signal handlers ***** ****** *****/
void signal_handler_left_button_down(const event::tevent event);
template<ttree_view_node* (ttree_view_node::*func) ()>
ttree_view_node* get_next_node();
template<ttree_view_node* (ttree_view_node::*func) ()>
bool handle_up_down_arrow();
};
} // namespace gui2

View file

@ -720,4 +720,92 @@ int ttree_view_node::calculate_ypos()
}
return res;
}
ttree_view_node* ttree_view_node::get_last_visible_parent_node()
{
if(!parent_node_) {
return this;
}
ttree_view_node* res = parent_node_->get_last_visible_parent_node();
return res == parent_node_ && !res->is_folded() ? this : res;
}
ttree_view_node* ttree_view_node::get_node_above()
{
assert(!is_root_node());
ttree_view_node* cur = NULL;
for(size_t i = 0; i < parent_node_->size(); ++i) {
if(&parent_node_->children_[i] == this) {
if(i == 0) {
return parent_node_->is_root_node() ? NULL : parent_node_;
}
else {
cur = &parent_node_->children_[i - 1];
break;
}
}
}
while(!cur->is_folded() && cur->size() > 0) {
cur = &cur->get_child_at(cur->size() - 1);
}
return cur;
}
ttree_view_node* ttree_view_node::get_node_below()
{
assert(!is_root_node());
if(!is_folded() && size() > 0) {
return &get_child_at(0);
}
ttree_view_node* cur = this;
while(cur->parent_node_ != NULL) {
ttree_view_node& parent = *cur->parent_node_;
for(size_t i = 0; i < parent.size(); ++i) {
if(&parent.children_[i] == cur) {
if(i < parent.size() - 1) {
return &parent.children_[i + 1];
}
else {
cur = &parent;
}
break;
}
}
}
return NULL;
}
ttree_view_node* ttree_view_node::get_selectable_node_above()
{
ttree_view_node* above = this;
do {
above = above->get_node_above();
} while(above != NULL && above->label_ == NULL);
return above;
}
ttree_view_node* ttree_view_node::get_selectable_node_below()
{
ttree_view_node* below = this;
do {
below = below->get_node_below();
} while(below != NULL && below->label_ == NULL);
return below;
}
void ttree_view_node::select_node()
{
if(!label_ || label_->get_value_bool()) {
return;
}
if(tree_view().selected_item_ && tree_view().selected_item_->label_) {
tree_view().selected_item_->label_->set_value(false);
}
tree_view().selected_item_ = this;
if(tree_view().selection_change_callback_) {
tree_view().selection_change_callback_(tree_view());
}
label_->set_value_bool(true);
}
} // namespace gui2

View file

@ -209,7 +209,13 @@ public:
break;
}
}
ttree_view_node* get_last_visible_parent_node();
ttree_view_node* get_node_above();
ttree_view_node* get_node_below();
ttree_view_node* get_selectable_node_above();
ttree_view_node* get_selectable_node_below();
void select_node();
tgrid& get_grid() { return grid_; }
private:
int calculate_ypos();