void StatusBar_Impl::position_parts() { Rect rect(Point(0,0), statusbar->get_geometry().get_size()); Rect content = statusbar->get_content_box(); int xpos = content.right; if (show_size_grip) { int preferred_width = part_size_grip.get_css_width(); Rect rect_sizegrip(content.right - preferred_width, content.top, content.right, content.bottom); xpos = rect_sizegrip.left; } for (unsigned int index = statusbar_parts.size(); index > 0; index--) { StatusBar_Part &statusbar_part = statusbar_parts[index-1]; int left = xpos - statusbar_part.width; int right = xpos; Rect new_position(left, content.top, right, content.bottom); if (statusbar_part.component && statusbar_part.position != new_position) statusbar_part.component->set_geometry(part_status_part.get_content_box(new_position)); statusbar_part.position = new_position; xpos = left; } }
void RadioButton_Impl::on_enablemode_changed() { radio->set_pseudo_class(CssStr::disabled, !radio->is_enabled()); radio->set_pseudo_class(CssStr::normal, radio->is_enabled()); part_checker.set_pseudo_class(CssStr::disabled, !radio->is_enabled()); part_checker.set_pseudo_class(CssStr::normal, radio->is_enabled()); radio->request_repaint(); }
void Window_Impl::on_render(Canvas &canvas, const Rect &update_rect) { if (!has_frame) return; Rect rect = window->get_size(); int caption_height = part_caption.get_css_height(); int frameleft_width = part_frameleft.get_css_width(); int frameright_width = part_frameright.get_css_width(); int framebottom_height = part_framebottom.get_css_height(); Rect caption_rect = Rect(rect.left, rect.top, rect.right, rect.top + caption_height); part_caption.render_box(canvas, caption_rect); Rect frameleft_rect = Rect(rect.left, rect.top + caption_height, rect.left + frameleft_width, rect.bottom - framebottom_height); part_frameleft.render_box(canvas, frameleft_rect); Rect frameright_rect = Rect(rect.right - frameright_width, rect.top + caption_height, rect.right, rect.bottom - framebottom_height); part_frameright.render_box(canvas, frameright_rect); Rect framebottom_rect = Rect(rect.left, rect.bottom - framebottom_height, rect.right, rect.bottom); part_framebottom.render_box(canvas, framebottom_rect); Rect part_buttonclose_rect = get_part_buttonclose_rect(); part_buttonclose.render_box(canvas, part_buttonclose_rect); Size text_size = window->get_render_text_size(canvas, title); window->render_text(canvas, title, caption_rect.left + 10, caption_rect.top + caption_rect.get_height()/2 + text_size.height/2 - 2); }
Rect Window_Impl::get_part_buttonclose_rect() const { Rect rect = window->get_size(); Size part_buttonclose_size = part_buttonclose.get_css_size(); int frameright_width = part_frameright.get_css_width(); int caption_height = part_caption.get_css_height(); return Rect(rect.right - part_buttonclose_size.width - frameright_width - 2, rect.top + caption_height - part_buttonclose_size.height - 3, rect.right - frameright_width - 2, rect.top + caption_height - 3); }
void RadioButton_Impl::create_parts() { part_checker = GUIThemePart(radio, CssStr::RadioButton::part_checker); part_checker.set_pseudo_class(CssStr::hover, false); part_checker.set_pseudo_class(CssStr::normal, true); part_checker.set_pseudo_class(CssStr::pressed, false); part_checker.set_pseudo_class(CssStr::checked, false); part_checker.set_pseudo_class(CssStr::indeterminated, false); part_checker.set_pseudo_class(CssStr::unchecked, true); part_checker.set_pseudo_class(CssStr::disabled, false); part_focus = GUIThemePart(radio, CssStr::RadioButton::part_focus); }
Rect Window_Impl::get_client_area() const { Rect rect = window->get_size(); if (!has_frame) return rect; int caption_height = part_caption.get_css_height(); int frameleft_width = part_frameleft.get_css_width(); int frameright_width = part_frameright.get_css_width(); int framebottom_height = part_framebottom.get_css_height(); return Rect(rect.left + frameleft_width, rect.top + caption_height, rect.right - frameright_width, rect.bottom - framebottom_height); }
void ProgressBar_Impl::on_render(Canvas &canvas, const Rect &update_rect) { Rect rect = progressbar->get_size(); if (marquee_mode) { if (rect.get_width() > 0) { Rect content_box = progressbar->get_content_box(); Rect progress_rect; progress_rect.left = content_box.left + marquee_position; progress_rect.top = content_box.top; progress_rect.bottom = content_box.bottom; progress_rect.right = content_box.left + marquee_position + marquee_box_width; if (progress_rect.left < content_box.left) { progress_rect.left = 0; progress_rect.right -= (content_box.left - progress_rect.left); } if (progress_rect.right > content_box.right) { progress_rect.right -= (progress_rect.right - content_box.right); } part_progress.render_box(canvas, progress_rect); } } else { if (progress_max >= progress_min && position >= progress_min && position <= progress_max && progress_min != progress_max && rect.get_width() > 0) { Rect content_box = progressbar->get_content_box(); Rect progress_rect; progress_rect.left = content_box.left; progress_rect.top = content_box.top; progress_rect.bottom = content_box.bottom; progress_rect.right = content_box.left + (position - progress_min) * content_box.get_width() / (progress_max - progress_min); part_progress.render_box(canvas, progress_rect); } } }
void Window_Impl::check_move_window(std::shared_ptr<GUIMessage> &msg) { if (draggable == false) { drag_start = false; return; } std::shared_ptr<GUIMessage_Pointer> pointer = std::dynamic_pointer_cast<GUIMessage_Pointer>(msg); if (pointer) { msg->consumed = true; } std::shared_ptr<GUIMessage_Input> input_msg = std::dynamic_pointer_cast<GUIMessage_Input>(msg); if (input_msg) { InputEvent &e = input_msg->input_event; if (e.type == InputEvent::pressed && e.id == mouse_left) { window->bring_to_front(); Rect rect = window->get_size(); int caption_height = part_caption.get_css_height(); Rect caption_rect = Rect(rect.left, rect.top, rect.right, rect.top + caption_height); if (caption_rect.contains(e.mouse_pos)) { drag_start = true; window->capture_mouse(true); last_mouse_pos = e.mouse_pos; } } else if (e.type == InputEvent::released && e.id == mouse_left) { if(drag_start) { drag_start = false; window->capture_mouse(false); } } else if (e.type == InputEvent::pointer_moved && drag_start == true) { if (window->get_parent_component()) { Rect geometry = window->get_geometry(); geometry.translate(e.mouse_pos.x - last_mouse_pos.x, e.mouse_pos.y - last_mouse_pos.y); window->set_geometry(geometry); } else { Rect geometry = window->get_window_geometry(); geometry.translate(e.mouse_pos.x - last_mouse_pos.x, e.mouse_pos.y - last_mouse_pos.y); window->set_window_geometry(geometry); } } } }
void Window_Impl::on_process_message(std::shared_ptr<GUIMessage> &msg) { if (!window->is_enabled()) return; if (!has_frame) // Performed by the OS on system wm return; check_move_window(msg); Rect part_buttonclose_rect = get_part_buttonclose_rect(); std::shared_ptr<GUIMessage_Input> input_msg = std::dynamic_pointer_cast<GUIMessage_Input>(msg); if (input_msg) { InputEvent &e = input_msg->input_event; if (e.type == InputEvent::pressed && e.id == mouse_left) { if(part_buttonclose_rect.contains(e.mouse_pos)) if(part_buttonclose.set_pseudo_class(CssStr::pressed, true)) window->request_repaint(); } else if (e.type == InputEvent::released && e.id == mouse_left) { if(part_buttonclose.set_pseudo_class(CssStr::pressed, false)) { window->request_repaint(); if (window->func_close() && window->func_close()()) msg->consumed = true; } } else if (e.type == InputEvent::pointer_moved) { bool inside = part_buttonclose_rect.contains(e.mouse_pos); if (part_buttonclose.get_pseudo_class(CssStr::hover) != inside) { part_buttonclose.set_pseudo_class(CssStr::hover, inside); window->request_repaint(); } } } }
void RadioButton_Impl::on_render(Canvas &canvas, const Rect &update_rect) { Rect rect = radio->get_size(); Size pref_size = part_checker.get_css_size(); Rect content_rect = radio->get_content_box(); int ypos = content_rect.top + content_rect.get_height()/2 - pref_size.height/2; Rect checker_rect(content_rect.left, ypos, content_rect.left + pref_size.width, ypos + pref_size.height); part_checker.render_box(canvas, checker_rect); int text_gap = radio->get_property_int(CssStr::text_gap, "2"); Size text_size = radio->render_text(canvas, text, checker_rect.right + text_gap, radio->get_vertical_text_align(canvas).baseline).get_size(); if (radio->has_focus()) { int focus_left = checker_rect.right + text_gap - 2; // todo: remove magic number hacks Rect focus_rect = RectPS(focus_left, content_rect.top, text_size.width+4, content_rect.bottom); part_focus.render_box(canvas, focus_rect); } }
void Window_Impl::create_parts() { if (has_frame) { part_caption = GUIThemePart(window, CssStr::Window::part_caption); part_frameleft = GUIThemePart(window, CssStr::Window::part_frameleft); part_frameright = GUIThemePart(window, CssStr::Window::part_frameright); part_framebottom = GUIThemePart(window, CssStr::Window::part_framebottom); part_buttonclose = GUIThemePart(window, CssStr::Window::part_buttonclose); part_buttonclose.set_pseudo_class(CssStr::normal, true); } }
void ToolBar_Impl::on_render(Canvas &canvas, const Rect &update_rect) { update_layout(canvas); Rect rect = toolbar->get_size(); std::vector<ToolBarItem>::size_type index, size; size = items.size(); for (index = 0; index < size; index++) { ToolBarItem &item = items[index]; GUIThemePart part_item = part_item_normal; if (index == index_hot_item) part_item = part_item_hot; if (index == index_pressed_item || items[index].impl->pressed) part_item = part_item_pressed; Rect item_content = part_item.get_content_box(item.impl->position); part_item.render_box(canvas, item.impl->position); Rect icon_pos = item.impl->icon_pos; icon_pos.translate(item_content.left, item_content.top); Point pressed_offset(0,0); if (index == index_pressed_item) pressed_offset = Point(0,0); // To do: Read this from css properties or remove feature totally if (!item.impl->icon.is_null()) { icon_pos.translate(pressed_offset); item.impl->icon.set_frame(item.impl->frame); item.impl->icon.draw(canvas, icon_pos); } //FIXME: toolbar->push_cliprect(canvas, item_content); //canvas.fill_rect(item_content, Colorf::gray); // FIXME: Added 256 as a hack .. until someone fixes this class part_item_normal.render_text(canvas, item.impl->text, Rect(item_content.left + item.impl->text_pos.x + pressed_offset.x, item_content.top + item.impl->text_pos.y + pressed_offset.y, item_content.right+256, item_content.bottom+256)); //toolbar->pop_cliprect(canvas); } }
void TabHeader_Impl::on_render(Canvas &canvas, const Rect &update_rect) { Rect rect = component->get_geometry(); std::vector<Handle>::size_type i; for (i = 0; i < tabs.size(); i++) { Handle &handle = tabs[i]; handle.part.render_box(canvas, handle.rect); Rect rect_handle_content = handle.part.get_content_box(handle.rect); Size text_size = handle.part.render_text(canvas, handle.label, rect_handle_content).get_size(); if (component->has_focus() && i == selected_page) { Rect focus_rect = handle.rect; focus_rect.shrink(2,2,2,2); part_focus.render_box(canvas, focus_rect); } } }
void ToolBar_Impl::create_parts() { toolbar->set_pseudo_class(CssStr::horizontal, true); part_item_normal = GUIThemePart(toolbar, CssStr::ToolBar::part_item); part_item_normal.set_pseudo_class(CssStr::normal, true); part_item_disabled = GUIThemePart(toolbar, CssStr::ToolBar::part_item); part_item_disabled.set_pseudo_class(CssStr::disabled, true); part_item_pressed = GUIThemePart(toolbar, CssStr::ToolBar::part_item); part_item_pressed.set_pseudo_class(CssStr::pressed, true); part_item_hot = GUIThemePart(toolbar, CssStr::ToolBar::part_item); part_item_hot.set_pseudo_class(CssStr::hover, true); part_item_on = GUIThemePart(toolbar, CssStr::ToolBar::part_item); part_item_on.set_pseudo_class(CssStr::on, true); size_icon.width = part_item_normal.get_property_int(CssStr::icon_width, "0"); size_icon.height = part_item_normal.get_property_int(CssStr::icon_height, "0"); std::string str_alignment = toolbar->get_property(CssStr::layout, "left"); if (str_alignment == "center") layout = layout_center; else layout = layout_left; need_layout_update = true; }
void StatusBar_Impl::on_render(Canvas &canvas, const Rect &update_rect) { Rect rect(Point(0,0), statusbar->get_geometry().get_size()); Rect content = statusbar->get_content_box(); Rect rect_status_text = content; if (show_size_grip) { int preferred_width = part_size_grip.get_css_width(); Rect rect_sizegrip(content.right - preferred_width, content.top, content.right, content.bottom); part_size_grip.render_box(canvas, rect_sizegrip); rect_status_text.right = rect_sizegrip.left; } if (!statusbar_parts.empty()) rect_status_text.right = statusbar_parts[0].position.left; part_status_text.render_box(canvas, rect_status_text); Rect status_text_content = part_status_text.get_content_box(rect_status_text); statusbar->render_text(canvas, status_text, status_text_content.left + 4, content.bottom - 6); for (unsigned int index = 0; index < statusbar_parts.size(); index++) { StatusBar_Part &statusbar_part = statusbar_parts[index]; part_status_part.render_box(canvas, statusbar_part.position); Rect part_content = part_status_part.get_content_box(statusbar_part.position); int icon_width = 0; if (!statusbar_part.icon.is_null()) { statusbar_part.icon.draw(canvas, (float)part_content.left + 4, (float)part_content.bottom - 6 - statusbar_part.icon.get_height()); icon_width = statusbar_part.icon.get_width() + 4; } if (!statusbar_part.text.empty()) { statusbar->render_text(canvas, statusbar_part.text, part_content.left + 4 + icon_width, part_content.bottom - 6); } } }
void ToolBar_Impl::update_layout(Canvas &canvas) { if (need_layout_update == false) return; need_layout_update = false; Rect rect = toolbar->get_size(); Rect component_content = toolbar->get_content_box(); Rect item_content = part_item_normal.get_content_box(component_content); int original_text_gap = part_item_normal.get_property_int(CssStr::text_gap, "3"); if (horizontal) { int x = component_content.left; int center_y = item_content.get_center().y; int item_size = part_item_normal.get_css_width(); std::vector<ToolBarItem>::size_type index, size; size = items.size(); for (index = 0; index < size; index++) { ToolBarItem &item = items[index]; item_content.left = x; Size text_size = toolbar->get_render_text_size(canvas, item.impl->text); int text_gap = original_text_gap; if (text_size.width == 0) text_gap = 0; if (layout == layout_left) { item.impl->icon_pos = Rect(Point(0, center_y-size_icon.height/2-item_content.top), size_icon); item_content.right = item_content.left + item.impl->icon_pos.get_width() + text_gap + text_size.width; item.impl->text_pos = Point(item.impl->icon_pos.right + text_gap, part_item_normal.get_vertical_text_align(canvas, item_content).baseline-item_content.top); } else if (layout == layout_center) { item.impl->icon_pos = Rect(Point(item_size/2-size_icon.width/2, 0), size_icon); item.impl->text_pos = Point(item_size/2-text_size.width/2, item.impl->icon_pos.bottom + text_gap + text_size.height); item_content.right = item_content.left + item_size; } Rect item_render = part_item_normal.get_border_box(item_content); Rect shrink_box = part_item_normal.get_content_shrink_box(); item_render.translate(shrink_box.left,0); item.impl->position = item_render; x = item_render.right; } } else { int y = component_content.top; int center_x = item_content.get_center().x; int size_item = part_item_normal.get_css_height(); std::vector<ToolBarItem>::size_type index, size; size = items.size(); for (index = 0; index < size; index++) { ToolBarItem &item = items[index]; item_content.top = y; Size text_size = toolbar->get_render_text_size(canvas, item.impl->text); int text_gap = original_text_gap; if (text_size.width == 0) text_gap = 0; if (layout == layout_left) { item.impl->icon_pos = Rect(Point(0,0), size_icon); item.impl->text_pos = Point(item.impl->icon_pos.right + text_gap, size_item/2+text_size.height/2); item_content.bottom = item_content.top + size_item; } else if (layout == layout_center) { item.impl->icon_pos = Rect(Point(center_x-size_icon.width/2, 0), size_icon); item.impl->text_pos = Point(center_x-text_size.width/2, item.impl->icon_pos.bottom + text_gap + text_size.height); item_content.bottom = item_content.top + item.impl->icon_pos.get_height() + text_gap + text_size.height; } Rect item_render = part_item_normal.get_border_box(item_content); Rect shrink_box = part_item_normal.get_content_shrink_box(); item_render.translate(0, shrink_box.top); item.impl->position = item_render; y = item_render.bottom; } } // toolbar->request_repaint(); }
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; } }