Пример #1
0
void Tabs::_ensure_no_over_offset() {

	if (!is_inside_tree())
		return;

	Ref<Texture> incr = get_icon("increment");
	Ref<Texture> decr = get_icon("decrement");

	int limit = get_size().width - incr->get_width() - decr->get_width();

	while (offset > 0) {

		int total_w = 0;
		for (int i = 0; i < tabs.size(); i++) {

			if (i < offset - 1)
				continue;

			total_w += get_tab_width(i);
		}

		if (total_w < limit) {
			offset--;
			update();
		} else {
			break;
		}
	}
}
Пример #2
0
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();
}
Пример #3
0
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;
	}
}
Пример #4
0
void Tabs::_update_cache() {
	Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled");
	Ref<StyleBox> tab_bg = get_stylebox("tab_bg");
	Ref<StyleBox> tab_fg = get_stylebox("tab_fg");
	Ref<Font> font = get_font("font");
	Ref<Texture> incr = get_icon("increment");
	Ref<Texture> decr = get_icon("decrement");
	int limit = get_size().width - incr->get_width() - decr->get_width();

	int w = 0;
	int mw = 0;
	int size_fixed = 0;
	int count_resize = 0;
	for (int i = 0; i < tabs.size(); i++) {
		tabs[i].ofs_cache = mw;
		tabs[i].size_cache = get_tab_width(i);
		tabs[i].size_text = font->get_string_size(tabs[i].text).width;
		mw += tabs[i].size_cache;
		if (tabs[i].size_cache <= min_width || i == current) {
			size_fixed += tabs[i].size_cache;
		} else {
			count_resize++;
		}
	}
	int m_width = min_width;
	if (count_resize > 0) {
		m_width = MAX((limit - size_fixed) / count_resize, min_width);
	}
	for (int i = 0; i < tabs.size(); i++) {
		if (i < offset)
			continue;
		Ref<StyleBox> sb;
		if (tabs[i].disabled) {
			sb = tab_disabled;
		} else if (i == current) {
			sb = tab_fg;
		} else {
			sb = tab_bg;
		}
		int lsize = tabs[i].size_cache;
		int slen = tabs[i].size_text;
		if (min_width > 0 && mw > limit && i != current) {
			if (lsize > m_width) {
				slen = m_width - (sb->get_margin(MARGIN_LEFT) + sb->get_margin(MARGIN_RIGHT));
				if (tabs[i].icon.is_valid()) {
					slen -= tabs[i].icon->get_width();
					slen -= get_constant("hseparation");
				}
				if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
					Ref<Texture> cb = get_icon("close");
					slen -= cb->get_width();
					slen -= get_constant("hseparation");
				}
				slen = MAX(slen, 1);
				lsize = m_width;
			}
		}
		tabs[i].ofs_cache = w;
		tabs[i].size_cache = lsize;
		tabs[i].size_text = slen;
		w += lsize;
	}
}