void FocusManager::update( Widget* const top_widget, const KeyEvent event ) { if( focus_widget() ) { const auto focus_screen_rect = focus_widget()->screen_rect(); const auto test_fn = [&focus_screen_rect, event](ui::Widget* const w) -> test_result_t { // if( w->visible() && w->focusable() ) { if( w->focusable() ) { const auto distance = rect_distances(event, focus_screen_rect, w->screen_rect()); if( distance >= 0 ) { return { w, distance }; } } return { nullptr, 0 }; }; test_collection_t collection; widget_collect_visible(top_widget, test_fn, collection); const auto compare_fn = [](const test_result_t& a, const test_result_t& b) { return a.second < b.second; }; const auto nearest = std::min_element(collection.cbegin(), collection.cend(), compare_fn); if( nearest != collection.cend() ) { //focus->blur(); const auto new_focus = (*nearest).first; set_focus_widget(new_focus); } } }
void fgui_application_process_event(struct fgui_application *app, struct fgui_event *event) { int ret; struct fgui_widget *widget; /* TAB cycles focus */ if (event->type == FGUI_EVENT_KEYDOWN && event->key.keycode == FGUI_KEY_TAB) { set_focus_widget(app, DIR_NEXT); } /* not tab, pass on to widget */ if (!app->focus_widget) { return; } /* * Send the event to each widget in the parent-child chain, until * someone handles it. */ for (widget = app->focus_widget; widget != NULL; widget = widget->parent) { ret = widget->event_handler(widget, event); if (ret == 0) { break; } } }
//-----------------------------------------------------------------// void enable(widget* root, bool flag = true, bool child = false) { if(root == nullptr) return; if(!root->get_param().state_[widget::state::ENABLE] && flag) { set_focus_widget(root); } root->at_param().state_[widget::state::ENABLE] = flag; if(!child) { return; } widgets ws; parents_widget(root, ws); for(auto w : ws) { w->at_param().state_[widget::state::ENABLE] = flag; } }