Пример #1
0
void TabContainer::add_child_notify(Node *p_child) {

    Control::add_child_notify(p_child);

    Control *c = p_child->cast_to<Control>();
    if (!c)
        return;
    if (c->is_set_as_toplevel())
        return;

    bool first=false;

    if (get_tab_count()!=1)
        c->hide();
    else {
        c->show();
        //call_deferred("set_current_tab",0);
        first=true;
        current=0;
    }
    c->set_area_as_parent_rect();
    if (tabs_visible)
        c->set_margin(MARGIN_TOP,_get_top_margin());
    Ref<StyleBox> sb = get_stylebox("panel");
    for(int i=0; i<4; i++)
        c->set_margin(Margin(i),c->get_margin(Margin(i))+sb->get_margin(Margin(i)));


    update();
    p_child->connect("renamed", this,"_child_renamed_callback");
    if(first)
        emit_signal("tab_changed",current);
}
Пример #2
0
void TabContainer::set_current_tab(int p_current) {

    ERR_FAIL_INDEX( p_current, get_tab_count() );

    current=p_current;

    int idx=0;

    Ref<StyleBox> sb=get_stylebox("panel");
    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 (idx==current) {
            c->show();
            c->set_area_as_parent_rect();
            if (tabs_visible)
                c->set_margin(MARGIN_TOP,_get_top_margin());
            for(int i=0; i<4; i++)
                c->set_margin(Margin(i),c->get_margin(Margin(i))+sb->get_margin(Margin(i)));


        } else
            c->hide();
        idx++;
    }

    _change_notify("current_tab");
    emit_signal("tab_changed",current);
    update();
}
Пример #3
0
void TabContainer::set_tabs_visible(bool p_visibe) {

	if (p_visibe == tabs_visible)
		return;

	tabs_visible = p_visibe;

	Vector<Control *> tabs = _get_tabs();
	for (int i = 0; i < tabs.size(); i++) {

		Control *c = tabs[i];
		if (p_visibe)
			c->set_margin(MARGIN_TOP, _get_top_margin());
		else
			c->set_margin(MARGIN_TOP, 0);
	}
	update();
}
Пример #4
0
void TabContainer::set_tabs_visible(bool p_visibe) {

    if (p_visibe==tabs_visible)
        return;

    tabs_visible=p_visibe;

    for(int i=0; i<get_child_count(); i++) {

        Control *c = get_child(i)->cast_to<Control>();
        if (!c)
            continue;
        if (p_visibe)
            c->set_margin(MARGIN_TOP,_get_top_margin());
        else
            c->set_margin(MARGIN_TOP,0);

    }
    update();
}
Пример #5
0
void TabContainer::set_current_tab(int p_current) {

	ERR_FAIL_INDEX(p_current, get_tab_count());

	int pending_previous = current;
	current = p_current;

	Ref<StyleBox> sb = get_stylebox("panel");
	Vector<Control *> tabs = _get_tabs();
	for (int i = 0; i < tabs.size(); i++) {

		Control *c = tabs[i];
		if (i == current) {
			c->show();
			c->set_area_as_parent_rect();
			if (tabs_visible)
				c->set_margin(MARGIN_TOP, _get_top_margin());
			c->set_margin(Margin(MARGIN_TOP), c->get_margin(Margin(MARGIN_TOP)) + sb->get_margin(Margin(MARGIN_TOP)));
			c->set_margin(Margin(MARGIN_LEFT), c->get_margin(Margin(MARGIN_LEFT)) + sb->get_margin(Margin(MARGIN_LEFT)));
			c->set_margin(Margin(MARGIN_RIGHT), c->get_margin(Margin(MARGIN_RIGHT)) - sb->get_margin(Margin(MARGIN_RIGHT)));
			c->set_margin(Margin(MARGIN_BOTTOM), c->get_margin(Margin(MARGIN_BOTTOM)) - sb->get_margin(Margin(MARGIN_BOTTOM)));

		} else
			c->hide();
	}

	_change_notify("current_tab");

	if (pending_previous == current)
		emit_signal("tab_selected", current);
	else {
		previous = pending_previous;
		emit_signal("tab_selected", current);
		emit_signal("tab_changed", current);
	}

	update();
}
Пример #6
0
void TabContainer::_input_event(const InputEvent& p_event) {

    if (p_event.type==InputEvent::MOUSE_BUTTON &&
            p_event.mouse_button.pressed &&
            p_event.mouse_button.button_index==BUTTON_LEFT) {

        // clicks
        Point2 pos( p_event.mouse_button.x, p_event.mouse_button.y );

        int top_margin = _get_top_margin();
        if (pos.y>top_margin)
            return; // no click (too far down)

        if (pos.x<tabs_ofs_cache)
            return; // no click (too far left)

        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");
        Ref<Texture> menu = get_icon("menu");
        Ref<Texture> menu_hl = get_icon("menu_hl");

        if (popup && pos.x>get_size().width-menu->get_width()) {


            emit_signal("pre_popup_pressed");
            Vector2 pp_pos = get_global_pos();
            pp_pos.x+=get_size().width;
            pp_pos.x-=popup->get_size().width;
            pp_pos.y+=menu->get_height();

            popup->set_global_pos( pp_pos );
            popup->popup();;
            return;
        }
        pos.x-=tabs_ofs_cache;

        int idx=0;
        int found=-1;
        bool rightroom=false;

        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 (idx<tab_display_ofs) {
                idx++;
                continue;
            }

            if (idx>last_tab_cache) {
                rightroom=true;
                break;
            }

            String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name());
            int tab_width=font->get_string_size(s).width;

            if (c->has_meta("_tab_icon")) {
                Ref<Texture> icon = c->get_meta("_tab_icon");
                if (icon.is_valid()) {
                    tab_width+=icon->get_width();
                    if (s!="")
                        tab_width+=get_constant("hseparation");

                }
            }

            if (idx==current) {

                tab_width+=tab_fg->get_minimum_size().width;
            } else {
                tab_width+=tab_bg->get_minimum_size().width;
            }

            if (pos.x < tab_width) {

                found=idx;
                break;
            }

            pos.x-=tab_width;
            idx++;
        }

        if (buttons_visible_cache) {

            if (p_event.mouse_button.x>get_size().width-incr->get_width()) {
                if (rightroom) {
                    tab_display_ofs+=1;
                    update();
                }
            } else if (p_event.mouse_button.x>get_size().width-incr->get_width()-decr->get_width()) {

                if (tab_display_ofs>0) {
                    tab_display_ofs-=1;
                    update();
                }

            }
        }


        if (found!=-1) {

            set_current_tab(found);
        }
    }

}
Пример #7
0
void TabContainer::_notification(int p_what) {


    switch(p_what) {


    case NOTIFICATION_DRAW: {

        RID ci = get_canvas_item();
        Ref<StyleBox> panel = get_stylebox("panel");
        Size2 size = get_size();

        if (!tabs_visible) {

            panel->draw(ci, Rect2( 0, 0, size.width, size.height));
            return;
        }



        Ref<StyleBox> tab_bg = get_stylebox("tab_bg");
        Ref<StyleBox> tab_fg = get_stylebox("tab_fg");
        Ref<Texture> incr = get_icon("increment");
        Ref<Texture> decr = get_icon("decrement");
        Ref<Texture> menu = get_icon("menu");
        Ref<Texture> menu_hl = get_icon("menu_hl");
        Ref<Font> font = get_font("font");
        Color color_fg = get_color("font_color_fg");
        Color color_bg = get_color("font_color_bg");

        int side_margin = get_constant("side_margin");
        int top_margin = _get_top_margin();


        Size2 top_size = Size2( size.width, top_margin );



        int w=0;
        int idx=0;
        Vector<int> offsets;
        Vector<Control*> controls;
        int from=0;
        int limit=get_size().width;
        if (popup) {
            top_size.width-=menu->get_width();
            limit-=menu->get_width();
        }

        bool notdone=false;
        last_tab_cache=-1;

        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 (idx<tab_display_ofs) {
                idx++;
                from=idx;
                continue;
            }

            if (w>=get_size().width) {
                buttons_visible_cache=true;
                notdone=true;
                break;
            }

            offsets.push_back(w);
            controls.push_back(c);

            String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name());
            w+=font->get_string_size(s).width;
            if (c->has_meta("_tab_icon")) {
                Ref<Texture> icon = c->get_meta("_tab_icon");
                if (icon.is_valid()) {
                    w+=icon->get_width();
                    if (s!="")
                        w+=get_constant("hseparation");

                }
            }

            if (idx==current) {

                w+=tab_fg->get_minimum_size().width;
            } else {
                w+=tab_bg->get_minimum_size().width;
            }

            if (idx<tab_display_ofs) {

            }
            last_tab_cache=idx;

            idx++;
        }


        int ofs;

        switch(align) {

        case ALIGN_LEFT:
            ofs = side_margin;
            break;
        case ALIGN_CENTER:
            ofs = (int(limit) - w)/2;
            break;
        case ALIGN_RIGHT:
            ofs = int(limit) - w - side_margin;
            break;
        };

        tab_display_ofs=0;


        tabs_ofs_cache=ofs;
        idx=0;



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

            idx=i+from;
            if (current>=from && current<from+controls.size()-1) {
                //current is visible! draw it last.
                if (i==controls.size()-1) {
                    idx=current;
                } else if (idx>=current) {
                    idx+=1;
                }
            }

            Control *c = controls[idx-from];

            String s = c->has_meta("_tab_name")?String(c->get_meta("_tab_name")):String(c->get_name());
            int w=font->get_string_size(s).width;
            Ref<Texture> icon;
            if (c->has_meta("_tab_icon")) {
                icon = c->get_meta("_tab_icon");
                if (icon.is_valid()) {

                    w+=icon->get_width();
                    if (s!="")
                        w+=get_constant("hseparation");

                }
            }


            Ref<StyleBox> sb;
            Color col;

            if (idx==current) {

                sb=tab_fg;
                col=color_fg;
            } else {
                sb=tab_bg;
                col=color_bg;
            }

            int lofs = ofs + offsets[idx-from];

            Size2i sb_ms = sb->get_minimum_size();
            Rect2 sb_rect = Rect2( lofs, 0, w+sb_ms.width, top_margin);


            sb->draw(ci, sb_rect );

            Point2i lpos = sb_rect.pos;
            lpos.x+=sb->get_margin(MARGIN_LEFT);
            if (icon.is_valid()) {

                icon->draw(ci, Point2i( lpos.x, sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-icon->get_height())/2 ) );
                if (s!="")
                    lpos.x+=icon->get_width()+get_constant("hseparation");

            }

            font->draw(ci, Point2i( lpos.x, sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-font->get_height())/2+font->get_ascent() ), s, col );

            idx++;
        }


        if (buttons_visible_cache) {

            int vofs = (top_margin-incr->get_height())/2;
            decr->draw(ci,Point2(limit,vofs),Color(1,1,1,tab_display_ofs==0?0.5:1.0));
            incr->draw(ci,Point2(limit+incr->get_width(),vofs),Color(1,1,1,notdone?1.0:0.5));
        }

        if (popup) {
            int from = get_size().width-menu->get_width();

            if (mouse_x_cache > from)
                menu_hl->draw(get_canvas_item(),Size2(from,0));
            else
                menu->draw(get_canvas_item(),Size2(from,0));
        }

        panel->draw(ci, Rect2( 0, top_size.height, size.width, size.height-top_size.height));

    }
    break;
    case NOTIFICATION_THEME_CHANGED: {
        if (get_tab_count() > 0) {
            call_deferred("set_current_tab",get_current_tab()); //wait until all changed theme
        }
    }
    break;
    }
}
Пример #8
0
void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {

	Ref<InputEventMouseButton> mb = p_event;

	if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {

		Point2 pos(mb->get_position().x, mb->get_position().y);
		Size2 size = get_size();

		// Click must be on tabs in the tab header area.
		if (pos.x < tabs_ofs_cache || pos.y > _get_top_margin())
			return;

		// Handle menu button.
		Ref<Texture> menu = get_icon("menu");
		if (popup && pos.x > size.width - menu->get_width()) {
			emit_signal("pre_popup_pressed");

			Vector2 popup_pos = get_global_position();
			popup_pos.x += size.width - popup->get_size().width;
			popup_pos.y += menu->get_height();

			popup->set_global_position(popup_pos);
			popup->popup();
			return;
		}

		Vector<Control *> tabs = _get_tabs();

		// Handle navigation buttons.
		if (buttons_visible_cache) {
			Ref<Texture> increment = get_icon("increment");
			Ref<Texture> decrement = get_icon("decrement");
			if (pos.x > size.width - increment->get_width()) {
				if (last_tab_cache < tabs.size() - 1) {
					first_tab_cache += 1;
					update();
				}
				return;
			} else if (pos.x > size.width - increment->get_width() - decrement->get_width()) {
				if (first_tab_cache > 0) {
					first_tab_cache -= 1;
					update();
				}
				return;
			}
		}

		// Activate the clicked tab.
		pos.x -= tabs_ofs_cache;
		for (int i = first_tab_cache; i <= last_tab_cache; i++) {
			int tab_width = _get_tab_width(i);
			if (pos.x < tab_width) {
				if (!get_tab_disabled(i)) {
					set_current_tab(i);
				}
				break;
			}
			pos.x -= tab_width;
		}
	}
}
Пример #9
0
void TabContainer::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_DRAW: {

			RID canvas = get_canvas_item();
			Size2 size = get_size();

			// Draw only the tab area if the header is hidden.
			Ref<StyleBox> panel = get_stylebox("panel");
			if (!tabs_visible) {
				panel->draw(canvas, Rect2(0, 0, size.width, size.height));
				return;
			}

			Vector<Control *> tabs = _get_tabs();
			Ref<StyleBox> tab_bg = get_stylebox("tab_bg");
			Ref<StyleBox> tab_fg = get_stylebox("tab_fg");
			Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled");
			Ref<Texture> increment = get_icon("increment");
			Ref<Texture> decrement = get_icon("decrement");
			Ref<Texture> menu = get_icon("menu");
			Ref<Texture> menu_hl = get_icon("menu_hl");
			Ref<Font> font = get_font("font");
			Color font_color_fg = get_color("font_color_fg");
			Color font_color_bg = get_color("font_color_bg");
			Color font_color_disabled = get_color("font_color_disabled");
			int side_margin = get_constant("side_margin");
			int icon_text_distance = get_constant("hseparation");

			// Find out start and width of the header area.
			int header_x = side_margin;
			int header_width = size.width - side_margin * 2;
			int header_height = _get_top_margin();
			if (popup)
				header_width -= menu->get_width();

			// Check if all tabs would fit into the header area.
			int all_tabs_width = 0;
			for (int i = 0; i < tabs.size(); i++) {
				int tab_width = _get_tab_width(i);
				all_tabs_width += tab_width;

				if (all_tabs_width > header_width) {
					// Not all tabs are visible at the same time - reserve space for navigation buttons.
					buttons_visible_cache = true;
					header_width -= decrement->get_width() + increment->get_width();
					break;
				} else {
					buttons_visible_cache = false;
				}
			}
			// With buttons, a right side margin does not need to be respected.
			if (popup || buttons_visible_cache) {
				header_width += side_margin;
			}

			// Go through the visible tabs to find the width they occupy.
			all_tabs_width = 0;
			Vector<int> tab_widths;
			for (int i = first_tab_cache; i < tabs.size(); i++) {
				int tab_width = _get_tab_width(i);
				if (all_tabs_width + tab_width > header_width && tab_widths.size() > 0)
					break;
				all_tabs_width += tab_width;
				tab_widths.push_back(tab_width);
			}

			// Find the offset at which to draw tabs, according to the alignment.
			switch (align) {
				case ALIGN_LEFT:
					tabs_ofs_cache = header_x;
					break;
				case ALIGN_CENTER:
					tabs_ofs_cache = header_x + (header_width / 2) - (all_tabs_width / 2);
					break;
				case ALIGN_RIGHT:
					tabs_ofs_cache = header_x + header_width - all_tabs_width;
					break;
			}

			// Draw all visible tabs.
			int x = 0;
			for (int i = 0; i < tab_widths.size(); i++) {
				Ref<StyleBox> tab_style;
				Color font_color;
				if (get_tab_disabled(i + first_tab_cache)) {
					tab_style = tab_disabled;
					font_color = font_color_disabled;
				} else if (i + first_tab_cache == current) {
					tab_style = tab_fg;
					font_color = font_color_fg;
				} else {
					tab_style = tab_bg;
					font_color = font_color_bg;
				}

				// Draw the tab background.
				int tab_width = tab_widths[i];
				Rect2 tab_rect(tabs_ofs_cache + x, 0, tab_width, header_height);
				tab_style->draw(canvas, tab_rect);

				// Draw the tab contents.
				Control *control = tabs[i + first_tab_cache]->cast_to<Control>();
				String text = control->has_meta("_tab_name") ? String(tr(String(control->get_meta("_tab_name")))) : String(control->get_name());

				int x_content = tab_rect.position.x + tab_style->get_margin(MARGIN_LEFT);
				int top_margin = tab_style->get_margin(MARGIN_TOP);
				int y_center = top_margin + (tab_rect.size.y - tab_style->get_minimum_size().y) / 2;

				// Draw the tab icon.
				if (control->has_meta("_tab_icon")) {
					Ref<Texture> icon = control->get_meta("_tab_icon");
					if (icon.is_valid()) {
						int y = y_center - (icon->get_height() / 2);
						icon->draw(canvas, Point2i(x_content, y));
						if (text != "")
							x_content += icon->get_width() + icon_text_distance;
					}
				}

				// Draw the tab text.
				Point2i text_pos(x_content, y_center - (font->get_height() / 2) + font->get_ascent());
				font->draw(canvas, text_pos, text, font_color);

				x += tab_width;
				last_tab_cache = i + first_tab_cache;
			}

			// Draw the popup menu.
			x = get_size().width;
			if (popup) {
				x -= menu->get_width();
				if (mouse_x_cache > x)
					menu_hl->draw(get_canvas_item(), Size2(x, 0));
				else
					menu->draw(get_canvas_item(), Size2(x, 0));
			}

			// Draw the navigation buttons.
			if (buttons_visible_cache) {
				int y_center = header_height / 2;

				x -= increment->get_width();
				increment->draw(canvas,
						Point2(x, y_center - (increment->get_height() / 2)),
						Color(1, 1, 1, last_tab_cache < tabs.size() - 1 ? 1.0 : 0.5));

				x -= decrement->get_width();
				decrement->draw(canvas,
						Point2(x, y_center - (decrement->get_height() / 2)),
						Color(1, 1, 1, first_tab_cache > 0 ? 1.0 : 0.5));
			}

			// Draw the tab area.
			panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height));
		} break;
		case NOTIFICATION_THEME_CHANGED: {
			if (get_tab_count() > 0) {
				call_deferred("set_current_tab", get_current_tab()); //wait until all changed theme
			}
		} break;
	}
}