void Tabs::remove_tab(int p_idx) { ERR_FAIL_INDEX(p_idx, tabs.size()); tabs.remove(p_idx); if (current >= p_idx) current--; update(); minimum_size_changed(); if (current < 0) current = 0; if (current >= tabs.size()) current = tabs.size() - 1; _ensure_no_over_offset(); }
void Tabs::ensure_tab_visible(int p_idx) { if (!is_inside_tree()) return; ERR_FAIL_INDEX(p_idx,tabs.size()); _ensure_no_over_offset(); if (p_idx<=offset) { offset=p_idx; update(); return; } Ref<Texture> incr = get_icon("increment"); Ref<Texture> decr = get_icon("decrement"); int limit=get_size().width-incr->get_width()-decr->get_width(); int x=0; for(int i=0;i<tabs.size();i++) { if (i<offset) continue; int sz = get_tab_width(i); tabs[i].x_cache=x; tabs[i].x_size_cache=sz; x+=sz; } while(offset<tabs.size() && ( (tabs[p_idx].x_cache + tabs[p_idx].x_size_cache) - tabs[offset].x_cache) > limit) { offset++; } update(); }
void Tabs::_notification(int p_what) { switch (p_what) { case NOTIFICATION_MOUSE_EXIT: { rb_hover = -1; cb_hover = -1; hover = -1; update(); } break; case NOTIFICATION_RESIZED: { _ensure_no_over_offset(); } break; case NOTIFICATION_DRAW: { RID ci = get_canvas_item(); Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); Ref<Font> font = get_font("font"); Color color_fg = get_color("font_color_fg"); Color color_bg = get_color("font_color_bg"); Ref<Texture> close = get_icon("close"); int h = get_size().height; int w = 0; int mw = 0; for (int i = 0; i < tabs.size(); i++) { tabs[i].ofs_cache = mw; mw += get_tab_width(i); } if (tab_align == ALIGN_CENTER) { w = (get_size().width - mw) / 2; } else if (tab_align == ALIGN_RIGHT) { w = get_size().width - mw; } if (w < 0) { w = 0; } Ref<Texture> incr = get_icon("increment"); Ref<Texture> decr = get_icon("decrement"); Ref<Texture> incr_hl = get_icon("increment_hilite"); Ref<Texture> decr_hl = get_icon("decrement_hilite"); int limit = get_size().width - incr->get_size().width - decr->get_size().width; missing_right = false; for (int i = 0; i < tabs.size(); i++) { if (i < offset) continue; tabs[i].ofs_cache = w; int lsize = get_tab_width(i); String text = tabs[i].text; int slen = font->get_string_size(text).width; if (w + lsize > limit) { max_drawn_tab = i - 1; missing_right = true; break; } else { max_drawn_tab = i; } Ref<StyleBox> sb; Color col; if (i == current) { sb = tab_fg; col = color_fg; } else { sb = tab_bg; col = color_bg; } Rect2 sb_rect = Rect2(w, 0, lsize, h); sb->draw(ci, sb_rect); w += sb->get_margin(MARGIN_LEFT); Size2i sb_ms = sb->get_minimum_size(); Ref<Texture> icon = tabs[i].icon; if (icon.is_valid()) { icon->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); if (text != "") w += icon->get_width() + get_constant("hseparation"); } font->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - font->get_height()) / 2 + font->get_ascent()), text, col); w += slen; if (tabs[i].right_button.is_valid()) { Ref<StyleBox> style = get_stylebox("button"); Ref<Texture> rb = tabs[i].right_button; w += get_constant("hseparation"); Rect2 rb_rect; rb_rect.size = style->get_minimum_size() + rb->get_size(); rb_rect.pos.x = w; rb_rect.pos.y = sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2; if (rb_hover == i) { if (rb_pressing) get_stylebox("button_pressed")->draw(ci, rb_rect); else style->draw(ci, rb_rect); } rb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), rb_rect.pos.y + style->get_margin(MARGIN_TOP))); w += rb->get_width(); tabs[i].rb_rect = rb_rect; } if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { Ref<StyleBox> style = get_stylebox("button"); Ref<Texture> cb = close; w += get_constant("hseparation"); Rect2 cb_rect; cb_rect.size = style->get_minimum_size() + cb->get_size(); cb_rect.pos.x = w; cb_rect.pos.y = sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2; if (cb_hover == i) { if (cb_pressing) get_stylebox("button_pressed")->draw(ci, cb_rect); else style->draw(ci, cb_rect); } cb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), cb_rect.pos.y + style->get_margin(MARGIN_TOP))); w += cb->get_width(); tabs[i].cb_rect = cb_rect; } w += sb->get_margin(MARGIN_RIGHT); tabs[i].size_cache = w - tabs[i].ofs_cache; } if (offset > 0 || missing_right) { int vofs = (get_size().height - incr->get_size().height) / 2; if (offset > 0) draw_texture(hilite_arrow == 0 ? decr_hl : decr, Point2(limit, vofs)); else draw_texture(decr, Point2(limit, vofs), Color(1, 1, 1, 0.5)); if (missing_right) draw_texture(hilite_arrow == 1 ? incr_hl : incr, Point2(limit + decr->get_size().width, vofs)); else draw_texture(incr, Point2(limit + decr->get_size().width, vofs), Color(1, 1, 1, 0.5)); buttons_visible = true; } else { buttons_visible = false; } } break; } }