GUIComponent *GUIComponent::get_named_item(const std::string &id) { GUIComponent *cur = impl->first_child; while (cur && cur != this) { if (cur->get_id() == id) return cur; if (cur->impl->first_child) cur = cur->impl->first_child; else if (cur->impl->next_sibling) cur = cur->impl->next_sibling; else { while (cur != this) { if (cur->impl->parent->impl->next_sibling) { cur = cur->impl->parent->impl->next_sibling; break; } else cur = cur->impl->parent; } } } return 0; }
EvidyonGUIButton* EvidyonGUIScrollableButtonList::button(int id) { GUIComponent* component = list_.getComponent(id); if (!component) { component = new Button(this, id); GUICanvas* canvas = component->getCanvas(); canvas->alignXLeft(0); canvas->alignYTop(0); canvas->relativeWidth(0); canvas->relativeHeight(0); canvas->relativeDepth(0.0f); list_.setComponent(id, component); } return reinterpret_cast<EvidyonGUIButton*>(component); }
GUIComponent *GUIComponent::get_top_level_component() { GUIComponent *parent = this; while (true) { if (parent->get_parent_component()) parent = parent->get_parent_component(); else break; } return parent; }
GUIComponent *GUIComponent::get_group_selected_component() { GUIComponent *parent = get_parent_component(); if (parent) { std::vector<GUIComponent*> group = parent->get_child_component_group(get_component_group_name()); std::vector<GUIComponent*>::size_type i; for (i = 0; i < group.size(); i++) { if (group[i]->is_selected_in_group()) { return group[i]; } } } return 0; }
GUIComponent *GUIComponent::get_next_component_in_tree() { if (has_child_components()) return get_first_child(); if (impl->next_sibling) return impl->next_sibling; GUIComponent *parent = impl->parent; while (parent) { if (parent->get_next_sibling()) return parent->get_next_sibling(); parent = parent->get_parent_component(); } // Reached end of tree. Return first item. return get_top_level_component(); }
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(); } }
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 GUIFindPreferredHeight::flex_vertical_node(GUIComponent_Impl *node) { node->css_used_values.height = node->component->get_preferred_content_height(node->css_used_values.width); CSSUsedValue preferred_height = 0.0f; for (GUIComponent *child = node->first_child; child != 0; child = child->get_next_sibling()) { if (is_normal_flow(child->impl.get())) { GUICSSUsedValues &child_used_values = child->impl->css_used_values; // If the height of the box cannot be determined from CSS, then ask the component: if (child_used_values.height_undetermined) { GUICSSDisplayVisitor::node(child->impl.get()); } preferred_height += get_used_noncontent_height(child_used_values) + child_used_values.height; } } node->css_used_values.height = std::max(node->css_used_values.height, preferred_height); GUICSSApplyMinMaxConstraints::visit(node->css_used_values, node->element.get_css_values().get_box(), node->parent->impl->css_used_values); }
GUIComponent *GUIComponent::get_previous_component_in_tree() { if (impl->prev_sibling) { // return last grand-child of sibling. if (impl->prev_sibling->has_child_components()) { GUIComponent *last = impl->prev_sibling->impl->last_child; while (last->has_child_components()) { last = last->get_last_child(); } return last; } else { // sibling has no children, return sibling. return impl->prev_sibling; } } // no previous sibling, return parent. if (impl->parent) return impl->parent; // No parent, must be top-level component. Find last child. GUIComponent *last = impl->last_child; // No child, must be a lonely top-level component. if(last == 0) return this; while (last->has_child_components()) { last = last->get_last_child(); } return last; }
bool show() { #if defined(WIN32) std::wstring title16 = StringHelp::utf8_to_ucs2(title); std::wstring initial_directory16 = StringHelp::utf8_to_ucs2(initial_directory); if(is_vista_or_later()) { HRESULT result; ComPtr<IFileOpenDialog> open_dialog; result = CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_ALL, __uuidof(open_dialog), reinterpret_cast<void**>(open_dialog.output_variable())); throw_if_failed(result, "CoCreateInstance(FileOpenDialog) failed"); result = open_dialog->SetTitle(title16.c_str()); throw_if_failed(result, "IFileOpenDialog.SetTitle failed"); result = open_dialog->SetOptions(FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST); throw_if_failed(result, "IFileOpenDialog.SetOptions((FOS_PICKFOLDERS) failed"); if(initial_directory16.length() > 0) { LPITEMIDLIST item_id_list = NULL; SFGAOF flags = 0; result = SHParseDisplayName(initial_directory16.c_str(), NULL, &item_id_list, SFGAO_FILESYSTEM, &flags); throw_if_failed(result, "SHParseDisplayName failed"); ComPtr<IShellItem> folder_item; result = SHCreateShellItem(NULL, NULL, item_id_list, folder_item.output_variable()); ILFree(item_id_list); throw_if_failed(result, "SHCreateItemFromParsingName failed"); /* This code requires Windows Vista or newer: ComPtr<IShellItem> folder_item; result = SHCreateItemFromParsingName(initial_directory16.c_str(), NULL, IID_PPV_ARGS(folder_item.output_variable())); throw_if_failed(result, "SHCreateItemFromParsingName failed"); */ if(!folder_item.is_null()) { result = open_dialog->SetFolder(folder_item); throw_if_failed(result, "IFileOpenDialog.SetFolder failed"); } } if(owner) result = open_dialog->Show(owner->get_display_window().get_hwnd()); else result = open_dialog->Show(0); if(SUCCEEDED(result)) { ComPtr<IShellItem> chosen_folder; result = open_dialog->GetResult(chosen_folder.output_variable()); throw_if_failed(result, "IFileOpenDialog.GetResult failed"); WCHAR *buffer = 0; result = chosen_folder->GetDisplayName(SIGDN_FILESYSPATH, &buffer); throw_if_failed(result, "IShellItem.GetDisplayName failed"); std::wstring output_directory16; try { output_directory16 = buffer; } catch (...) { CoTaskMemFree(buffer); throw; } CoTaskMemFree(buffer); selected_path = StringHelp::ucs2_to_utf8(output_directory16); return true; } else { return false; } } else { BROWSEINFO bi; ZeroMemory(&bi, sizeof(bi)); std::wstring::value_type path_buffer[FILENAME_MAX] = { 0 }; WCHAR Buffer[MAX_PATH]; memset(Buffer, 0, sizeof(WCHAR) * MAX_PATH); if(owner) bi.hwndOwner = owner->get_display_window().get_hwnd(); else bi.hwndOwner = 0; bi.pszDisplayName = Buffer; bi.lpszTitle = title16.c_str(); bi.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE; LPCITEMIDLIST pFolder = SHBrowseForFolder(&bi); if (pFolder == NULL) return false; if (!SHGetPathFromIDList(pFolder, path_buffer)) throw Exception("Bad path for Browse Folder Dialog"); selected_path = StringHelp::ucs2_to_utf8(path_buffer); return true; } #elif defined(__APPLE__) // To do: add cocoa code here return false; #elif defined(I_LOVE_AUTOHELL_AND_FIXED_THE_GTK_CHECK) if (!gtk_init_check(NULL, NULL)) throw Exception("gtk_init_check Failed!"); GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new ("Open File", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); //printf("%s\n", filename); g_free (filename); } gtk_widget_destroy (dialog); unsigned int x_time = System::get_time(); while(true) { if(owner) XSync(owner->get_display_window().get_display(), True); gtk_main_iteration_do(FALSE); unsigned int x_time_now = System::get_time(); if ((x_time_now - x_time) > 250) break; } bool success = false; return success; #else return false; #endif }
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::render(Canvas &canvas, const Rect &clip_rect, bool include_children) { if (!impl->visible) return; Rect viewport = get_top_level_component()->get_size(); CSSResourceCache *resource_cache = &impl->gui_manager_impl->resource_cache; CSSLayoutGraphics graphics(canvas, resource_cache, viewport, 0); Rect border_box = get_size(); Rect padding_box = Rect(border_box).shrink(impl->css_used_values.border.left, impl->css_used_values.border.top, impl->css_used_values.border.right, impl->css_used_values.border.bottom); Rect content_box = Rect(padding_box).shrink(impl->css_used_values.padding.left, impl->css_used_values.padding.top, impl->css_used_values.padding.right, impl->css_used_values.padding.bottom); CSSBackgroundRenderer background(&graphics, resource_cache, impl->element.get_css_values().get_background()); background.set_border_box(border_box); background.set_padding_box(padding_box); background.set_content_box(content_box); background.set_initial_containing_box(get_top_level_component()->get_viewport()); background.render(); CSSBorderRenderer border(&graphics, resource_cache, impl->element.get_css_values().get_border()); border.set_border_box(border_box); border.set_border_values(impl->css_used_values.border.left, impl->css_used_values.border.top, impl->css_used_values.border.right, impl->css_used_values.border.bottom); border.render(); if (impl->func_render.is_null() == false) { impl->func_render.invoke(canvas, clip_rect); } else { //GUIThemePart part(this); //Rect geometry = get_size(); //part.render_box(canvas, RectPS(0, 0, geometry.get_width(), geometry.get_height()), clip_rect); } if (include_children) { if (impl->clip_children) { push_cliprect(canvas, impl->clip_children_rect); } GUIComponent *cur = impl->first_child; while (cur) { Rect cur_geometry = cur->get_geometry(); Rect update_rect = component_to_window_coords(clip_rect); update_rect.overlap(component_to_window_coords(cur_geometry)); if (update_rect.get_width() > 0 && update_rect.get_height() > 0) { Rect child_dirty_rect = cur->window_to_component_coords(update_rect); canvas.push_translate((float)cur_geometry.left, (float)cur_geometry.top); cur->render(canvas, child_dirty_rect, true); canvas.pop_modelview(); } cur = cur->impl->next_sibling; } if (impl->clip_children) { pop_cliprect(canvas); } } }