2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* tabs.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
2017-01-01 22:01:57 +01:00
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
2017-04-08 00:11:42 +02:00
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
2014-02-10 02:10:30 +01:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
# include "tabs.h"
# include "message_queue.h"
Size2 Tabs : : get_minimum_size ( ) const {
Ref < StyleBox > tab_bg = get_stylebox ( " tab_bg " ) ;
Ref < StyleBox > tab_fg = get_stylebox ( " tab_fg " ) ;
2017-02-27 19:07:50 +01:00
Ref < StyleBox > tab_disabled = get_stylebox ( " tab_disabled " ) ;
2014-02-10 02:10:30 +01:00
Ref < Font > font = get_font ( " font " ) ;
2017-03-05 16:44:50 +01:00
Size2 ms ( 0 , MAX ( MAX ( tab_bg - > get_minimum_size ( ) . height , tab_fg - > get_minimum_size ( ) . height ) , tab_disabled - > get_minimum_size ( ) . height ) + font - > get_height ( ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < tabs . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
Ref < Texture > tex = tabs [ i ] . icon ;
if ( tex . is_valid ( ) ) {
2016-05-01 16:27:33 +02:00
ms . height = MAX ( ms . height , tex - > get_size ( ) . height ) ;
2017-03-05 16:44:50 +01:00
if ( tabs [ i ] . text ! = " " )
ms . width + = get_constant ( " hseparation " ) ;
2014-02-10 02:10:30 +01:00
}
2016-05-01 16:27:33 +02:00
2017-03-05 16:44:50 +01:00
ms . width + = font - > get_string_size ( tabs [ i ] . text ) . width ;
2016-05-01 16:27:33 +02:00
2017-02-27 19:07:50 +01:00
if ( tabs [ i ] . disabled )
ms . width + = tab_disabled - > get_minimum_size ( ) . width ;
2017-03-05 16:44:50 +01:00
else if ( current = = i )
ms . width + = tab_fg - > get_minimum_size ( ) . width ;
2014-02-10 02:10:30 +01:00
else
2017-03-05 16:44:50 +01:00
ms . width + = tab_bg - > get_minimum_size ( ) . width ;
2014-02-10 02:10:30 +01:00
2015-07-26 15:44:10 +02:00
if ( tabs [ i ] . right_button . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
Ref < Texture > rb = tabs [ i ] . right_button ;
2016-05-01 16:27:33 +02:00
Size2 bms = rb - > get_size ( ) ;
2017-03-05 16:44:50 +01:00
bms . width + = get_constant ( " hseparation " ) ;
ms . width + = bms . width ;
ms . height = MAX ( bms . height + tab_bg - > get_minimum_size ( ) . height , ms . height ) ;
2015-07-26 15:44:10 +02:00
}
2015-08-18 20:27:01 +02:00
2017-03-05 16:44:50 +01:00
if ( cb_displaypolicy = = CLOSE_BUTTON_SHOW_ALWAYS | | ( cb_displaypolicy = = CLOSE_BUTTON_SHOW_ACTIVE_ONLY & & i = = current ) ) {
Ref < Texture > cb = get_icon ( " close " ) ;
2016-05-01 16:27:33 +02:00
Size2 bms = cb - > get_size ( ) ;
2017-03-05 16:44:50 +01:00
bms . width + = get_constant ( " hseparation " ) ;
ms . width + = bms . width ;
ms . height = MAX ( bms . height + tab_bg - > get_minimum_size ( ) . height , ms . height ) ;
2015-08-18 20:27:01 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
ms . width = 0 ; //TODO: should make this optional
2014-02-10 02:10:30 +01:00
return ms ;
}
2017-05-20 17:38:03 +02:00
void Tabs : : _gui_input ( const Ref < InputEvent > & p_event ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Ref < InputEventMouseMotion > mm = p_event ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( mm . is_valid ( ) ) {
2017-06-03 10:54:24 +02:00
Point2 pos = mm - > get_position ( ) ;
2015-07-26 15:44:10 +02:00
2017-05-02 22:13:12 +02:00
highlight_arrow = - 1 ;
2015-12-14 14:24:28 +01:00
if ( buttons_visible ) {
Ref < Texture > incr = get_icon ( " increment " ) ;
Ref < Texture > decr = get_icon ( " decrement " ) ;
2017-03-05 16:44:50 +01:00
int limit = get_size ( ) . width - incr - > get_width ( ) - decr - > get_width ( ) ;
2015-12-14 14:24:28 +01:00
2017-03-05 16:44:50 +01:00
if ( pos . x > limit + decr - > get_width ( ) ) {
2017-05-02 22:13:12 +02:00
highlight_arrow = 1 ;
2017-03-05 16:44:50 +01:00
} else if ( pos . x > limit ) {
2017-05-02 22:13:12 +02:00
highlight_arrow = 0 ;
2015-12-14 14:24:28 +01:00
}
}
2016-05-01 16:27:33 +02:00
// test hovering to display right or close button
2017-06-15 17:30:03 +02:00
int hover_now = - 1 ;
2017-03-05 16:44:50 +01:00
int hover_buttons = - 1 ;
for ( int i = 0 ; i < tabs . size ( ) ; i + + ) {
2015-07-26 15:44:10 +02:00
2017-03-05 16:44:50 +01:00
if ( i < offset )
2016-05-01 16:27:33 +02:00
continue ;
2015-08-18 20:27:01 +02:00
2017-06-15 17:30:03 +02:00
Rect2 rect = get_tab_rect ( i ) ;
if ( rect . has_point ( pos ) ) {
hover_now = i ;
}
2015-07-26 15:44:10 +02:00
if ( tabs [ i ] . rb_rect . has_point ( pos ) ) {
2017-03-05 16:44:50 +01:00
rb_hover = i ;
cb_hover = - 1 ;
2015-08-18 20:27:01 +02:00
hover_buttons = i ;
2015-07-26 15:44:10 +02:00
break ;
2017-03-05 16:44:50 +01:00
} else if ( ! tabs [ i ] . disabled & & tabs [ i ] . cb_rect . has_point ( pos ) ) {
cb_hover = i ;
rb_hover = - 1 ;
2015-08-18 20:27:01 +02:00
hover_buttons = i ;
break ;
}
2015-07-26 15:44:10 +02:00
}
2017-06-15 17:30:03 +02:00
if ( hover ! = hover_now ) {
hover = hover_now ;
emit_signal ( " tab_hover " , hover ) ;
}
2015-07-26 15:44:10 +02:00
2016-05-01 16:27:33 +02:00
if ( hover_buttons = = - 1 ) { // no hover
2017-03-05 16:44:50 +01:00
rb_hover = hover_buttons ;
cb_hover = hover_buttons ;
2015-07-26 15:44:10 +02:00
}
2015-08-18 20:27:01 +02:00
update ( ) ;
2015-07-26 15:44:10 +02:00
return ;
}
2017-05-20 17:38:03 +02:00
Ref < InputEventMouseButton > mb = p_event ;
if ( rb_pressing & & mb . is_valid ( ) & &
! mb - > is_pressed ( ) & &
mb - > get_button_index ( ) = = BUTTON_LEFT ) {
2015-08-18 20:27:01 +02:00
2017-03-05 16:44:50 +01:00
if ( rb_hover ! = - 1 ) {
2015-07-26 15:44:10 +02:00
//pressed
2017-03-05 16:44:50 +01:00
emit_signal ( " right_button_pressed " , rb_hover ) ;
2015-07-26 15:44:10 +02:00
}
2017-03-05 16:44:50 +01:00
rb_pressing = false ;
2015-07-26 15:44:10 +02:00
update ( ) ;
}
2017-05-20 17:38:03 +02:00
if ( cb_pressing & & mb . is_valid ( ) & &
! mb - > is_pressed ( ) & &
mb - > get_button_index ( ) = = BUTTON_LEFT ) {
2016-05-01 16:27:33 +02:00
2017-03-05 16:44:50 +01:00
if ( cb_hover ! = - 1 ) {
2015-08-18 20:27:01 +02:00
//pressed
2017-03-05 16:44:50 +01:00
emit_signal ( " tab_close " , cb_hover ) ;
2015-08-18 20:27:01 +02:00
}
2017-03-05 16:44:50 +01:00
cb_pressing = false ;
2015-08-18 20:27:01 +02:00
update ( ) ;
}
2017-05-20 17:38:03 +02:00
if ( mb . is_valid ( ) & &
mb - > is_pressed ( ) & &
mb - > get_button_index ( ) = = BUTTON_LEFT ) {
2014-02-10 02:10:30 +01:00
// clicks
2017-06-03 10:54:24 +02:00
Point2 pos ( mb - > get_position ( ) . x , mb - > get_position ( ) . y ) ;
2014-02-10 02:10:30 +01:00
2015-12-14 14:24:28 +01:00
if ( buttons_visible ) {
Ref < Texture > incr = get_icon ( " increment " ) ;
Ref < Texture > decr = get_icon ( " decrement " ) ;
2017-03-05 16:44:50 +01:00
int limit = get_size ( ) . width - incr - > get_width ( ) - decr - > get_width ( ) ;
2015-12-14 14:24:28 +01:00
2017-03-05 16:44:50 +01:00
if ( pos . x > limit + decr - > get_width ( ) ) {
2015-12-14 14:24:28 +01:00
if ( missing_right ) {
offset + + ;
update ( ) ;
}
return ;
2017-03-05 16:44:50 +01:00
} else if ( pos . x > limit ) {
if ( offset > 0 ) {
2015-12-14 14:24:28 +01:00
offset - - ;
update ( ) ;
}
return ;
}
}
2017-03-05 16:44:50 +01:00
int found = - 1 ;
for ( int i = 0 ; i < tabs . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( i < offset )
2015-12-14 14:24:28 +01:00
continue ;
2016-05-01 16:27:33 +02:00
2015-07-26 15:44:10 +02:00
if ( tabs [ i ] . rb_rect . has_point ( pos ) ) {
2017-03-05 16:44:50 +01:00
rb_pressing = true ;
2015-07-26 15:44:10 +02:00
update ( ) ;
return ;
}
2015-08-18 20:27:01 +02:00
if ( tabs [ i ] . cb_rect . has_point ( pos ) ) {
2017-03-05 16:44:50 +01:00
cb_pressing = true ;
2015-08-18 20:27:01 +02:00
update ( ) ;
return ;
}
2017-03-05 16:44:50 +01:00
if ( pos . x > = tabs [ i ] . ofs_cache & & pos . x < tabs [ i ] . ofs_cache + tabs [ i ] . size_cache ) {
2017-02-27 19:07:50 +01:00
if ( ! tabs [ i ] . disabled ) {
found = i ;
}
2014-02-10 02:10:30 +01:00
break ;
}
}
2017-03-05 16:44:50 +01:00
if ( found ! = - 1 ) {
2014-02-10 02:10:30 +01:00
set_current_tab ( found ) ;
2017-03-05 16:44:50 +01:00
emit_signal ( " tab_changed " , found ) ;
2014-02-10 02:10:30 +01:00
}
}
}
2016-05-01 16:27:33 +02:00
void Tabs : : _notification ( int p_what ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
switch ( p_what ) {
2014-02-10 02:10:30 +01:00
2015-07-26 15:44:10 +02:00
case NOTIFICATION_MOUSE_EXIT : {
2017-03-05 16:44:50 +01:00
rb_hover = - 1 ;
cb_hover = - 1 ;
hover = - 1 ;
2015-07-26 15:44:10 +02:00
update ( ) ;
} break ;
2016-01-23 00:19:57 +01:00
case NOTIFICATION_RESIZED : {
2017-06-15 17:30:03 +02:00
_update_cache ( ) ;
2016-01-23 00:19:57 +01:00
_ensure_no_over_offset ( ) ;
2017-06-15 17:30:03 +02:00
ensure_tab_visible ( current ) ;
2016-01-23 00:19:57 +01:00
} break ;
2014-02-10 02:10:30 +01:00
case NOTIFICATION_DRAW : {
2017-06-15 17:30:03 +02:00
_update_cache ( ) ;
2014-02-10 02:10:30 +01:00
RID ci = get_canvas_item ( ) ;
Ref < StyleBox > tab_bg = get_stylebox ( " tab_bg " ) ;
Ref < StyleBox > tab_fg = get_stylebox ( " tab_fg " ) ;
2017-02-27 19:07:50 +01:00
Ref < StyleBox > tab_disabled = get_stylebox ( " tab_disabled " ) ;
2014-02-10 02:10:30 +01:00
Ref < Font > font = get_font ( " font " ) ;
Color color_fg = get_color ( " font_color_fg " ) ;
Color color_bg = get_color ( " font_color_bg " ) ;
2017-02-27 19:07:50 +01:00
Color color_disabled = get_color ( " font_color_disabled " ) ;
2017-03-05 16:44:50 +01:00
Ref < Texture > close = get_icon ( " close " ) ;
2014-02-10 02:10:30 +01:00
int h = get_size ( ) . height ;
2016-05-01 16:27:33 +02:00
int w = 0 ;
2015-12-14 14:24:28 +01:00
int mw = 0 ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < tabs . size ( ) ; i + + ) {
2015-12-14 14:24:28 +01:00
2016-05-01 16:27:33 +02:00
tabs [ i ] . ofs_cache = mw ;
mw + = get_tab_width ( i ) ;
2015-12-14 14:24:28 +01:00
}
2017-03-05 16:44:50 +01:00
if ( tab_align = = ALIGN_CENTER ) {
w = ( get_size ( ) . width - mw ) / 2 ;
} else if ( tab_align = = ALIGN_RIGHT ) {
w = get_size ( ) . width - mw ;
2015-06-22 05:03:19 +02:00
}
2017-03-05 16:44:50 +01:00
if ( w < 0 ) {
w = 0 ;
2015-06-22 05:03:19 +02:00
}
2015-12-14 14:24:28 +01:00
Ref < Texture > incr = get_icon ( " increment " ) ;
Ref < Texture > decr = get_icon ( " decrement " ) ;
2017-05-02 22:13:12 +02:00
Ref < Texture > incr_hl = get_icon ( " increment_highlight " ) ;
Ref < Texture > decr_hl = get_icon ( " decrement_highlight " ) ;
2015-12-14 14:24:28 +01:00
2017-03-05 16:44:50 +01:00
int limit = get_size ( ) . width - incr - > get_size ( ) . width - decr - > get_size ( ) . width ;
2015-12-14 14:24:28 +01:00
2017-03-05 16:44:50 +01:00
missing_right = false ;
2015-12-14 14:24:28 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < tabs . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( i < offset )
2015-12-14 14:24:28 +01:00
continue ;
2016-05-01 16:27:33 +02:00
2017-03-05 16:44:50 +01:00
tabs [ i ] . ofs_cache = w ;
2014-02-10 02:10:30 +01:00
2017-06-15 17:30:03 +02:00
int lsize = tabs [ i ] . size_cache ;
2015-12-14 14:24:28 +01:00
2014-02-10 02:10:30 +01:00
Ref < StyleBox > sb ;
Color col ;
2017-02-27 19:07:50 +01:00
if ( tabs [ i ] . disabled ) {
sb = tab_disabled ;
col = color_disabled ;
} else if ( i = = current ) {
2017-03-05 16:44:50 +01:00
sb = tab_fg ;
col = color_fg ;
2014-02-10 02:10:30 +01:00
} else {
2017-03-05 16:44:50 +01:00
sb = tab_bg ;
col = color_bg ;
2014-02-10 02:10:30 +01:00
}
2017-06-15 17:30:03 +02:00
if ( w + lsize > limit ) {
max_drawn_tab = i - 1 ;
missing_right = true ;
break ;
} else {
max_drawn_tab = i ;
}
Rect2 sb_rect = Rect2 ( w , 0 , tabs [ i ] . size_cache , h ) ;
2016-05-01 15:27:58 +02:00
sb - > draw ( ci , sb_rect ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
w + = sb - > get_margin ( MARGIN_LEFT ) ;
2014-02-10 02:10:30 +01:00
2016-05-01 15:27:58 +02:00
Size2i sb_ms = sb - > get_minimum_size ( ) ;
Ref < Texture > icon = tabs [ i ] . icon ;
2014-02-10 02:10:30 +01:00
if ( icon . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
icon - > draw ( ci , Point2i ( w , sb - > get_margin ( MARGIN_TOP ) + ( ( sb_rect . size . y - sb_ms . y ) - icon - > get_height ( ) ) / 2 ) ) ;
2017-06-15 17:30:03 +02:00
if ( tabs [ i ] . text ! = " " )
2017-03-05 16:44:50 +01:00
w + = icon - > get_width ( ) + get_constant ( " hseparation " ) ;
2014-02-10 02:10:30 +01:00
}
2017-06-15 17:30:03 +02:00
font - > draw ( ci , Point2i ( w , sb - > get_margin ( MARGIN_TOP ) + ( ( sb_rect . size . y - sb_ms . y ) - font - > get_height ( ) ) / 2 + font - > get_ascent ( ) ) , tabs [ i ] . text , col , tabs [ i ] . size_text ) ;
2014-02-10 02:10:30 +01:00
2017-06-15 17:30:03 +02:00
w + = tabs [ i ] . size_text ;
2015-07-26 15:44:10 +02:00
if ( tabs [ i ] . right_button . is_valid ( ) ) {
2016-05-01 16:27:33 +02:00
2015-07-26 15:44:10 +02:00
Ref < StyleBox > style = get_stylebox ( " button " ) ;
2017-03-05 16:44:50 +01:00
Ref < Texture > rb = tabs [ i ] . right_button ;
2015-07-26 15:44:10 +02:00
2017-03-05 16:44:50 +01:00
w + = get_constant ( " hseparation " ) ;
2015-07-26 15:44:10 +02:00
Rect2 rb_rect ;
2017-03-05 16:44:50 +01:00
rb_rect . size = style - > get_minimum_size ( ) + rb - > get_size ( ) ;
2017-06-04 00:25:13 +02:00
rb_rect . position . x = w ;
rb_rect . position . y = sb - > get_margin ( MARGIN_TOP ) + ( ( sb_rect . size . y - sb_ms . y ) - ( rb_rect . size . y ) ) / 2 ;
2015-07-26 15:44:10 +02:00
2017-03-05 16:44:50 +01:00
if ( rb_hover = = i ) {
2015-07-26 15:44:10 +02:00
if ( rb_pressing )
2017-03-05 16:44:50 +01:00
get_stylebox ( " button_pressed " ) - > draw ( ci , rb_rect ) ;
2015-07-26 15:44:10 +02:00
else
2017-03-05 16:44:50 +01:00
style - > draw ( ci , rb_rect ) ;
2015-07-26 15:44:10 +02:00
}
2017-06-04 00:25:13 +02:00
rb - > draw ( ci , Point2i ( w + style - > get_margin ( MARGIN_LEFT ) , rb_rect . position . y + style - > get_margin ( MARGIN_TOP ) ) ) ;
2017-03-05 16:44:50 +01:00
w + = rb - > get_width ( ) ;
tabs [ i ] . rb_rect = rb_rect ;
2015-07-26 15:44:10 +02:00
}
2017-03-05 16:44:50 +01:00
if ( cb_displaypolicy = = CLOSE_BUTTON_SHOW_ALWAYS | | ( cb_displaypolicy = = CLOSE_BUTTON_SHOW_ACTIVE_ONLY & & i = = current ) ) {
2015-08-18 20:27:01 +02:00
2016-01-13 11:39:31 +01:00
Ref < StyleBox > style = get_stylebox ( " button " ) ;
2017-03-05 16:44:50 +01:00
Ref < Texture > cb = close ;
2015-08-18 20:27:01 +02:00
2017-03-05 16:44:50 +01:00
w + = get_constant ( " hseparation " ) ;
2015-08-18 20:27:01 +02:00
2016-01-13 11:39:31 +01:00
Rect2 cb_rect ;
2017-03-05 16:44:50 +01:00
cb_rect . size = style - > get_minimum_size ( ) + cb - > get_size ( ) ;
2017-06-04 00:25:13 +02:00
cb_rect . position . x = w ;
cb_rect . position . y = sb - > get_margin ( MARGIN_TOP ) + ( ( sb_rect . size . y - sb_ms . y ) - ( cb_rect . size . y ) ) / 2 ;
2015-08-18 20:27:01 +02:00
2017-02-27 19:07:50 +01:00
if ( ! tabs [ i ] . disabled & & cb_hover = = i ) {
2016-01-13 11:39:31 +01:00
if ( cb_pressing )
2017-03-05 16:44:50 +01:00
get_stylebox ( " button_pressed " ) - > draw ( ci , cb_rect ) ;
2016-01-13 11:39:31 +01:00
else
2017-03-05 16:44:50 +01:00
style - > draw ( ci , cb_rect ) ;
2015-08-18 20:27:01 +02:00
}
2017-06-04 00:25:13 +02:00
cb - > draw ( ci , Point2i ( w + style - > get_margin ( MARGIN_LEFT ) , cb_rect . position . y + style - > get_margin ( MARGIN_TOP ) ) ) ;
2017-03-05 16:44:50 +01:00
w + = cb - > get_width ( ) ;
tabs [ i ] . cb_rect = cb_rect ;
2015-08-18 20:27:01 +02:00
}
2017-03-05 16:44:50 +01:00
w + = sb - > get_margin ( MARGIN_RIGHT ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( offset > 0 | | missing_right ) {
2015-12-14 14:24:28 +01:00
2017-03-05 16:44:50 +01:00
int vofs = ( get_size ( ) . height - incr - > get_size ( ) . height ) / 2 ;
2015-12-14 14:24:28 +01:00
2017-03-05 16:44:50 +01:00
if ( offset > 0 )
2017-05-02 22:13:12 +02:00
draw_texture ( highlight_arrow = = 0 ? decr_hl : decr , Point2 ( limit , vofs ) ) ;
2015-12-14 14:24:28 +01:00
else
2017-03-05 16:44:50 +01:00
draw_texture ( decr , Point2 ( limit , vofs ) , Color ( 1 , 1 , 1 , 0.5 ) ) ;
2015-12-14 14:24:28 +01:00
if ( missing_right )
2017-05-02 22:13:12 +02:00
draw_texture ( highlight_arrow = = 1 ? incr_hl : incr , Point2 ( limit + decr - > get_size ( ) . width , vofs ) ) ;
2015-12-14 14:24:28 +01:00
else
2017-03-05 16:44:50 +01:00
draw_texture ( incr , Point2 ( limit + decr - > get_size ( ) . width , vofs ) , Color ( 1 , 1 , 1 , 0.5 ) ) ;
2015-12-14 14:24:28 +01:00
2017-03-05 16:44:50 +01:00
buttons_visible = true ;
2015-12-14 14:24:28 +01:00
} else {
2017-03-05 16:44:50 +01:00
buttons_visible = false ;
2015-12-14 14:24:28 +01:00
}
2014-02-10 02:10:30 +01:00
} break ;
}
}
int Tabs : : get_tab_count ( ) const {
return tabs . size ( ) ;
}
void Tabs : : set_current_tab ( int p_current ) {
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX ( p_current , get_tab_count ( ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
current = p_current ;
2014-02-10 02:10:30 +01:00
_change_notify ( " current_tab " ) ;
2017-06-15 17:30:03 +02:00
_update_cache ( ) ;
2014-02-10 02:10:30 +01:00
update ( ) ;
}
int Tabs : : get_current_tab ( ) const {
return current ;
}
2017-06-15 17:30:03 +02:00
int Tabs : : get_hovered_tab ( ) const {
return hover ;
}
2017-03-05 16:44:50 +01:00
void Tabs : : set_tab_title ( int p_tab , const String & p_title ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX ( p_tab , tabs . size ( ) ) ;
tabs [ p_tab ] . text = p_title ;
2014-02-10 02:10:30 +01:00
update ( ) ;
minimum_size_changed ( ) ;
}
2017-03-05 16:44:50 +01:00
String Tabs : : get_tab_title ( int p_tab ) const {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX_V ( p_tab , tabs . size ( ) , " " ) ;
2014-02-10 02:10:30 +01:00
return tabs [ p_tab ] . text ;
}
2017-03-05 16:44:50 +01:00
void Tabs : : set_tab_icon ( int p_tab , const Ref < Texture > & p_icon ) {
2016-05-01 16:27:33 +02:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX ( p_tab , tabs . size ( ) ) ;
tabs [ p_tab ] . icon = p_icon ;
2014-02-10 02:10:30 +01:00
update ( ) ;
minimum_size_changed ( ) ;
}
2016-05-01 16:27:33 +02:00
2017-03-05 16:44:50 +01:00
Ref < Texture > Tabs : : get_tab_icon ( int p_tab ) const {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX_V ( p_tab , tabs . size ( ) , Ref < Texture > ( ) ) ;
2014-02-10 02:10:30 +01:00
return tabs [ p_tab ] . icon ;
}
2017-02-27 19:07:50 +01:00
void Tabs : : set_tab_disabled ( int p_tab , bool p_disabled ) {
2017-03-05 16:44:50 +01:00
2017-02-27 19:07:50 +01:00
ERR_FAIL_INDEX ( p_tab , tabs . size ( ) ) ;
tabs [ p_tab ] . disabled = p_disabled ;
update ( ) ;
}
bool Tabs : : get_tab_disabled ( int p_tab ) const {
2017-03-05 16:44:50 +01:00
2017-02-27 19:07:50 +01:00
ERR_FAIL_INDEX_V ( p_tab , tabs . size ( ) , false ) ;
return tabs [ p_tab ] . disabled ;
}
2017-03-05 16:44:50 +01:00
void Tabs : : set_tab_right_button ( int p_tab , const Ref < Texture > & p_right_button ) {
2015-07-26 15:44:10 +02:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX ( p_tab , tabs . size ( ) ) ;
tabs [ p_tab ] . right_button = p_right_button ;
2015-07-26 15:44:10 +02:00
update ( ) ;
minimum_size_changed ( ) ;
}
2017-03-05 16:44:50 +01:00
Ref < Texture > Tabs : : get_tab_right_button ( int p_tab ) const {
2015-07-26 15:44:10 +02:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX_V ( p_tab , tabs . size ( ) , Ref < Texture > ( ) ) ;
2015-07-26 15:44:10 +02:00
return tabs [ p_tab ] . right_button ;
}
2017-06-15 17:30:03 +02:00
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 ;
}
}
2017-03-05 16:44:50 +01:00
void Tabs : : add_tab ( const String & p_str , const Ref < Texture > & p_icon ) {
2014-02-10 02:10:30 +01:00
Tab t ;
2017-03-05 16:44:50 +01:00
t . text = p_str ;
t . icon = p_icon ;
2017-02-27 19:07:50 +01:00
t . disabled = false ;
2017-06-15 17:30:03 +02:00
t . ofs_cache = 0 ;
t . size_cache = 0 ;
2015-08-18 20:27:01 +02:00
2014-02-10 02:10:30 +01:00
tabs . push_back ( t ) ;
2017-06-15 17:30:03 +02:00
_update_cache ( ) ;
2014-02-10 02:10:30 +01:00
update ( ) ;
minimum_size_changed ( ) ;
}
2015-06-22 05:03:19 +02:00
void Tabs : : clear_tabs ( ) {
tabs . clear ( ) ;
2017-03-05 16:44:50 +01:00
current = 0 ;
2015-06-22 05:03:19 +02:00
update ( ) ;
}
2014-02-10 02:10:30 +01:00
void Tabs : : remove_tab ( int p_idx ) {
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX ( p_idx , tabs . size ( ) ) ;
2014-02-10 02:10:30 +01:00
tabs . remove ( p_idx ) ;
2017-03-05 16:44:50 +01:00
if ( current > = p_idx )
2014-02-10 02:10:30 +01:00
current - - ;
2017-06-15 17:30:03 +02:00
_update_cache ( ) ;
2014-02-10 02:10:30 +01:00
update ( ) ;
minimum_size_changed ( ) ;
2017-03-05 16:44:50 +01:00
if ( current < 0 )
current = 0 ;
if ( current > = tabs . size ( ) )
current = tabs . size ( ) - 1 ;
2014-02-10 02:10:30 +01:00
2016-01-23 00:19:57 +01:00
_ensure_no_over_offset ( ) ;
2015-06-22 05:03:19 +02:00
}
2017-07-05 15:44:53 +02:00
Variant Tabs : : get_drag_data ( const Point2 & p_point ) {
return get_tab_idx_at_point ( p_point ) ;
}
bool Tabs : : can_drop_data ( const Point2 & p_point , const Variant & p_data ) const {
return get_tab_idx_at_point ( p_point ) > - 1 ;
}
void Tabs : : drop_data ( const Point2 & p_point , const Variant & p_data ) {
int hover_now = get_tab_idx_at_point ( p_point ) ;
ERR_FAIL_INDEX ( hover_now , tabs . size ( ) ) ;
emit_signal ( " reposition_active_tab_request " , hover_now ) ;
}
int Tabs : : get_tab_idx_at_point ( const Point2 & p_point ) const {
int hover_now = - 1 ;
for ( int i = 0 ; i < tabs . size ( ) ; i + + ) {
if ( i < offset )
continue ;
Rect2 rect = get_tab_rect ( i ) ;
if ( rect . has_point ( p_point ) ) {
hover_now = i ;
}
}
return hover_now ;
}
2015-06-22 05:03:19 +02:00
void Tabs : : set_tab_align ( TabAlign p_align ) {
2017-07-22 18:15:31 +02:00
ERR_FAIL_INDEX ( p_align , ALIGN_MAX ) ;
2017-03-05 16:44:50 +01:00
tab_align = p_align ;
2015-06-22 05:03:19 +02:00
update ( ) ;
}
Tabs : : TabAlign Tabs : : get_tab_align ( ) const {
2014-02-10 02:10:30 +01:00
2015-06-22 05:03:19 +02:00
return tab_align ;
2014-02-10 02:10:30 +01:00
}
2017-07-12 16:48:43 +02:00
void Tabs : : move_tab ( int from , int to ) {
if ( from = = to )
return ;
ERR_FAIL_INDEX ( from , tabs . size ( ) ) ;
ERR_FAIL_INDEX ( to , tabs . size ( ) ) ;
Tab tab_from = tabs [ from ] ;
tabs . remove ( from ) ;
tabs . insert ( to , tab_from ) ;
_update_cache ( ) ;
update ( ) ;
}
2016-01-13 11:39:31 +01:00
int Tabs : : get_tab_width ( int p_idx ) const {
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX_V ( p_idx , tabs . size ( ) , 0 ) ;
2016-01-13 11:39:31 +01:00
Ref < StyleBox > tab_bg = get_stylebox ( " tab_bg " ) ;
Ref < StyleBox > tab_fg = get_stylebox ( " tab_fg " ) ;
2017-02-27 19:07:50 +01:00
Ref < StyleBox > tab_disabled = get_stylebox ( " tab_disabled " ) ;
2016-01-13 11:39:31 +01:00
Ref < Font > font = get_font ( " font " ) ;
2016-05-01 16:27:33 +02:00
2017-03-05 16:44:50 +01:00
int x = 0 ;
2016-01-13 11:39:31 +01:00
Ref < Texture > tex = tabs [ p_idx ] . icon ;
if ( tex . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
x + = tex - > get_width ( ) ;
if ( tabs [ p_idx ] . text ! = " " )
x + = get_constant ( " hseparation " ) ;
2016-01-13 11:39:31 +01:00
}
2017-03-05 16:44:50 +01:00
x + = font - > get_string_size ( tabs [ p_idx ] . text ) . width ;
2016-05-01 16:27:33 +02:00
2017-02-27 19:07:50 +01:00
if ( tabs [ p_idx ] . disabled )
x + = tab_disabled - > get_minimum_size ( ) . width ;
2017-03-05 16:44:50 +01:00
else if ( current = = p_idx )
x + = tab_fg - > get_minimum_size ( ) . width ;
2016-01-13 11:39:31 +01:00
else
2017-03-05 16:44:50 +01:00
x + = tab_bg - > get_minimum_size ( ) . width ;
2016-01-13 11:39:31 +01:00
if ( tabs [ p_idx ] . right_button . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
Ref < Texture > rb = tabs [ p_idx ] . right_button ;
x + = rb - > get_width ( ) ;
x + = get_constant ( " hseparation " ) ;
2016-01-13 11:39:31 +01:00
}
2017-03-05 16:44:50 +01:00
if ( cb_displaypolicy = = CLOSE_BUTTON_SHOW_ALWAYS | | ( cb_displaypolicy = = CLOSE_BUTTON_SHOW_ACTIVE_ONLY & & p_idx = = current ) ) {
Ref < Texture > cb = get_icon ( " close " ) ;
x + = cb - > get_width ( ) ;
x + = get_constant ( " hseparation " ) ;
2016-01-13 11:39:31 +01:00
}
return x ;
}
2014-02-10 02:10:30 +01:00
2016-01-23 00:19:57 +01:00
void Tabs : : _ensure_no_over_offset ( ) {
if ( ! is_inside_tree ( ) )
return ;
Ref < Texture > incr = get_icon ( " increment " ) ;
Ref < Texture > decr = get_icon ( " decrement " ) ;
2017-03-05 16:44:50 +01:00
int limit = get_size ( ) . width - incr - > get_width ( ) - decr - > get_width ( ) ;
2016-01-23 00:19:57 +01:00
2017-03-05 16:44:50 +01:00
while ( offset > 0 ) {
2016-01-23 00:19:57 +01:00
2017-03-05 16:44:50 +01:00
int total_w = 0 ;
for ( int i = 0 ; i < tabs . size ( ) ; i + + ) {
2016-01-23 00:19:57 +01:00
2017-03-05 16:44:50 +01:00
if ( i < offset - 1 )
2016-01-23 00:19:57 +01:00
continue ;
2017-06-15 17:30:03 +02:00
total_w + = tabs [ i ] . size_cache ;
2016-01-23 00:19:57 +01:00
}
if ( total_w < limit ) {
offset - - ;
update ( ) ;
} else {
break ;
}
}
}
2016-01-11 01:45:11 +01:00
void Tabs : : ensure_tab_visible ( int p_idx ) {
if ( ! is_inside_tree ( ) )
return ;
2017-06-15 17:30:03 +02:00
if ( tabs . size ( ) = = 0 ) return ;
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX ( p_idx , tabs . size ( ) ) ;
2016-01-11 01:45:11 +01:00
2017-06-15 17:30:03 +02:00
if ( p_idx = = offset ) {
return ;
}
if ( p_idx < offset ) {
2017-03-05 16:44:50 +01:00
offset = p_idx ;
2016-01-11 01:45:11 +01:00
update ( ) ;
return ;
}
2017-06-15 17:30:03 +02:00
int prev_offset = offset ;
2016-01-11 01:45:11 +01:00
Ref < Texture > incr = get_icon ( " increment " ) ;
Ref < Texture > decr = get_icon ( " decrement " ) ;
2017-03-05 16:44:50 +01:00
int limit = get_size ( ) . width - incr - > get_width ( ) - decr - > get_width ( ) ;
2017-06-15 17:30:03 +02:00
for ( int i = offset ; i < = p_idx ; i + + ) {
if ( tabs [ i ] . ofs_cache + tabs [ i ] . size_cache > limit ) {
offset + + ;
}
2016-01-11 01:45:11 +01:00
}
2017-06-15 17:30:03 +02:00
if ( prev_offset ! = offset ) {
update ( ) ;
2016-01-11 01:45:11 +01:00
}
2017-06-15 17:30:03 +02:00
}
2016-01-11 01:45:11 +01:00
2017-07-05 15:44:53 +02:00
Rect2 Tabs : : get_tab_rect ( int p_tab ) const {
2017-06-15 17:30:03 +02:00
return Rect2 ( tabs [ p_tab ] . ofs_cache , 0 , tabs [ p_tab ] . size_cache , get_size ( ) . height ) ;
2016-01-11 01:45:11 +01:00
}
2016-01-13 11:39:31 +01:00
void Tabs : : set_tab_close_display_policy ( CloseButtonDisplayPolicy p_policy ) {
2017-07-22 18:15:31 +02:00
ERR_FAIL_INDEX ( p_policy , CLOSE_BUTTON_MAX ) ;
2017-03-05 16:44:50 +01:00
cb_displaypolicy = p_policy ;
2016-01-13 11:39:31 +01:00
update ( ) ;
}
2017-07-22 18:15:31 +02:00
Tabs : : CloseButtonDisplayPolicy Tabs : : get_tab_close_display_policy ( ) const {
return cb_displaypolicy ;
}
2017-06-15 17:30:03 +02:00
void Tabs : : set_min_width ( int p_width ) {
min_width = p_width ;
}
2014-02-10 02:10:30 +01:00
void Tabs : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " _gui_input " ) , & Tabs : : _gui_input ) ;
ClassDB : : bind_method ( D_METHOD ( " get_tab_count " ) , & Tabs : : get_tab_count ) ;
ClassDB : : bind_method ( D_METHOD ( " set_current_tab " , " tab_idx " ) , & Tabs : : set_current_tab ) ;
ClassDB : : bind_method ( D_METHOD ( " get_current_tab " ) , & Tabs : : get_current_tab ) ;
ClassDB : : bind_method ( D_METHOD ( " set_tab_title " , " tab_idx " , " title " ) , & Tabs : : set_tab_title ) ;
ClassDB : : bind_method ( D_METHOD ( " get_tab_title " , " tab_idx " ) , & Tabs : : get_tab_title ) ;
ClassDB : : bind_method ( D_METHOD ( " set_tab_icon " , " tab_idx " , " icon:Texture " ) , & Tabs : : set_tab_icon ) ;
ClassDB : : bind_method ( D_METHOD ( " get_tab_icon:Texture " , " tab_idx " ) , & Tabs : : get_tab_icon ) ;
2017-02-27 19:07:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_tab_disabled " , " tab_idx " , " disabled " ) , & Tabs : : set_tab_disabled ) ;
ClassDB : : bind_method ( D_METHOD ( " get_tab_disabled " , " tab_idx " ) , & Tabs : : get_tab_disabled ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " remove_tab " , " tab_idx " ) , & Tabs : : remove_tab ) ;
2017-07-28 03:27:46 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_tab " , " title " , " icon:Texture " ) , & Tabs : : add_tab , DEFVAL ( " " ) , DEFVAL ( Ref < Texture > ( ) ) ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_tab_align " , " align " ) , & Tabs : : set_tab_align ) ;
ClassDB : : bind_method ( D_METHOD ( " get_tab_align " ) , & Tabs : : get_tab_align ) ;
ClassDB : : bind_method ( D_METHOD ( " ensure_tab_visible " , " idx " ) , & Tabs : : ensure_tab_visible ) ;
2017-07-12 16:48:43 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_tab_rect " , " tab_idx " ) , & Tabs : : get_tab_rect ) ;
ClassDB : : bind_method ( D_METHOD ( " move_tab " , " from " , " to " ) , & Tabs : : move_tab ) ;
2017-07-22 18:15:31 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_tab_close_display_policy " , " policy " ) , & Tabs : : set_tab_close_display_policy ) ;
ClassDB : : bind_method ( D_METHOD ( " get_tab_close_display_policy " ) , & Tabs : : get_tab_close_display_policy ) ;
2015-08-18 20:27:01 +02:00
2017-03-05 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " tab_changed " , PropertyInfo ( Variant : : INT , " tab " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " right_button_pressed " , PropertyInfo ( Variant : : INT , " tab " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " tab_close " , PropertyInfo ( Variant : : INT , " tab " ) ) ) ;
2017-06-15 17:30:03 +02:00
ADD_SIGNAL ( MethodInfo ( " tab_hover " , PropertyInfo ( Variant : : INT , " tab " ) ) ) ;
2017-07-05 15:44:53 +02:00
ADD_SIGNAL ( MethodInfo ( " reposition_active_tab_request " , PropertyInfo ( Variant : : INT , " idx_to " ) ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " current_tab " , PROPERTY_HINT_RANGE , " -1,4096,1 " , PROPERTY_USAGE_EDITOR ) , " set_current_tab " , " get_current_tab " ) ;
2017-07-22 18:15:31 +02:00
ADD_PROPERTYNZ ( PropertyInfo ( Variant : : INT , " tab_close_display_policy " , PROPERTY_HINT_ENUM , " Show Never,Show Active Only,Show Always " ) , " set_tab_close_display_policy " , " get_tab_close_display_policy " ) ;
2015-08-18 20:27:01 +02:00
2017-03-05 16:44:50 +01:00
BIND_CONSTANT ( ALIGN_LEFT ) ;
BIND_CONSTANT ( ALIGN_CENTER ) ;
BIND_CONSTANT ( ALIGN_RIGHT ) ;
2017-07-22 18:15:31 +02:00
BIND_CONSTANT ( ALIGN_MAX ) ;
2016-01-13 11:39:31 +01:00
2017-03-05 16:44:50 +01:00
BIND_CONSTANT ( CLOSE_BUTTON_SHOW_ACTIVE_ONLY ) ;
BIND_CONSTANT ( CLOSE_BUTTON_SHOW_ALWAYS ) ;
BIND_CONSTANT ( CLOSE_BUTTON_SHOW_NEVER ) ;
2017-07-22 18:15:31 +02:00
BIND_CONSTANT ( CLOSE_BUTTON_MAX ) ;
2014-02-10 02:10:30 +01:00
}
Tabs : : Tabs ( ) {
2017-03-05 16:44:50 +01:00
current = 0 ;
tab_align = ALIGN_CENTER ;
rb_hover = - 1 ;
rb_pressing = false ;
2017-05-02 22:13:12 +02:00
highlight_arrow = - 1 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
cb_hover = - 1 ;
cb_pressing = false ;
2016-05-01 16:27:33 +02:00
cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER ;
2017-03-05 16:44:50 +01:00
offset = 0 ;
max_drawn_tab = 0 ;
2017-06-15 17:30:03 +02:00
min_width = 0 ;
2014-02-10 02:10:30 +01:00
}