GUIComponent *GUIComponent::get_component_at(const Point &point) { if (is_visible() == false) { return 0; } else { Rect parent_rect = get_size(); if( parent_rect.contains(point) ) { std::vector<GUIComponent *> children = get_child_components(); std::size_t pos, size = children.size(); for( pos=size; pos>0; pos-- ) { GUIComponent *child = children[pos-1]; if(child->is_visible()) { if (child->get_geometry().contains(point)) { Point P = point; P.x -= child->get_geometry().left; P.y -= child->get_geometry().top; GUIComponent *comp = child->get_component_at(P); if (comp) return comp; else return child; } } } return this; } else { return 0; } } }
void RadioButton_Impl::on_process_message(std::shared_ptr<GUIMessage> &msg) { if (!radio->is_enabled()) return; std::shared_ptr<GUIMessage_Input> input_msg = std::dynamic_pointer_cast<GUIMessage_Input>(msg); if (input_msg) { const InputEvent &e = input_msg->input_event; if (e.type == InputEvent::pressed && e.id == mouse_left) { part_checker.set_pseudo_class(CssStr::pressed, true); radio->request_repaint(); msg->consumed = true; } else if (e.type == InputEvent::released && e.id == mouse_left) { if ((part_checker.get_pseudo_class(CssStr::checked) == false)) { Callback_v1<RadioButton*> cb = uncheck_radio_buttons(radio->get_parent_component()); part_checker.set_pseudo_class(CssStr::pressed, false); radio->set_selected(true); if (!cb.is_null()) cb.invoke(radio); if (!func_selected.is_null()) func_selected.invoke(); } else { part_checker.set_pseudo_class(CssStr::pressed, false); radio->request_repaint(); } radio->set_focus(true); msg->consumed = true; } else if (e.type == InputEvent::pressed && (e.id == keycode_left || e.id == keycode_up)) { std::vector<GUIComponent*> group = radio->get_parent_component()->get_child_component_group(radio->get_component_group_name()); // find previous visible & enabled radiobutton in the same group: GUIComponent *comp = radio->get_previous_sibling(); if (comp == 0) comp = group.back(); while (comp != radio) { if (comp->is_visible() && comp->is_enabled() && comp->get_component_group_name() == radio->get_component_group_name()) { RadioButton *focus_comp = dynamic_cast<RadioButton*>(comp); if (focus_comp) { Callback_v1<RadioButton*> cb = uncheck_radio_buttons(radio->get_parent_component()); focus_comp->set_selected(true); if (!cb.is_null()) cb.invoke(focus_comp); if (!focus_comp->func_selected().is_null()) focus_comp->func_selected().invoke(); focus_comp->set_focus(); break; } } if (!comp->get_previous_sibling() || comp->get_previous_sibling()->get_component_group_name() != radio->get_component_group_name()) { // reach first item in group, loop around from the last: comp = group.back(); } else comp = comp->get_previous_sibling(); } msg->consumed = true; } else if (e.type == InputEvent::pressed && (e.id == keycode_right || e.id == keycode_down)) { std::vector<GUIComponent*> group = radio->get_parent_component()->get_child_component_group(radio->get_component_group_name()); // find next visible & enabled radiobutton in the same group: GUIComponent *comp = radio->get_next_sibling(); if (comp == 0 || comp->get_component_group_name() != radio->get_component_group_name()) comp = group.front(); while (comp != radio) { if (comp->is_visible() && comp->is_enabled() && comp->get_component_group_name() == radio->get_component_group_name()) { RadioButton *focus_comp = dynamic_cast<RadioButton*>(comp); if (focus_comp) { Callback_v1<RadioButton*> cb = uncheck_radio_buttons(radio->get_parent_component()); focus_comp->set_selected(true); if (!cb.is_null()) cb.invoke(focus_comp); if (!focus_comp->func_selected().is_null()) focus_comp->func_selected().invoke(); focus_comp->set_focus(); break; } } if (!comp->get_previous_sibling() || comp->get_previous_sibling()->get_component_group_name() != radio->get_component_group_name()) { // reach first item in group, loop around from the last: comp = group.back(); } else comp = comp->get_next_sibling(); } msg->consumed = true; } } std::shared_ptr<GUIMessage_Pointer> pointer = std::dynamic_pointer_cast<GUIMessage_Pointer>(msg); if (pointer) { if (pointer->pointer_type == GUIMessage_Pointer::pointer_enter) { part_checker.set_pseudo_class(CssStr::hover, true); radio->request_repaint(); } else { part_checker.set_pseudo_class(CssStr::hover, false); radio->request_repaint(); } } std::shared_ptr<GUIMessage_FocusChange> focus_change_msg = std::dynamic_pointer_cast<GUIMessage_FocusChange>(msg); if (focus_change_msg) { if (focus_change_msg->focus_type == GUIMessage_FocusChange::gained_focus) { radio->set_pseudo_class(CssStr::focused, true); if (!radio->is_selected()) { Callback_v1<RadioButton*> cb = uncheck_radio_buttons(radio->get_parent_component()); radio->set_selected(true); if (!cb.is_null()) cb.invoke(radio); if (!func_selected.is_null()) func_selected.invoke(); } radio->request_repaint(); } else { radio->set_pseudo_class(CssStr::focused, false); radio->request_repaint(); } msg->consumed = true; } }
void GUIComponent::focus_previous() { GUIComponent *c = this; // Skip over components in the same group: if (get_focus_policy() == focus_group) { while (c->impl->prev_sibling && c->get_component_group_name() == this->get_component_group_name()) { c = c->impl->prev_sibling; } } else c = c->get_previous_component_in_tree(); while (c != this) { if ((c->get_focus_policy() == focus_local || c->get_focus_policy() == focus_group) && c->is_visible() && c->is_enabled()) { if (c->get_focus_policy() == focus_group) { GUIComponent *selected_comp = c->get_group_selected_component(); if (selected_comp) { selected_comp->set_focus(true); } else { c->set_focus(true); } } else { c->set_focus(true); } break; } c = c->get_previous_component_in_tree(); } }