OutputStrings::OutputStrings() { following=true; updating=false; line_max_count=4096; h_scroll = memnew( HScrollBar ); v_scroll = memnew( VScrollBar ); add_child(h_scroll); add_child(v_scroll); size_height=1; font_height=1; update_scrollbars(); h_scroll->connect("value_changed", this,"_hscroll_changed"); v_scroll->connect("value_changed", this,"_vscroll_changed"); }
void OutputStrings::_notification(int p_what) { switch(p_what) { case NOTIFICATION_DRAW: { if (following) { updating=true; v_scroll->set_val( v_scroll->get_max() - v_scroll->get_page() ); updating=false; } RID ci = get_canvas_item(); Size2 size = get_size(); Ref<Font> font = get_font("font","Tree"); Ref<StyleBox> tree_st = get_stylebox("bg","Tree"); tree_st->draw(ci,Rect2(Point2(),size)); Color color = get_color("font_color","Tree"); Ref<Texture> icon_error = get_icon("Error","EditorIcons"); Ref<Texture> icon_warning = get_icon("Warning","EditorIcons"); // int lines = (size_height-(int)margin.y) / font_height; Point2 ofs=tree_st->get_offset(); LineMap::Element *E = line_map.find(v_scroll->get_val()); float h_ofs = (int)h_scroll->get_val(); Point2 icon_ofs=Point2(0,(font_height-(int)icon_error->get_height())/2); while( E && ofs.y < (size_height-(int)margin.y) ) { String str = E->get().text; Point2 line_ofs=ofs; switch(E->get().type) { case LINE_WARNING: { icon_warning->draw(ci,line_ofs+icon_ofs); } break; case LINE_ERROR: { icon_error->draw(ci,line_ofs+icon_ofs); } break; case LINE_LINK: { } break; default: {} } line_ofs.y+=font->get_ascent(); line_ofs.x+=icon_error->get_width()+4; for(int i=0;i<str.length();i++) { if (line_ofs.x-h_ofs < 0 ) { line_ofs.x+=font->get_char_size(str[i],str[i+1]).width; } else if (line_ofs.x-h_ofs > size.width - margin.width) { break; } else { line_ofs.x+=font->draw_char(ci,Point2(line_ofs.x-h_ofs,line_ofs.y),str[i],str[i+1],color); } } ofs.y+=font_height; E=E->next(); } } break; case NOTIFICATION_ENTER_TREE: case NOTIFICATION_RESIZED: { font_height = get_font("font","Tree")->get_height(); size_height = get_size().height; update_scrollbars(); } break; } }
void ScrollContainer::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { call_deferred("_update_scrollbar_pos"); }; if (p_what==NOTIFICATION_SORT_CHILDREN) { child_max_size = Size2(0, 0); Size2 size = get_size(); if (h_scroll->is_visible()) size.y-=h_scroll->get_minimum_size().y; if (v_scroll->is_visible()) size.x-=h_scroll->get_minimum_size().x; for(int i=0;i<get_child_count();i++) { Control *c = get_child(i)->cast_to<Control>(); if (!c) continue; if (c->is_set_as_toplevel()) continue; if (c == h_scroll || c == v_scroll) continue; Size2 minsize = c->get_combined_minimum_size(); child_max_size.x = MAX(child_max_size.x, minsize.x); child_max_size.y = MAX(child_max_size.y, minsize.y); Rect2 r = Rect2(-scroll,minsize); if (!(scroll_h || h_scroll->is_visible())) { r.pos.x=0; if (c->get_h_size_flags()&SIZE_EXPAND) r.size.width=MAX(size.width,minsize.width); else r.size.width=minsize.width; } if (!(scroll_v || v_scroll->is_visible())) { r.pos.y=0; r.size.height=size.height; if (c->get_v_size_flags()&SIZE_EXPAND) r.size.height=MAX(size.height,minsize.height); else r.size.height=minsize.height; } fit_child_in_rect(c,r); } update(); }; if (p_what == NOTIFICATION_DRAW) { update_scrollbars(); VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(),true); } if (p_what==NOTIFICATION_FIXED_PROCESS) { if (drag_touching) { if (drag_touching_deaccel) { Vector2 pos = Vector2(h_scroll->get_val(),v_scroll->get_val()); pos+=drag_speed*get_fixed_process_delta_time(); bool turnoff_h=false; bool turnoff_v=false; if (pos.x<0) { pos.x=0; turnoff_h=true; } if (pos.x > (h_scroll->get_max()-h_scroll->get_page())) { pos.x=h_scroll->get_max()-h_scroll->get_page(); turnoff_h=true; } if (pos.y<0) { pos.y=0; turnoff_v=true; } if (pos.y > (v_scroll->get_max()-v_scroll->get_page())) { pos.y=v_scroll->get_max()-v_scroll->get_page(); turnoff_v=true; } if (scroll_h) h_scroll->set_val(pos.x); if (scroll_v) v_scroll->set_val(pos.y); float sgn_x = drag_speed.x<0? -1 : 1; float val_x = Math::abs(drag_speed.x); val_x-=1000*get_fixed_process_delta_time(); if (val_x<0) { turnoff_h=true; } float sgn_y = drag_speed.y<0? -1 : 1; float val_y = Math::abs(drag_speed.y); val_y-=1000*get_fixed_process_delta_time(); if (val_y<0) { turnoff_v=true; } drag_speed=Vector2(sgn_x*val_x,sgn_y*val_y); if (turnoff_h && turnoff_v) { set_fixed_process(false); drag_touching=false; drag_touching_deaccel=false; } } else { if (time_since_motion==0 || time_since_motion>0.1) { Vector2 diff = drag_accum - last_drag_accum; last_drag_accum=drag_accum; drag_speed=diff/get_fixed_process_delta_time(); } time_since_motion+=get_fixed_process_delta_time(); } } } };