diff --git a/win-linux/defaults.pri b/win-linux/defaults.pri index d6b1f0dc3..1188b0428 100644 --- a/win-linux/defaults.pri +++ b/win-linux/defaults.pri @@ -71,7 +71,6 @@ HEADERS += \ $$PWD/src/windows/ceditorwindow_p.h \ $$PWD/src/windows/cpresenterwindow.h \ $$PWD/src/components/asctabwidget.h \ - $$PWD/src/components/ctabbarwrapper.h \ $$PWD/src/components/cdownloadwidget.h \ $$PWD/src/components/cpushbutton.h \ $$PWD/src/components/cfiledialog.h \ @@ -122,7 +121,6 @@ SOURCES += \ $$PWD/src/components/cpushbutton.cpp \ $$PWD/src/components/cfiledialog.cpp \ $$PWD/src/components/cprintprogress.cpp \ - $$PWD/src/components/ctabbarwrapper.cpp \ $$PWD/src/components/ctabbar.cpp \ $$PWD/src/components/cmessage.cpp \ $$PWD/src/components/canimatedicon.cpp \ diff --git a/win-linux/res/styles/tabbar.qss b/win-linux/res/styles/tabbar.qss index ed787650b..3160f399a 100644 --- a/win-linux/res/styles/tabbar.qss +++ b/win-linux/res/styles/tabbar.qss @@ -1,275 +1,225 @@ +CTabBar {background: #f1f1f1;} +CTabBar #tabArea {background: transparent;} -QTabWidget::pane {background-color: #f1f1f1; border: none; padding: 0px;} -QLabel[class=tab-icon] {padding:0 0 2px 4px;} -QTabBar {font-size: 11px; font-family: "Arial", "Helvetica", "Helvetica Neue", sans-serif; background-color: #f1f1f1;} -QTabBar::tear {width: 0px;} -QTabBar::scroller {width: 0px;} -QTabBar::tab {min-width: 41px; max-width: 135px; width: 135px; height: 28px; background-color: #f1f1f1; border: 0 none; - border-right: 1px solid #a5a5a5; margin: 0 0 0 0; padding: 0px;} -QTabBar::tab:hover {background-color: #cecece;} -QTabBar::tab-label {active: #fff; normal: #444;} -QTabBar::tab-icon {width: 15; height: 15;} -QTabBar::tab:first {} -QTabBar::tab:only-one {} -QTabBar::tab:last {} -QTabBar::tab::selected {padding-left: 0px;} -QTabBar[active=false]::tab:selected {background-color: #f1f1f1;} -QTabBar[active=true]::tab:selected {background-color: #f1f1f1;} -QTabBar[active=false]::tab:selected:hover {background-color: #cecece;} +CTabBar #tabScroll {border: none; background: transparent;} +CTabBar #tabScroll>QToolButton {margin: 0px; border: none; background: #f1f1f1;} +CTabBar #tabScroll>QToolButton:hover {background: #cecece;} +CTabBar #tabScroll>QToolButton:pressed {background: #b7b7b7;} +CTabBar #tabScroll>#leftButton {image: url(:/tabbar/icons/scrolltab_ln.svg);} +CTabBar #tabScroll>#leftButton:disabled {image: url(:/tabbar/icons/scrolltab_ld.svg);} +CTabBar #tabScroll>#leftButton:hover {image: url(:/tabbar/icons/scrolltab_lh.svg);} +CTabBar #tabScroll>#leftButton:pressed {image: url(:/tabbar/icons/scrolltab_lp.svg);} -QTabBar::close-button { - image: url(:/res/icons/tab_close_normal.svg); - margin-top: -1px; - icon-size:16px; -} -QTabBar::close-button:hover { - image: url(:/res/icons/tab_close_hover.svg); -} -QTabBar::close-button:pressed { - image: url(:/res/icons/tab_close_active.svg); -} +CTabBar #tabScroll>#rightButton {image: url(:/tabbar/icons/scrolltab_rn.svg);} +CTabBar #tabScroll>#rightButton:disabled {image: url(:/tabbar/icons/scrolltab_rd.svg);} +CTabBar #tabScroll>#rightButton:hover {image: url(:/tabbar/icons/scrolltab_rh.svg);} +CTabBar #tabScroll>#rightButton:pressed {image: url(:/tabbar/icons/scrolltab_rp.svg);} -QTabBar QToolButton, - QTabBar QToolButton:disabled { - background-color:#f1f1f1; - border:0 none; - width: 40px; -} +Tab {background: #f1f1f1; border: none; border-right: 1px solid #dfdfdf; margin: 0px; padding: 0px;} +Tab #tabIcon {background: transparent; /*image: url(:/tabbar/icons/res/icons/tabicon_oform_normal.svg);*/} +Tab #tabText {color: #444; background: transparent; font-family: "Arial", "Helvetica", "Helvetica Neue", sans-serif;} +Tab #tabButton {border: none; margin-top: 0px; image: none; background: transparent;} -QTabBar QToolButton[class=tab-close]{ - background-color:rgba(255,255,255,0); -} -QTabBar QToolButton[class=tab-close]{ - image: url(:/tabbar/icons/close_normal.svg); -} -QTabBar QToolButton[class=tab-close][state=active]{ - image:url(:/tabbar/icons/close_active_normal.svg); -} -QTabBar QToolButton[class=tab-close]:hover{ - image: url(:/tabbar/icons/close_hover.svg); -} -QTabBar QToolButton[class=tab-close][state=active]:hover{ - image: url(:/tabbar/icons/close_active_hover.svg); -} -QTabBar QToolButton[class=tab-close]:pressed{ - image: url(:/tabbar/icons/close_pressed.svg); -} -QTabBar QToolButton[class=tab-close][state=active]:pressed{ - image: url(:/tabbar/icons/close_active_pressed.svg); -} +Tab[selected=true] {background: #446995; border-color: #446995;} +Tab[selected=true] #tabText {color: #fff;} +Tab[selected=true] #tabButton {image:url(:/tabbar/icons/close_active_normal.svg); /*background: #446995;*/} +Tab[selected=true] #tabButton:hover {image: url(:/tabbar/icons/close_active_hover.svg);} +Tab[selected=true] #tabButton:pressed {image: url(:/tabbar/icons/close_active_pressed.svg);} -#tabWrapper {margin: 0; padding: 0; background: #f1f1f1;} -#paddingWidget {min-width: 0px; max-width: 0px; border: none; background: transparent;} +CTabBar[active=false] Tab[selected=true] {background: #f1f1f1; border-color: #dfdfdf;} +CTabBar[active=false] Tab[selected=true] #tabText {color: #444;} +CTabBar[active=false] Tab[selected=true] #tabButton {image: none; /*background: #f1f1f1;*/} -#scrollerFrame {min-width: 32px; max-width: 32px; border: none; background: transparent;} -#scrollerFrame>QToolButton {max-height: 28px; margin: 0px; border: none; background-color: #f1f1f1;} -#scrollerFrame>QToolButton:hover {background-color: #cecece;} -#scrollerFrame>QToolButton:pressed {background-color: #b7b7b7;} - -#scrollerFrame>QToolButton#leftButton { - image: url(:/tabbar/icons/scrolltab_ln.svg) center no-repeat; -} -#scrollerFrame>QToolButton#leftButton:disabled { - image: url(:/tabbar/icons/scrolltab_ld.svg) center no-repeat; -} -#scrollerFrame>QToolButton#leftButton:hover { - image: url(:/tabbar/icons/scrolltab_lh.svg) center no-repeat; -} -#scrollerFrame>QToolButton#leftButton:pressed { - image: url(:/tabbar/icons/scrolltab_lp.svg) center no-repeat; -} - -#scrollerFrame>QToolButton#rightButton { - image: url(:/tabbar/icons/scrolltab_rn.svg) center no-repeat; -} -#scrollerFrame>QToolButton#rightButton:disabled { - image: url(:/tabbar/icons/scrolltab_rd.svg) center no-repeat; -} -#scrollerFrame>QToolButton#rightButton:hover { - image: url(:/tabbar/icons/scrolltab_rh.svg) center no-repeat; -} -#scrollerFrame>QToolButton#rightButton:pressed { - image: url(:/tabbar/icons/scrolltab_rp.svg) center no-repeat; -} +Tab[selected=false][hovered=true], +CTabBar[active=false] Tab[selected=true][hovered=true] {background: #cecece;} +Tab[selected=false][hovered=true] #tabButton, +CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton {image: url(:/tabbar/icons/close_normal.svg); /*background: #cecece;*/} +Tab[selected=false][hovered=true] #tabButton:hover, +CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton:hover {image: url(:/tabbar/icons/close_hover.svg);} +Tab[selected=false][hovered=true] #tabButton:pressed, +CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton:pressed {image: url(:/tabbar/icons/close_pressed.svg);} /* light */ -#mainPanel[uitheme=theme-light] QTabBar::tab {border-right-color:#dfdfdf;} +#mainPanel[uitheme=theme-light] Tab {border-right-color: #dfdfdf;} /* classic light */ -#mainPanel[uitheme=theme-classic-light] QTabBar::tab {border-right-color:#cbcbcb;} +#mainPanel[uitheme=theme-classic-light] Tab {border-right-color: #cbcbcb;} /* dark */ -#mainPanel[uitheme=theme-dark] QTabBar, -#mainPanel[uitheme=theme-dark] #tabWrapper {background-color: #404040;} -#mainPanel[uitheme=theme-dark] QTabBar QToolButton::left-arrow, -#mainPanel[uitheme=theme-dark] QTabBar QToolButton::right-arrow {background-color: #606060;} -#mainPanel[uitheme=theme-dark] QTabBar QToolButton:pressed {background-color: #606060;} -#mainPanel[uitheme=theme-dark] QTabWidget::pane {background-color: #404040;} -#mainPanel[uitheme=theme-dark] QTabBar::tab {background-color: #404040; border-right-color: #505050;} -#mainPanel[uitheme=theme-dark] QTabBar::tab:hover {background-color: #555;} -#mainPanel[uitheme=theme-dark] QTabBar::tab:selected {background-color: #404040;} -#mainPanel[uitheme=theme-dark] QTabBar[active=false]::tab:selected:hover {background-color: #555;} -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton {background-color: #404040;} -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton:hover {background-color: #555;} -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton:pressed {background-color: #606060;} +#mainPanel[uitheme=theme-dark] CTabBar {background: #404040;} +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>QToolButton {background: #404040;} +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>QToolButton:hover {background: #555;} +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>QToolButton:pressed {background: #606060;} +#mainPanel[uitheme=theme-dark] Tab {background: #404040; border-right-color: #505050;} +#mainPanel[uitheme=theme-dark] Tab #tabText {color: #dfdfdf;} +#mainPanel[uitheme=theme-dark] Tab[selected=true] {background: #2a2a2a; border-color: #2a2a2a;} +#mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true] {background: #404040; border-color: #505050;} +#mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true][custom=true] #tabText {color: #dfdfdf;} +#mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true][custom=true] #tabButton {image: none;} +#mainPanel[uitheme=theme-dark] Tab[selected=false][hovered=true], +#mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true][hovered=true] {background: #555;} +#mainPanel[uitheme=theme-dark] Tab[selected=false][hovered=true] #tabButton, +#mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton {image: url(:/tabbar/icons/close_active_normal.svg);} +#mainPanel[uitheme=theme-dark] Tab[selected=false][hovered=true] #tabButton:hover, +#mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton:hover {image: url(:/tabbar/icons/close_active_hover.svg);} +#mainPanel[uitheme=theme-dark] Tab[selected=false][hovered=true] #tabButton:pressed, +#mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton:pressed {image: url(:/tabbar/icons/close_active_pressed.svg);} +#mainPanel[uitheme=theme-dark] Tab[selected=true] #tabButton:pressed {background: #555;} +#mainPanel[uitheme=theme-dark] Tab[selected=true][custom=true] #tabButton:pressed {background: transparent;} /* contrast-dark */ -#mainPanel[uitheme=theme-contrast-dark] QTabBar, -#mainPanel[uitheme=theme-contrast-dark] #tabWrapper {background-color: #2a2a2a;} -#mainPanel[uitheme=theme-contrast-dark] QTabBar QToolButton::left-arrow, -#mainPanel[uitheme=theme-contrast-dark] QTabBar QToolButton::right-arrow {background-color: #f00;} -#mainPanel[uitheme=theme-contrast-dark] QTabBar QToolButton:pressed {background-color: #f00;} -#mainPanel[uitheme=theme-contrast-dark] QTabWidget::pane {background-color: #2a2a2a;} -#mainPanel[uitheme=theme-contrast-dark] QTabBar::tab {background-color: #2a2a2a; border-right-color: #414141;} -#mainPanel[uitheme=theme-contrast-dark] QTabBar::tab:hover {background-color: #424242;} -#mainPanel[uitheme=theme-contrast-dark] QTabBar::tab:selected {background-color: #2a2a2a;} -#mainPanel[uitheme=theme-contrast-dark] QTabBar[active=false]::tab:selected:hover {background-color: #424242;} -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton {background-color: #2a2a2a;} -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton:hover {background-color: #525252;} -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton:pressed {background-color: #424242;} +#mainPanel[uitheme=theme-contrast-dark] CTabBar {background: #2a2a2a;} +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>QToolButton {background: #2a2a2a;} +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>QToolButton:hover {background: #525252;} +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>QToolButton:pressed {background: #424242;} +#mainPanel[uitheme=theme-contrast-dark] Tab {background: #2a2a2a; border-right-color: #414141;} +#mainPanel[uitheme=theme-contrast-dark] Tab #tabText {color: #fff;} +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=true] {background: #1e1e1e; border-color: #1e1e1e;} +#mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true] {background: #2a2a2a; border-color: #414141;} +#mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true][custom=true] #tabText {color: #fff;} +#mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true][custom=true] #tabButton {image: none;} +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=false][hovered=true], +#mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true][hovered=true] {background: #424242;} +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=false][hovered=true] #tabButton, +#mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton {image: url(:/tabbar/icons/close_active_normal.svg);} +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=false][hovered=true] #tabButton:hover, +#mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton:hover {image: url(:/tabbar/icons/close_active_hover.svg);} +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=false][hovered=true] #tabButton:pressed, +#mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true][hovered=true] #tabButton:pressed {image: url(:/tabbar/icons/close_active_pressed.svg);} +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=true] #tabButton:pressed {background: #424242;} +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=true][custom=true] #tabButton:pressed {background: transparent;} + +/* portal */ +Tab[selected=true][custom=true], +#mainPanel[uitheme=theme-dark] Tab[selected=true][custom=true], +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=true][custom=true] {background: #fff;} +Tab[selected=true][custom=true] #tabText, +#mainPanel[uitheme=theme-dark] Tab[selected=true][custom=true] #tabText, +#mainPanel[uitheme=theme-contrast-dark] Tab[selected=true][custom=true] #tabText {color: #444;} +Tab[selected=true][custom=true] #tabButton {image:url(:/tabbar/icons/close_normal.svg);} +Tab[selected=true][custom=true] #tabButton:hover {image: url(:/tabbar/icons/close_hover.svg);} +Tab[selected=true][custom=true] #tabButton:pressed {image: url(:/tabbar/icons/close_pressed.svg);} /* dark, contrast-dark */ -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton#leftButton, -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton#leftButton { - image: url(:/tabbar/icons/scrolltab_ln_light.svg) center no-repeat; +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>#leftButton, +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>#leftButton { + image: url(:/tabbar/icons/scrolltab_ln_light.svg); } -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton#leftButton:disabled, -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton#leftButton:disabled { - image: url(:/tabbar/icons/scrolltab_ld_light.svg) center no-repeat; +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>#leftButton:disabled, +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>#leftButton:disabled { + image: url(:/tabbar/icons/scrolltab_ld_light.svg); } -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton#leftButton:hover, -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton#leftButton:hover { - image: url(:/tabbar/icons/scrolltab_lh_light.svg) center no-repeat; +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>#leftButton:hover, +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>#leftButton:hover { + image: url(:/tabbar/icons/scrolltab_lh_light.svg); } -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton#leftButton:pressed, -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton#leftButton:pressed { - image: url(:/tabbar/icons/scrolltab_lp_light.svg) center no-repeat; +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>#leftButton:pressed, +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>#leftButton:pressed { + image: url(:/tabbar/icons/scrolltab_lp_light.svg); } -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton#rightButton, -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton#rightButton { - image: url(:/tabbar/icons/scrolltab_rn_light.svg) center no-repeat; +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>#rightButton, +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>#rightButton { + image: url(:/tabbar/icons/scrolltab_rn_light.svg); } -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton#rightButton:disabled, -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton#rightButton:disabled { - image: url(:/tabbar/icons/scrolltab_rd_light.svg) center no-repeat; +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>#rightButton:disabled, +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>#rightButton:disabled { + image: url(:/tabbar/icons/scrolltab_rd_light.svg); } -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton#rightButton:hover, -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton#rightButton:hover { - image: url(:/tabbar/icons/scrolltab_rh_light.svg) center no-repeat; +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>#rightButton:hover, +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>#rightButton:hover { + image: url(:/tabbar/icons/scrolltab_rh_light.svg); } -#mainPanel[uitheme=theme-dark] #scrollerFrame>QToolButton#rightButton:pressed, -#mainPanel[uitheme=theme-contrast-dark] #scrollerFrame>QToolButton#rightButton:pressed { - image: url(:/tabbar/icons/scrolltab_rp_light.svg) center no-repeat; +#mainPanel[uitheme=theme-dark] CTabBar #tabScroll>#rightButton:pressed, +#mainPanel[uitheme=theme-contrast-dark] CTabBar #tabScroll>#rightButton:pressed { + image: url(:/tabbar/icons/scrolltab_rp_light.svg); } +/* 1x */ +CTabBar #tabScroll {min-width: 32px; max-width: 32px;} +CTabBar #tabScroll>QToolButton {max-height: 28px;} +Tab {min-width: 41px; max-width: 135px; width: 135px; height: 28px;} +Tab #tabIcon {padding: 0px; min-width: 15px; min-height: 15px; max-width: 15px; max-height: 15px;} +Tab #tabText {font-size: 11px;} +Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2px;} + /* 1.25x */ -#mainPanel[zoom="1.25x"] QLabel[class=tab-icon] {padding:0 0 2px 8px;} -#mainPanel[zoom="1.25x"] QTabBar {font-size: 14px;} -#mainPanel[zoom="1.25x"] QTabBar::tab {min-width: 51px; max-width: 169px; width: 169px; height: 35px; border-right-width: 1px;} -#mainPanel[zoom="1.25x"] QTabBar::close-button {margin-top: -1px; icon-size: 20px;} -#mainPanel[zoom="1.25x"] QTabBar QToolButton, -#mainPanel[zoom="1.25x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="1.25x"] #paddingWidget {min-width: 15px; max-width: 15px;} -#mainPanel[zoom="1.25x"] #scrollerFrame {min-width: 48px; max-width: 48px;} -#mainPanel[zoom="1.25x"] #scrollerFrame>QToolButton {max-height: 35px;} +#mainPanel[zoom="1.25x"] CTabBar #tabScroll {min-width: 48px; max-width: 48px;} +#mainPanel[zoom="1.25x"] CTabBar #tabScroll>QToolButton {max-height: 35px;} +#mainPanel[zoom="1.25x"] Tab {min-width: 51px; max-width: 169px; width: 169px; height: 35px; border-right-width: 1px;} +#mainPanel[zoom="1.25x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 19px; min-height: 19px; max-width: 19px; max-height: 19px;} +#mainPanel[zoom="1.25x"] Tab #tabText {font-size: 14px;} +#mainPanel[zoom="1.25x"] Tab #tabButton {width: 20px; max-width: 20px; max-height: 20px; border-width: 2px;} /* 1.5x */ -#mainPanel[zoom="1.5x"] QLabel[class=tab-icon] {padding:0 0 3px 9px;} -#mainPanel[zoom="1.5x"] QTabBar {font-size: 15px;} -#mainPanel[zoom="1.5x"] QTabBar::tab {min-width: 62px; max-width: 203px; width: 203px; height: 42px; border-right-width: 2px;} -#mainPanel[zoom="1.5x"] QTabBar::close-button {margin-top: -1px; icon-size: 24px;} -#mainPanel[zoom="1.5x"] QTabBar QToolButton, -#mainPanel[zoom="1.5x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="1.5x"] #paddingWidget {min-width: 15px; max-width: 15px;} -#mainPanel[zoom="1.5x"] #scrollerFrame {min-width: 48px; max-width: 48px;} -#mainPanel[zoom="1.5x"] #scrollerFrame>QToolButton {max-height: 42px;} +#mainPanel[zoom="1.5x"] CTabBar #tabScroll {min-width: 48px; max-width: 48px;} +#mainPanel[zoom="1.5x"] CTabBar #tabScroll>QToolButton {max-height: 42px;} +#mainPanel[zoom="1.5x"] Tab {min-width: 62px; max-width: 203px; width: 203px; height: 42px; border-right-width: 2px;} +#mainPanel[zoom="1.5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 24px; min-height: 24px; max-width: 24px; max-height: 24px;} +#mainPanel[zoom="1.5x"] Tab #tabText {font-size: 15px;} +#mainPanel[zoom="1.5x"] Tab #tabButton {width: 24px; max-width: 24px; max-height: 24px; border-width: 2px;} /* 1.75x */ -#mainPanel[zoom="1.75x"] QLabel[class=tab-icon] {padding:0 0 4px 9px;} -#mainPanel[zoom="1.75x"] QTabBar {font-size: 18px;} -#mainPanel[zoom="1.75x"] QTabBar::tab {min-width: 72px; max-width: 236px; width: 236px; height: 49px; border-right-width: 2px;} -#mainPanel[zoom="1.75x"] QTabBar::close-button {margin-top: -2px; icon-size: 28px;} -#mainPanel[zoom="1.75x"] QTabBar QToolButton, -#mainPanel[zoom="1.75x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="1.75x"] #paddingWidget {min-width: 31px; max-width: 31px;} -#mainPanel[zoom="1.75x"] #scrollerFrame {min-width: 64px; max-width: 64px;} -#mainPanel[zoom="1.75x"] #scrollerFrame>QToolButton {max-height: 49px;} +#mainPanel[zoom="1.75x"] CTabBar #tabScroll {min-width: 64px; max-width: 64px;} +#mainPanel[zoom="1.75x"] CTabBar #tabScroll>QToolButton {max-height: 49px;} +#mainPanel[zoom="1.75x"] Tab {min-width: 72px; max-width: 236px; width: 236px; height: 49px; border-right-width: 2px;} +#mainPanel[zoom="1.75x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 28px; min-height: 28px; max-width: 28px; max-height: 28px;} +#mainPanel[zoom="1.75x"] Tab #tabText {font-size: 18px;} +#mainPanel[zoom="1.75x"] Tab #tabButton {width: 28px; max-width: 28px; max-height: 28px; border-width: 2px;} /* 2x */ -#mainPanel[zoom="2x"] QLabel[class=tab-icon] {padding:0 0 4px 12px;} -#mainPanel[zoom="2x"] QTabBar {font-size: 20px;} -#mainPanel[zoom="2x"] QTabBar::tab {min-width: 82px; max-width: 270px; width: 270px; height: 56px; border-right-width: 2px;} -#mainPanel[zoom="2x"] QTabBar::close-button {margin-top: -2px; icon-size: 32px;} -#mainPanel[zoom="2x"] QTabBar QToolButton, -#mainPanel[zoom="2x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="2x"] #paddingWidget {min-width: 31px; max-width: 31px;} -#mainPanel[zoom="2x"] #scrollerFrame {min-width: 64px; max-width: 64px;} -#mainPanel[zoom="2x"] #scrollerFrame>QToolButton {max-height: 56px;} +#mainPanel[zoom="2x"] CTabBar #tabScroll {min-width: 64px; max-width: 64px;} +#mainPanel[zoom="2x"] CTabBar #tabScroll>QToolButton {max-height: 56px;} +#mainPanel[zoom="2x"] Tab {min-width: 82px; max-width: 270px; width: 270px; height: 56px; border-right-width: 2px;} +#mainPanel[zoom="2x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 32px; min-height: 32px; max-width: 32px; max-height: 32px;} +#mainPanel[zoom="2x"] Tab #tabText {font-size: 20px;} +#mainPanel[zoom="2x"] Tab #tabButton {width: 32px; max-width: 32px; max-height: 32px; border-width: 2px;} /* 2.5x */ -#mainPanel[zoom="2.5x"] QLabel[class=tab-icon] {padding:0 0 5px 15px;} -#mainPanel[zoom="2.5x"] QTabBar {font-size: 25px;} -#mainPanel[zoom="2.5x"] QTabBar::tab {min-width: 103px; max-width: 338px; width: 338px; height: 70px; border-right-width: 3px;} -#mainPanel[zoom="2.5x"] QTabBar::close-button {margin-top: -3px; icon-size: 40px;} -#mainPanel[zoom="2.5x"] QTabBar QToolButton, -#mainPanel[zoom="2.5x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="2.5x"] #paddingWidget {min-width: 49px; max-width: 49px;} -#mainPanel[zoom="2.5x"] #scrollerFrame {min-width: 80px; max-width: 80px;} -#mainPanel[zoom="2.5x"] #scrollerFrame>QToolButton {max-height: 70px;} +#mainPanel[zoom="2.5x"] CTabBar #tabScroll {min-width: 80px; max-width: 80px;} +#mainPanel[zoom="2.5x"] CTabBar #tabScroll>QToolButton {max-height: 70px;} +#mainPanel[zoom="2.5x"] Tab {min-width: 103px; max-width: 338px; width: 338px; height: 70px; border-right-width: 3px;} +#mainPanel[zoom="2.5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 40px; min-height: 40px; max-width: 40px; max-height: 40px;} +#mainPanel[zoom="2.5x"] Tab #tabText {font-size: 25px;} +#mainPanel[zoom="2.5x"] Tab #tabButton {width: 40px; max-width: 40px; max-height: 40px; border-width: 2px;} /* 3x */ -#mainPanel[zoom="3x"] QLabel[class=tab-icon] {padding:0 0 6px 18px;} -#mainPanel[zoom="3x"] QTabBar {font-size: 30px;} -#mainPanel[zoom="3x"] QTabBar::tab {min-width: 123px; max-width: 405px; width: 405px; height: 84px; border-right-width: 3px;} -#mainPanel[zoom="3x"] QTabBar::close-button {margin-top: -3px; icon-size: 48px;} -#mainPanel[zoom="3x"] QTabBar QToolButton, -#mainPanel[zoom="3x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="3x"] #paddingWidget {min-width: 65px; max-width: 65px;} -#mainPanel[zoom="3x"] #scrollerFrame {min-width: 96px; max-width: 96px;} -#mainPanel[zoom="3x"] #scrollerFrame>QToolButton {max-height: 84px;} +#mainPanel[zoom="3x"] CTabBar #tabScroll {min-width: 96px; max-width: 96px;} +#mainPanel[zoom="3x"] CTabBar #tabScroll>QToolButton {max-height: 84px;} +#mainPanel[zoom="3x"] Tab {min-width: 123px; max-width: 405px; width: 405px; height: 84px; border-right-width: 3px;} +#mainPanel[zoom="3x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 48px; min-height: 48px; max-width: 48px; max-height: 48px;} +#mainPanel[zoom="3x"] Tab #tabText {font-size: 30px;} +#mainPanel[zoom="3x"] Tab #tabButton {width: 48px; max-width: 48px; max-height: 48px; border-width: 2px;} /* 3.5x */ -#mainPanel[zoom="3.5x"] QLabel[class=tab-icon] {padding:0 0 7px 21px;} -#mainPanel[zoom="3.5x"] QTabBar {font-size: 35px;} -#mainPanel[zoom="3.5x"] QTabBar::tab {min-width: 144px; max-width: 473px; width: 473px; height: 98px; border-right-width: 4px;} -#mainPanel[zoom="3.5x"] QTabBar::close-button {margin-top: -4px; icon-size: 56px;} -#mainPanel[zoom="3.5x"] QTabBar QToolButton, -#mainPanel[zoom="3.5x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="3.5x"] #paddingWidget {min-width: 82px; max-width: 82px;} -#mainPanel[zoom="3.5x"] #scrollerFrame {min-width: 112px; max-width: 112px;} -#mainPanel[zoom="3.5x"] #scrollerFrame>QToolButton {max-height: 98px;} +#mainPanel[zoom="3.5x"] CTabBar #tabScroll {min-width: 112px; max-width: 112px;} +#mainPanel[zoom="3.5x"] CTabBar #tabScroll>QToolButton {max-height: 98px;} +#mainPanel[zoom="3.5x"] Tab {min-width: 144px; max-width: 473px; width: 473px; height: 98px; border-right-width: 4px;} +#mainPanel[zoom="3.5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 56px; min-height: 56px; max-width: 56px; max-height: 56px;} +#mainPanel[zoom="3.5x"] Tab #tabText {font-size: 35px;} +#mainPanel[zoom="3.5x"] Tab #tabButton {width: 56px; max-width: 56px; max-height: 56px; border-width: 2px;} /* 4x */ -#mainPanel[zoom="4x"] QLabel[class=tab-icon] {padding:0 0 8px 24px;} -#mainPanel[zoom="4x"] QTabBar {font-size: 40px;} -#mainPanel[zoom="4x"] QTabBar::tab {min-width: 164px; max-width: 540px; width: 540px; height: 112px; border-right-width: 4px;} -#mainPanel[zoom="4x"] QTabBar::close-button {margin-top: -4px; icon-size: 64px;} -#mainPanel[zoom="4x"] QTabBar QToolButton, -#mainPanel[zoom="4x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="4x"] #paddingWidget {min-width: 98px; max-width: 98px;} -#mainPanel[zoom="4x"] #scrollerFrame {min-width: 128px; max-width: 128px;} -#mainPanel[zoom="4x"] #scrollerFrame>QToolButton {max-height: 112px;} +#mainPanel[zoom="4x"] CTabBar #tabScroll {min-width: 128px; max-width: 128px;} +#mainPanel[zoom="4x"] CTabBar #tabScroll>QToolButton {max-height: 112px;} +#mainPanel[zoom="4x"] Tab {min-width: 164px; max-width: 540px; width: 540px; height: 112px; border-right-width: 4px;} +#mainPanel[zoom="4x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 64px; min-height: 64px; max-width: 64px; max-height: 64px;} +#mainPanel[zoom="4x"] Tab #tabText {font-size: 40px;} +#mainPanel[zoom="4x"] Tab #tabButton {width: 64px; max-width: 64px; max-height: 64px; border-width: 2px;} /* 4.5x */ -#mainPanel[zoom="4.5x"] QLabel[class=tab-icon] {padding:0 0 9px 27px;} -#mainPanel[zoom="4.5x"] QTabBar {font-size: 45px;} -#mainPanel[zoom="4.5x"] QTabBar::tab {min-width: 185px; max-width: 608px; width: 608px; height: 126px; border-right-width: 5px;} -#mainPanel[zoom="4.5x"] QTabBar::close-button {margin-top: -5px; icon-size: 72px;} -#mainPanel[zoom="4.5x"] QTabBar QToolButton, -#mainPanel[zoom="4.5x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="4.5x"] #paddingWidget {min-width: 112px; max-width: 112px;} -#mainPanel[zoom="4.5x"] #scrollerFrame {min-width: 144px; max-width: 144px;} -#mainPanel[zoom="4.5x"] #scrollerFrame>QToolButton {max-height: 126px;} +#mainPanel[zoom="4.5x"] CTabBar #tabScroll {min-width: 144px; max-width: 144px;} +#mainPanel[zoom="4.5x"] CTabBar #tabScroll>QToolButton {max-height: 126px;} +#mainPanel[zoom="4.5x"] Tab {min-width: 185px; max-width: 608px; width: 608px; height: 126px; border-right-width: 5px;} +#mainPanel[zoom="4.5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 72px; min-height: 72px; max-width: 72px; max-height: 72px;} +#mainPanel[zoom="4.5x"] Tab #tabText {font-size: 45px;} +#mainPanel[zoom="4.5x"] Tab #tabButton {width: 72px; max-width: 72px; max-height: 72px; border-width: 2px;} /* 5x */ -#mainPanel[zoom="5x"] QLabel[class=tab-icon] {padding:0 0 10px 30px;} -#mainPanel[zoom="5x"] QTabBar {font-size: 50px;} -#mainPanel[zoom="5x"] QTabBar::tab {min-width: 205px; max-width: 675px; width: 675px; height: 140px; border-right-width: 5px;} -#mainPanel[zoom="5x"] QTabBar::close-button {margin-top: -5px; icon-size: 80px;} -#mainPanel[zoom="5x"] QTabBar QToolButton, -#mainPanel[zoom="5x"] QTabBar QToolButton:disabled {/*margin-right: -2px;*/ border-width: 2px;} -#mainPanel[zoom="5x"] #paddingWidget {min-width: 130px; max-width: 130px;} -#mainPanel[zoom="5x"] #scrollerFrame {min-width: 160px; max-width: 160px;} -#mainPanel[zoom="5x"] #scrollerFrame>QToolButton {max-height: 140px;} +#mainPanel[zoom="5x"] CTabBar #tabScroll {min-width: 160px; max-width: 160px;} +#mainPanel[zoom="5x"] CTabBar #tabScroll>QToolButton {max-height: 140px;} +#mainPanel[zoom="5x"] Tab {min-width: 205px; max-width: 675px; width: 675px; height: 140px; border-right-width: 5px;} +#mainPanel[zoom="5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 80px; min-height: 80px; max-width: 80px; max-height: 80px;} +#mainPanel[zoom="5x"] Tab #tabText {font-size: 50px;} +#mainPanel[zoom="5x"] Tab #tabButton {width: 80px; max-width: 80px; max-height: 80px; border-width: 2px;} diff --git a/win-linux/src/components/asctabwidget.cpp b/win-linux/src/components/asctabwidget.cpp index ab3e8c184..001a5e3ba 100644 --- a/win-linux/src/components/asctabwidget.cpp +++ b/win-linux/src/components/asctabwidget.cpp @@ -32,36 +32,25 @@ #include "components/asctabwidget.h" #include - -#include - #include #include -#include -#include #include +#include #include #include - -#include "ctabstyle.h" #include "casctabdata.h" #include "common/Types.h" #include "defines.h" #include "utils.h" #include "cfilechecker.h" -#include "components/canimatedicon.h" #include "ceditortools.h" - #include "cascapplicationmanagerwrapper.h" #include "ctabundockevent.h" #include "OfficeFileFormats.h" -#include "private/qtabbar_p.h" using namespace std; - - /* * * Tab data @@ -141,7 +130,7 @@ auto panelfromwidget(QWidget * panelwidget) -> CTabPanel * { } CAscTabWidget::CAscTabWidget(QWidget *parent, CTabBar *_pBar) - : QTabWidget(parent) + : QStackedWidget(parent) , CScalingWrapper(parent) , m_dataFullScreen(0) , m_widthParams({{100, 135, 9}, 68, 3, 0, WINDOW_TITLE_MIN_WIDTH, 140, 0}) @@ -150,43 +139,36 @@ CAscTabWidget::CAscTabWidget(QWidget *parent, CTabBar *_pBar) , m_tabIconSize(16, 16) , m_pBar(_pBar) { - QTabWidget::tabBar()->hide(); m_pBar->setObjectName("asc_editors_tabbar"); - m_pBar->setTabTextColor(QPalette::Active, QColor(51, 51, 51)); - m_pBar->setTabTextColor(QPalette::Inactive, QColor(51, 51, 51)); - - m_pBar->setMovable(true); - m_pBar->setExpanding(false); - m_pBar->setTabsClosable(true); - - setIconSize(m_tabIconSize); setProperty("active", false); setProperty("empty", true); m_pBar->setProperty("active", false); static int _dropedindex = -1; QObject::connect(this, &CAscTabWidget::currentChanged, this, [=](int index) { - if (index > -1) m_pBar->setCurrentIndex(index); - updateIcons(); + QTimer::singleShot(0, this, [=]() { + updateIcons(); + }); setFocusedView(); _dropedindex = -1; }); - QObject::connect(m_pBar, &CTabBar::tabUndock, this, [=](int index, bool * accept) { + QObject::connect(this, &CAscTabWidget::widgetRemoved, this, [=](int index) { + emit editorRemoved(index, count()); + }); + QObject::connect(m_pBar, &CTabBar::tabUndock, this, [=](int index, bool &accept) { if (index == _dropedindex) return; const CTabPanel * _panel = panel(index); if ( _panel->data()->viewType() == cvwtEditor ) { CTabUndockEvent event(index); - QObject * obj = qobject_cast( - static_cast(&AscAppManager::getInstance())); + QObject * obj = qobject_cast(&AscAppManager::getInstance()); if ( QApplication::sendEvent(obj, &event) && event.isAccepted() ) { _dropedindex = index; - *accept = true; + accept = true; - QTimer::singleShot(10, this, [=]() { + QTimer::singleShot(0, this, [=]() { if (widget(index)) { - m_pBar->removeTab(index); widget(index)->deleteLater(); } }); @@ -205,7 +187,11 @@ CAscTabWidget::CAscTabWidget(QWidget *parent, CTabBar *_pBar) turnOffAltHints(m_pBar->currentIndex(), index); }); QObject::connect(m_pBar, &CTabBar::tabMoved, this, [=](int from, int to) { - QTabWidget::tabBar()->moveTab(from, to); + if (from < 0 || from >= count() || to < 0 || to >= count() || from == to) + return; + auto wgt = widget(from); + removeWidget(wgt); + insertWidget(to, wgt); }); } @@ -267,10 +253,9 @@ int CAscTabWidget::addEditor(const COpenOptions& opts) data->setChanged(opts.srctype == etRecoveryFile); pView->setData(data); - tab_index = addTab(panelwidget, data->title()); + tab_index = addWidget(panelwidget); m_pBar->addTab(data->title()); - //m_pBar->setTabToolTip(tab_index, data->title()); - m_pBar->setTabProperty(tab_index, "ToolTip", data->title()); + m_pBar->setTabToolTip(tab_index, data->title()); m_pBar->tabStartLoading(tab_index); //m_pBar->setCurrentIndex(tab_index); @@ -315,7 +300,7 @@ void CAscTabWidget::closeEditorByIndex(int index, bool checkmodified) int CAscTabWidget::count(int type) const { if ( type < 0 ) - return QTabWidget::count(); + return QStackedWidget::count(); else { int _out(0); for (int i(count()); i-- > 0; ) { @@ -329,7 +314,7 @@ int CAscTabWidget::count(int type) const int CAscTabWidget::count(const wstring& portal, bool exclude) { if ( portal.empty() ) - return QTabWidget::count(); + return QStackedWidget::count(); else { int _out(0); for (int i(count()); i-- > 0; ) { @@ -392,14 +377,11 @@ int CAscTabWidget::addPortal(const QString& url, const QString& name, const QStr int tab_index = -1; - tab_index = insertTab(tab_index, panelwidget, portal); + tab_index = insertWidget(tab_index, panelwidget); m_pBar->insertTab(tab_index, portal); - //m_pBar->setTabToolTip(tab_index, _url); - m_pBar->setTabProperty(tab_index, "ToolTip", _url); - m_pBar->setTabTheme(tab_index, CTabBar::LightTab); + m_pBar->setTabToolTip(tab_index, _url); + m_pBar->setTabIconTheme(tab_index, CTabBar::LightTab); m_pBar->tabStartLoading(tab_index); - //m_pBar->setCurrentIndex(tab_index); - // updateTabIcon(tabIndexByView(id)); return tab_index; @@ -434,13 +416,11 @@ int CAscTabWidget::addOAuthPortal(const QString& portal, const QString& type, co int tab_index = -1; - tab_index = insertTab(tab_index, panelwidget, _portal); + tab_index = insertWidget(tab_index, panelwidget); m_pBar->insertTab(tab_index, _portal); - //m_pBar->setTabToolTip(tab_index, portal); - m_pBar->setTabProperty(tab_index, "ToolTip", portal); - m_pBar->setTabTheme(tab_index, CTabBar::LightTab); + m_pBar->setTabToolTip(tab_index, portal); + m_pBar->setTabIconTheme(tab_index, CTabBar::LightTab); m_pBar->tabStartLoading(tab_index); - //m_pBar->setCurrentIndex(tab_index); return tab_index; } @@ -456,24 +436,19 @@ int CAscTabWidget::insertPanel(QWidget * panel, int index) QWidget * panelwidget = createTabPanel(this, _panel); - tabindex = insertTab(index, panelwidget, tabdata->title()); - m_pBar->insertTab(index, tabdata->title()); - //m_pBar->setTabToolTip(tabindex, tabdata->title()); - m_pBar->setTabProperty(tabindex, "ToolTip", tabdata->title()); - //m_pBar->setCurrentIndex(tabindex); + tabindex = insertWidget(index, panelwidget); + m_pBar->insertTab(tabindex, tabdata->title()); + m_pBar->setTabToolTip(tabindex, tabdata->title()); } return tabindex; } -void CAscTabWidget::tabInserted(int index) +int CAscTabWidget::insertWidget(int index, QWidget* widget) { - emit editorInserted(index, count()); -} - -void CAscTabWidget::tabRemoved(int index) -{ - emit editorRemoved(index, count()); + int actual_index = QStackedWidget::insertWidget(index, widget); + emit editorInserted(actual_index, count()); + return actual_index; } void CAscTabWidget::setCustomWindowParams(bool iscustom) @@ -492,7 +467,7 @@ void CAscTabWidget::updateIcons() void CAscTabWidget::updateTabIcon(int index) { - if ( !(index < 0) ) { + if ( !(index < 0) && panel(index)) { CCefViewEditor * pEditor = (CCefViewEditor *)panel(index)->cef(); if (pEditor) { @@ -514,7 +489,7 @@ void CAscTabWidget::updateTabIcon(int index) default: tab_type = panel(index)->data()->contentType(); break; } - if ( !isActiveWidget() || !(index == currentIndex()) ) { + if ( !is_active ) { tab_theme = AscAppManager::themes().current().isDark() ? CTabBar::DarkTab : CTabBar::LightTab; } else { switch ( tab_type ) { @@ -534,19 +509,16 @@ void CAscTabWidget::updateTabIcon(int index) break; } } - QString icon_name = is_active ? m_mapTabIcons.at(tab_type).second : m_mapTabIcons.at(tab_type).first; m_pBar->setTabIcon(index, QIcon(icon_name)); -// ((CTabBar *)tabBar())->changeTabTheme(index, _theme); - m_pBar->setTabTheme(index, tab_theme); - +// m_pBar->setTabIconTheme(index, tab_theme); if ( index == currentIndex() ) { - m_pBar->setActiveTabColor(active_tab_color); -// ((CTabBar *)tabBar())->setUseTabCustomPalette( !(tab_type == etPortal || tab_type == etUndefined) ); - - m_pBar->setTabTextColor(QPalette::Active, AscAppManager::themes().isColorDark(active_tab_color) ? - ui_theme.color(CTheme::ColorRole::ecrTextPressed) : ui_theme.color(CTheme::ColorRole::ecrTabSimpleActiveText)); - + if (tab_type == etPortal || tab_type == etNewPortal || tab_type == etUndefined) + m_pBar->setUseTabCustomPalette(index, true); + else { + m_pBar->setUseTabCustomPalette(index, false); + m_pBar->setActiveTabColor(index, active_tab_color); + } } } } @@ -580,7 +552,6 @@ void CAscTabWidget::reloadTabIcons() * Slots */ - void CAscTabWidget::editorCloseRequest(int index) { panel(index)->data()->close(); @@ -786,8 +757,7 @@ void CAscTabWidget::applyDocumentChanging(int viewId, const QString& name, const } m_pBar->setTabText(tabIndex, doc->title()); - //m_pBar->setTabToolTip(tabIndex, path.isEmpty() ? doc->title() : path); - m_pBar->setTabProperty(tabIndex, "ToolTip", path.isEmpty() ? doc->title() : path); + m_pBar->setTabToolTip(tabIndex, path.isEmpty() ? doc->title() : path); } } @@ -806,8 +776,7 @@ void CAscTabWidget::applyDocumentChanging(int viewId, bool state) if (doc->hasChanges() != state && (!doc->closed() || state)) { doc->setChanged(state); m_pBar->setTabText(tabIndex, doc->title()); - //m_pBar->setTabToolTip(tabIndex, doc->title()); - m_pBar->setTabProperty(tabIndex, "ToolTip", doc->title()); + m_pBar->setTabToolTip(tabIndex, doc->title()); } } } @@ -878,8 +847,7 @@ void CAscTabWidget::setEditorOptions(int id, const wstring& option) if (option.find(L"readonly\":") != wstring::npos) { m_pBar->setTabText(tabIndex, doc->title()); - //m_pBar->setTabToolTip(tabIndex, doc->title()); - m_pBar->setTabProperty(tabIndex, "ToolTip", doc->title()); + m_pBar->setTabToolTip(tabIndex, doc->title()); } // if (std::regex_search(option, std::wregex(L"titlebuttons\":\\s?true"))) { @@ -924,13 +892,8 @@ void CAscTabWidget::activate(bool a) this->setProperty("active", a); m_pBar->setProperty("active", a); } - - updateTabIcon(currentIndex()); - - m_pBar->activate(a); - m_pBar->customColors().setCurrentColorGroup(a ? QPalette::Normal : QPalette::Disabled ); - m_pBar->update(); - //m_pBar->repaint(); + updateIcons(); + m_pBar->polish(); } bool CAscTabWidget::isActiveWidget() @@ -1157,7 +1120,7 @@ void CAscTabWidget::setFullScreen(bool apply, int id) _break_demonstration(); e->ignore(); // TODO: associate panel with reporter window and close both simultaneously - QTimer::singleShot(10, [=] {emit tabCloseRequested(m_dataFullScreen->tabindex());}); + QTimer::singleShot(10, [=] {emit m_pBar->tabCloseRequested(m_dataFullScreen->tabindex());}); }); connect((CFullScrWidget*)m_dataFullScreen->parent, &CFullScrWidget::closeRequest, this, [=]() { @@ -1173,29 +1136,9 @@ QWidget * CAscTabWidget::fullScreenWidget() return m_dataFullScreen ? m_dataFullScreen->widget() : nullptr; } -void CAscTabWidget::updateScalingFactor(double f) -{ - CScalingWrapper::updateScalingFactor(f); - - double dpi_ratio = scaling(); - - setIconSize(m_tabIconSize * dpi_ratio); - m_pBar->setIconSize(m_tabIconSize * dpi_ratio); - updateIcons(); - - (m_widthParams = size_params(m_defWidthParams)).apply_scale(dpi_ratio); - if ( m_isCustomStyle ) - m_widthParams.tools_width = int(50 * dpi_ratio), - m_widthParams.title_width = int(WINDOW_TITLE_MIN_WIDTH * dpi_ratio); - else - m_widthParams.tools_width = m_widthParams.title_width = 0; - - m_pBar->updateScalingFactor(f); -} - void CAscTabWidget::setStyleSheet(const QString& stylesheet) { - QTabWidget::setStyleSheet(stylesheet); + QStackedWidget::setStyleSheet(stylesheet); auto _string_to_color = [](const QString& str) -> QColor { int r = -1, g = -1, b = -1; @@ -1240,10 +1183,8 @@ void CAscTabWidget::applyUITheme(const std::wstring& theme) { reloadTabIcons(); updateIcons(); -// _tabbar.setTabTextColor(QPalette::Active, AscAppManager::themes().color(theme, CThemes::ColorRole::ecrTextPressed)); - m_pBar->setTabTextColor(QPalette::Inactive, AscAppManager::themes().current().color(CTheme::ColorRole::ecrTextNormal)); - m_pBar->setUIThemeType(!AscAppManager::themes().current().isDark()); - m_pBar->style()->polish(m_pBar); + m_pBar->setIgnoreActiveTabColor(AscAppManager::themes().current().isDark()); + m_pBar->polish(); style()->polish(this); QColor back_color = AscAppManager::themes().current().color(CTheme::ColorRole::ecrWindowBackground); diff --git a/win-linux/src/components/asctabwidget.h b/win-linux/src/components/asctabwidget.h index 1b25c4bf1..67fcd92d0 100644 --- a/win-linux/src/components/asctabwidget.h +++ b/win-linux/src/components/asctabwidget.h @@ -34,16 +34,13 @@ #define ASCTABWIDGET #include -//#include -#include #include -#include "ctabbarwrapper.h" +#include +#include "ctabbar.h" #include "qcefview.h" #include "cscalingwrapper.h" #include "ctabpanel.h" -#include - #define etLocalFile AscEditorType(254) #define etRecoveryFile AscEditorType(253) #define etRecentFile AscEditorType(252) @@ -76,7 +73,7 @@ struct COpenOptions { eOpenMode mode = eOpenMode::edit; }; -class CAscTabWidget : public QTabWidget, public CScalingWrapper +class CAscTabWidget : public QStackedWidget, public CScalingWrapper { Q_OBJECT @@ -118,8 +115,6 @@ class CAscTabWidget : public QTabWidget, public CScalingWrapper typedef std::map< int, std::pair > CTabIconSet; - using QTabWidget::tabBar; - private: std::map m_mapDownloads; CFullScreenData * m_dataFullScreen; @@ -151,15 +146,13 @@ public: void setStyleSheet(const QString&); void applyUITheme(const std::wstring&); - using QTabWidget::count; + using QStackedWidget::count; int count(int type) const; int count(const std::wstring& portal, bool exclude = false); bool hasForPortal(const QString&); - void updateScalingFactor(double) override; protected: - void tabInserted(int index) override; - void tabRemoved(int index) override; + int insertWidget(int index, QWidget* widget); void closeEditor(int, bool, bool); public: diff --git a/win-linux/src/components/canimatedicon.cpp b/win-linux/src/components/canimatedicon.cpp index 8bc8daf60..333d1d406 100644 --- a/win-linux/src/components/canimatedicon.cpp +++ b/win-linux/src/components/canimatedicon.cpp @@ -53,7 +53,8 @@ void CAnimatedIcon::startSvg(const QString& source, const QString& eid) if ( !eid.isEmpty() ) m_svgElemId = eid; if ( m_image ) delete m_image; - m_image = new QPixmap( m_svgSize ); + int icon_size = qMin(width(), height()); + m_image = new QPixmap(icon_size, icon_size); connect(m_svg, &QSvgRenderer::repaintNeeded, this, &CAnimatedIcon::onSvgRepaint); } else { diff --git a/win-linux/src/components/ctabbar.cpp b/win-linux/src/components/ctabbar.cpp index b68dd4372..c1959189e 100644 --- a/win-linux/src/components/ctabbar.cpp +++ b/win-linux/src/components/ctabbar.cpp @@ -31,1041 +31,1073 @@ */ #include "components/ctabbar.h" -//#include "ctabbar_p.h" -#include "private/qtabbar_p.h" -#include -#include -#include #include "components/canimatedicon.h" -#include "utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#define TAB_BTNCLOSE(index) tabButton(index, QTabBar::RightSide) -#define TAB_ICON(index) tabButton(index, QTabBar::LeftSide) +#define ANIMATION_DEFAULT_MS 0 +#define ANIMATION_SCROLL_MS 60 +#define ANIMATION_MOVE_TAB_MS 500 +#define TABSPACING 0 +#define DEFAULT_ICON_SIZE QSize(16,16) +#define _tabRect(i) tabList[i]->geometry() +#define tabIndex(i) tabList[i]->index -inline static bool verticalTabs(QTabBar::Shape shape) + +class Tab : public QFrame { - return shape == QTabBar::RoundedWest || shape == QTabBar::RoundedEast - || shape == QTabBar::TriangularWest || shape == QTabBar::TriangularEast; + Q_OBJECT +public: + Tab(QWidget *parent = nullptr); + ~Tab(); + + void setText(const QString &text, Qt::TextElideMode mode = Qt::ElideRight); + void elideText(Qt::TextElideMode mode = Qt::ElideRight); + void setIcon(const QIcon &icon); + void polish(); + + QIcon *tab_icon = nullptr; + CAnimatedIcon *icon_label = nullptr; + QLabel *text_label = nullptr; + QToolButton *close_btn = nullptr; + QString text; + QString tabcolor; + int tab_width = -1; + int index = -1; + +signals: + void onTabWidthChanged(int width); + +protected: + virtual void resizeEvent(QResizeEvent*) final; + virtual void paintEvent(QPaintEvent*) override; + virtual bool eventFilter(QObject*, QEvent*) override; + +private: + CTabBar *tabBar = nullptr; +}; + +Tab::Tab(QWidget *parent) : + QFrame(parent), + tabcolor("none") +{ + setAttribute(Qt::WA_Hover); + installEventFilter(this); + setMinimumWidth(20); + tabBar = dynamic_cast(parent->parent()); + + QHBoxLayout *lut = new QHBoxLayout(this); + lut->setContentsMargins(6, 6, 6, 6); + lut->setSpacing(6); + setLayout(lut); + + icon_label = new CAnimatedIcon(this); + icon_label->setObjectName("tabIcon"); + icon_label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + icon_label->setMaximumSize(DEFAULT_ICON_SIZE); + lut->addWidget(icon_label); + + text_label = new QLabel(this); + text_label->setObjectName("tabText"); + text_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + lut->addWidget(text_label); + + close_btn = new QToolButton(this); + close_btn->setObjectName("tabButton"); + close_btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + close_btn->setMaximumSize(DEFAULT_ICON_SIZE); + lut->addWidget(close_btn); + show(); } -QMovableTabWidget::QMovableTabWidget(QWidget *parent) - : QWidget(parent) +Tab::~Tab() { + if (tab_icon) + delete tab_icon, tab_icon = nullptr; } -void QMovableTabWidget::paintEvent(QPaintEvent *e) +void Tab::setText(const QString &text, Qt::TextElideMode mode) { - Q_UNUSED(e); - QPainter p(this); - p.drawPixmap(0, 0, m_pixmap); + this->text = text; + elideText(mode); } -/* - * TabBarPrivate class description - * -*/ -void QTabBarPrivate::layoutTab(int index) +void Tab::elideText(Qt::TextElideMode mode) { - Q_Q(QTabBar); - Q_ASSERT(index >= 0); - - Tab &tab = tabList[index]; - bool vertical = verticalTabs(shape); - if (!(tab.leftWidget || tab.rightWidget)) - return; - - QStyleOptionTabV3 opt; - q->initStyleOption(&opt, index); - if (tab.leftWidget) { - QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabLeftButton, &opt, q); - QPoint p = rect.topLeft(); - if ((index == pressedIndex) || paintWithOffsets) { - if (vertical) - p.setY(p.y() + tabList[index].dragOffset); else - p.setX(p.x() + tabList[index].dragOffset); - } - tab.leftWidget->move(p); - } - if (tab.rightWidget) { - QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabRightButton, &opt, q); - QPoint p = rect.topLeft(); - if ((index == pressedIndex) || paintWithOffsets) { - if (vertical) - p.setY(p.y() + tab.dragOffset); - else - p.setX(p.x() + tab.dragOffset); - } - - tab.rightWidget->move(p); - } + const QMargins mrg = text_label->contentsMargins(); + const int padding = mrg.left() + mrg.right(); + const int width = text_label->maximumWidth() != QWIDGETSIZE_MAX ? text_label->maximumWidth() : text_label->width(); + QFontMetrics mtr(text_label->font()); + text_label->setText(mtr.elidedText(text, mode, width - padding - 1)); } -void QTabBarPrivate::layoutWidgets(int start) +void Tab::setIcon(const QIcon &icon) { - Q_Q(QTabBar); - - for (int i = start; i < q->count(); ++i) { - layoutTab(i); - } + if (tab_icon) + delete tab_icon, tab_icon = nullptr; + tab_icon = new QIcon(icon); + icon_label->setPixmap(tab_icon->pixmap(icon_label->size())); } -void QTabBarPrivate::slide(int from, int to) +void Tab::polish() { - Q_Q(QTabBar); - - if (from == to || !validIndex(from) || !validIndex(to)) - return; - - bool vertical = verticalTabs(shape); - int preLocation = vertical ? q->tabRect(from).y() : q->tabRect(from).x(); - q->setUpdatesEnabled(false); - q->moveTab(from, to); - q->setUpdatesEnabled(true); - int postLocation = vertical ? q->tabRect(to).y() : q->tabRect(to).x(); - int length = postLocation - preLocation; - tabList[to].dragOffset -= length; - tabList[to].startAnimation(this, ANIMATION_DURATION); + style()->polish(this); + icon_label->style()->polish(icon_label); + text_label->style()->polish(text_label); + close_btn->style()->polish(close_btn); } -void QTabBarPrivate::moveTabFinished(int index) +void Tab::resizeEvent(QResizeEvent *event) { - Q_Q(QTabBar); - - bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index); - bool allAnimationsFinished = true; -#ifndef QT_NO_ANIMATION - for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) { - const Tab &t = tabList.at(i); - if (t.animation && t.animation->state() == QAbstractAnimation::Running) - allAnimationsFinished = false; - } -#endif //QT_NO_ANIMATION - if (allAnimationsFinished && cleanup) { - if(movingTab) - movingTab->setVisible(false); // We might not get a mouse release - for (int i = 0; i < tabList.count(); ++i) { - tabList[i].dragOffset = 0; - } - if (pressedIndex != -1 && movable) { - pressedIndex = -1; - dragInProgress = false; - dragStartPosition = QPoint(); - } - layoutWidgets(); + QFrame::resizeEvent(event); + int new_width = event->size().width(); + if (tab_width < 0) { + tab_width = new_width; } else { - if (!validIndex(index)) - return; - tabList[index].dragOffset = 0; + if (tab_width != new_width) { + tab_width = new_width; + QTimer::singleShot(0, this, [=]() { + emit onTabWidthChanged(tab_width); + }); + } } - - q->update(); } -void QTabBarPrivate::setupMovableTab() +void Tab::paintEvent(QPaintEvent *ev) { - Q_Q(QTabBar); - - if (!movingTab) - movingTab = new QMovableTabWidget((QWidget *)q); - - int taboverlap = q->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 ,q); - QRect grabRect = q->tabRect(pressedIndex); - grabRect.adjust(-taboverlap, 0, taboverlap, 0); - - QPixmap grabImage(grabRect.size()); - grabImage.fill(Qt::transparent); - QStylePainter p(&grabImage, q); - p.initFrom(q); - - QStyleOptionTabV3 tab; - q->initStyleOption(&tab, pressedIndex); - tab.rect.moveTopLeft(QPoint(taboverlap, 0)); - - QString text = tab.text; - tab.text = ""; - p.drawControl(QStyle::CE_TabBarTab, tab); - ((CTabBar*)q)->fillTabColor(&p, tab, pressedIndex, ((CTabBar*)q)->m_activeColor); - ((CTabBar*)q)->drawTabCaption(&p, text, tab); - p.end(); - - QPalette pal; - pal.setBrush(QPalette::All, QPalette::Window, grabImage); - movingTab->setPalette(pal); - movingTab->setGeometry(grabRect); - movingTab->setAutoFillBackground(true); - movingTab->raise(); - - // Re-arrange widget order to avoid overlaps - if (tabList[pressedIndex].leftWidget) - tabList[pressedIndex].leftWidget->raise(); - if (tabList[pressedIndex].rightWidget) - tabList[pressedIndex].rightWidget->raise(); - if (leftB) leftB->raise(); - if (rightB) rightB->raise(); - - movingTab->setVisible(true); + QFrame::paintEvent(ev); + if (!tabcolor.isEmpty() && tabcolor != "none" && property("selected").toBool()) { + if (tabBar && tabBar->property("active").toBool() && !tabBar->ignoreActiveTabColor()) { + QStylePainter p(this); + p.fillRect(rect(), QBrush(QColor(tabcolor))); + } + } } -void QTabBarPrivate::moveTab(int index, int offset) +bool Tab::eventFilter(QObject *obj, QEvent *ev) { - if (!validIndex(index)) + switch (ev->type()) { + case QEvent::HoverEnter: + setProperty("hovered", true); + polish(); + break; + case QEvent::HoverLeave: + setProperty("hovered", false); + polish(); + break; + default: + break; + } + return QFrame::eventFilter(obj, ev); +} + + +class CTabBar::CTabBarPrivate +{ +public: + CTabBarPrivate(CTabBar* owner); + ~CTabBarPrivate(); + + enum Direction { + Left, Right + }; + + int getIntersectedOffset(int index); + int getIntersectedIndex(int direction, int &offsetX); + int getLayoutsIntersectedIndex(Tab *tab, int &offsetX); + int cellWidth(); + int nextTabPosByPrev(int index); +// int prevTabPosByNext(int index); + void slide(int from, int to, int offset, int animation_ms); + void scrollToDirection(int direction); + void scrollTo(int index); + void onCurrentChanged(int index); + void onTabWidthChanged(int width); + void changeScrollerState(); + void reorderIndexes(); + void recalcWidth(); + bool indexIsValid(int index); + + CTabBar* owner = nullptr; + QFrame* tabArea = nullptr; + QFrame* scrollFrame = nullptr; + QToolButton* leftButton = nullptr; + QToolButton* rightButton = nullptr; + QVector tabList; + QVector tabLayouts; + Qt::TextElideMode elideMode; + Tab* movedTab = nullptr; + bool lock = false; + bool isUIThemeDark = false; + bool ignore_tabcolor = false; + int animationInProgress = 0; + int movedTabPosX = 0; + int movedTabPressPosX = 0; + int movedTabIndex = -1; + int tab_width = -1; + int currentIndex = -1; + QSize iconSize; +}; + +CTabBar::CTabBarPrivate::CTabBarPrivate(CTabBar* owner) : + owner(owner), + elideMode(Qt::ElideRight), + iconSize(DEFAULT_ICON_SIZE) +{ + +} + +CTabBar::CTabBarPrivate::~CTabBarPrivate() +{} + +int CTabBar::CTabBarPrivate::getIntersectedOffset(int index) +{ + if (indexIsValid(index)) { + QRect tabRect = _tabRect(index); + if (!tabArea->rect().contains(tabRect) && tabArea->rect().intersects(tabRect)) { + QRect interRect = tabArea->rect().intersected(tabRect); + int sign = (interRect.x() == 0) ? -1 : 1; + return sign * (cellWidth() - interRect.width()); + } + } + return 0; +} + +int CTabBar::CTabBarPrivate::getIntersectedIndex(int direction, int &offsetX) +{ + offsetX = 0; + for (int i = 0; i < tabList.size(); i++) { + QRect tabRect = _tabRect(i); + if (!tabArea->rect().contains(tabRect) && tabArea->rect().intersects(tabRect)) { + QRect interRect = tabArea->rect().intersected(tabRect); + if ((direction == Direction::Left && interRect.x() != 0) + || (direction == Direction::Right && interRect.x() == 0)) { + offsetX = cellWidth() - interRect.width(); + return i; + } + } + } + return -1; +} + +int CTabBar::CTabBarPrivate::getLayoutsIntersectedIndex(Tab *tab, int &offsetX) +{ + offsetX = 0; + QRect tabRect = tab->geometry(); + for (int i = 0; i < tabLayouts.size(); i++) { + if (i != tab->index && tabRect.intersects(tabLayouts[i])) { + QRect interRect = tabRect.intersected(tabLayouts[i]); + int sign = (tabRect.x() < tabLayouts[i].x()) ? -1 : 1; + offsetX = sign * interRect.width(); + return i; + } + } + return -1; +} + +int CTabBar::CTabBarPrivate::cellWidth() +{ + Q_ASSERT(!tabList.isEmpty()); + return tabList[0]->width() + TABSPACING; +} + +//int CTabBar::CTabBarPrivate::prevTabPosByNext(int index) +//{ +// Q_ASSERT(index > -1 && index < tabList.size()); +// return tabRect(index).left() - cellWidth() - 1; +//} + +int CTabBar::CTabBarPrivate::nextTabPosByPrev(int index) +{ + Q_ASSERT(index > -1 && index < tabList.size()); + return _tabRect(index).right() + TABSPACING + 1; +} + +void CTabBar::CTabBarPrivate::slide(int from, int to, int offset, int animation_ms) +{ + animationInProgress++; + QParallelAnimationGroup *group = new QParallelAnimationGroup; + for (int i = from; i <= to; i++) { + QPropertyAnimation* animation = new QPropertyAnimation(tabList[i], "pos"); + animation->setDuration(animation_ms); + animation->setStartValue(tabList[i]->pos()); + animation->setEndValue(tabList[i]->pos() + QPoint(offset, 0)); + animation->setEasingCurve(QEasingCurve::InOutQuad); + group->addAnimation(animation); + } + QObject::connect(group, &QParallelAnimationGroup::finished, qApp, [=]() { + changeScrollerState(); + }); + QObject::connect(group, &QParallelAnimationGroup::stateChanged, qApp, + [=](QAbstractAnimation::State newState, QAbstractAnimation::State) { + if (newState == QAbstractAnimation::Stopped) + animationInProgress--; + }); + group->start(QParallelAnimationGroup::DeleteWhenStopped); +} + +void CTabBar::CTabBarPrivate::scrollToDirection(int direction) +{ + while (animationInProgress) + qApp->processEvents(); + + if (tabList.isEmpty()) return; - tabList[index].dragOffset = offset; - layoutTab(index); // Make buttons follow tab - q_func()->update(); -} - - -void QTabBarPrivate::Tab::TabBarAnimation::updateCurrentValue(const QVariant ¤t) -{ - priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); -} - -void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State, QAbstractAnimation::State newState) -{ - if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); -} - -/* - * CTabBar descrition -*/ -CTabBar::CTabBar(QWidget * parent) - : QTabBar(parent) - , CScalingWrapper(parent) - , m_scrollPos(0) -{ - hide(); - setDrawBase(false); - - if (Utils::getScreenDpiRatio( - QApplication::desktop()->screen(QApplication::desktop()->primaryScreen())->geometry().topLeft()) > 1) - { - setProperty("scroll", "var2"); + const int supIndex = (direction == Direction::Left) ? tabList.size() - 1 : 0; + if (!tabArea->rect().contains(_tabRect(supIndex))) { + int offsetX; + int ind = getIntersectedIndex(direction, offsetX); + int offset = (ind != -1) ? offsetX : cellWidth(); + if (direction == Direction::Left) + offset *= -1; + slide(0, tabList.size() - 1, offset, ANIMATION_SCROLL_MS); } +} - connect(this, &QTabBar::currentChanged, this, &CTabBar::onCurrentChanged); - connect(this, &QTabBar::tabMoved, this, [=](){ - m_tabWasMoved = true; +void CTabBar::CTabBarPrivate::scrollTo(int index) +{ + while (animationInProgress) + qApp->processEvents(); + + if (!indexIsValid(index)) + return; + + if (!tabArea->rect().contains(_tabRect(index))) { + int x = _tabRect(index).x(); + int offsetX = (x > 0) ? x - tabArea->width() + cellWidth() : x; + slide(0, tabList.size() - 1, -1 * offsetX, ANIMATION_DEFAULT_MS); + } else { + changeScrollerState(); + } +} + +void CTabBar::CTabBarPrivate::onCurrentChanged(int index) +{ + while (animationInProgress) + qApp->processEvents(); + recalcWidth(); + scrollTo(index); + currentIndex = index; + for (int i = 0; i < tabList.size(); i++) { + tabList[i]->setProperty("selected", i == index); + tabList[i]->polish(); + } + emit owner->currentChanged(index); +} + +void CTabBar::CTabBarPrivate::onTabWidthChanged(int width) +{ + Q_UNUSED(width) + while (animationInProgress) + qApp->processEvents(); + + if (!tabList.isEmpty()) + iconSize = tabList[0]->icon_label->size(); + + for (int i = 0; i < tabList.size(); i++) { + int posX = i * cellWidth(); + tabList[i]->move(posX, 0); + + if (QIcon *icon = tabList[i]->tab_icon) + tabList[i]->icon_label->setPixmap(icon->pixmap(iconSize)); + + tabList[i]->elideText(elideMode); + } + recalcWidth(); + scrollTo(currentIndex); +} + +void CTabBar::CTabBarPrivate::changeScrollerState() +{ + bool allowScroll = false; + for (int i = 0; i < tabList.size(); i++) { + if (_tabRect(i).x() + 1 < 0) { + allowScroll = true; + break; + } + } + leftButton->setEnabled(allowScroll); + + allowScroll = false; + for (int i = 0; i < tabList.size(); i++) { + if (_tabRect(i).right() + TABSPACING > tabArea->rect().right()) { + allowScroll = true; + break; + } + } + rightButton->setEnabled(allowScroll); +} + +void CTabBar::CTabBarPrivate::reorderIndexes() +{ + QVector dupTabList = tabList; + for (int i = 0; i < tabList.size(); i++) { + if (tabIndex(i) != i) { + for (int j = 0; j < tabList.size(); j++) { + if (j != i && dupTabList[j]->index == i) { + tabList[i] = dupTabList[j]; + break; + } + } + } + } +} + +void CTabBar::CTabBarPrivate::recalcWidth() +{ + int minWidth = (tabList.isEmpty()) ? 0 : cellWidth(); + tabArea->setMinimumWidth(minWidth); + tabArea->setMaximumWidth(minWidth * tabList.size()); + owner->setMaximumWidth(tabArea->maximumWidth() + scrollFrame->maximumWidth()); + qApp->processEvents(); +} + +bool CTabBar::CTabBarPrivate::indexIsValid(int index) +{ + return index > -1 && index < tabList.size(); +} + + +CTabBar::CTabBar(QWidget *parent) : + QFrame(parent), + d(new CTabBarPrivate(this)) +{ + installEventFilter(this); + QHBoxLayout *main_layout = new QHBoxLayout(this); + main_layout->setAlignment(Qt::AlignLeft); + main_layout->setContentsMargins(0,0,0,0); + main_layout->setSpacing(0); + d->tabArea = new QFrame(this); + d->tabArea->setObjectName("tabArea"); + d->tabArea->installEventFilter(this); + d->tabArea->setMaximumWidth(0); + d->tabArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + main_layout->addWidget(d->tabArea); + setMinimumWidth(0); + setMaximumWidth(0); + + d->scrollFrame = new QFrame(this); + d->scrollFrame->setObjectName("tabScroll"); + QHBoxLayout *scrollLayout = new QHBoxLayout(d->scrollFrame); + scrollLayout->setSpacing(0); + scrollLayout->setContentsMargins(0,0,0,0); + d->scrollFrame->setLayout(scrollLayout); + + d->leftButton = new QToolButton(d->scrollFrame); + d->rightButton = new QToolButton(d->scrollFrame); + d->leftButton->setObjectName("leftButton"); + d->rightButton->setObjectName("rightButton"); + + scrollLayout->addWidget(d->leftButton); + scrollLayout->addWidget(d->rightButton); + d->leftButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + d->rightButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + main_layout->addWidget(d->scrollFrame); + connect(d->leftButton, &QToolButton::clicked, this, [=]() { + d->scrollToDirection(d->Direction::Right); }); + connect(d->rightButton, &QToolButton::clicked, this, [=]() { + d->scrollToDirection(d->Direction::Left); + }); + + show(); + d->leftButton->hide(); + d->rightButton->hide(); + d->leftButton->setEnabled(false); + d->rightButton->setEnabled(false); } CTabBar::~CTabBar() { - + delete d, d = nullptr; } -void CTabBar::initCustomScroll(QFrame *_pScrollerFrame, - QToolButton *_pLeftButton, - QToolButton *_pRightButton) +int CTabBar::addTab(const QString &text) { - // Bypassing the bug with tab scroller - m_pScrollerFrame = _pScrollerFrame; - m_pLeftButton = _pLeftButton; - m_pRightButton = _pRightButton; - m_pScrollerFrame->show(); - m_pScrollerFrame->raise(); - m_pLeftButton->show(); - m_pLeftButton->raise(); - m_pRightButton->show(); - m_pRightButton->raise(); - m_pScrollerFrame->setVisible(false); - connect(m_pLeftButton, &QToolButton::clicked, this, [=](){ - Q_D(QTabBar); - d->leftB->click(); - m_scrollPos = d->scrollOffset; - changeCustomScrollerState(); + while (d->animationInProgress) + qApp->processEvents(); + + const int lastIndex = d->tabList.size() - 1; + const int posX = (lastIndex == -1) ? 0 : d->nextTabPosByPrev(lastIndex); + Tab *tab = new Tab(d->tabArea); + tab->move(posX, 0); + tab->setFixedHeight(d->tabArea->height()); + tab->setText(text, d->elideMode); + if (tab->icon_label->minimumSize().isNull()) { + tab->icon_label->setBaseSize(d->iconSize); + tab->icon_label->setFixedSize(d->iconSize); + } + tab->index = lastIndex + 1; + d->tabList.append(tab); + connect(tab->close_btn, &QToolButton::clicked, this, [=]() { + emit tabCloseRequested(tab->index); }); - connect(m_pRightButton, &QToolButton::clicked, this, [=](){ - Q_D(QTabBar); - d->rightB->click(); - m_scrollPos = d->scrollOffset; - changeCustomScrollerState(); - }); // End bypassing the bug + connect(tab, &Tab::onTabWidthChanged, this, [=](int width) { + if (d->tab_width != width) { + d->tab_width = width; + d->onTabWidthChanged(width); + } + }); + tabInserted(lastIndex + 1); + d->onCurrentChanged(lastIndex + 1); + return d->currentIndex; } -void CTabBar::mouseMoveEvent(QMouseEvent * event) +int CTabBar::addTab(const QIcon &icon, const QString &text) { - Q_D(QTabBar); - this->setCursor(QCursor(Qt::ArrowCursor)); - if (verticalTabs(d->shape)) { - QTabBar::mouseMoveEvent(event); + const int index = addTab(text); + setTabIcon(index, icon); + return index; +} + +int CTabBar::count() const +{ + return d->tabList.size(); +} + +int CTabBar::currentIndex() const +{ + return d->currentIndex; +} + +Qt::TextElideMode CTabBar::elideMode() const +{ + return d->elideMode; +} + +QSize CTabBar::iconSize() const +{ + return d->iconSize; +} + +int CTabBar::insertTab(int index, const QString &text) +{ + while (d->animationInProgress) + qApp->processEvents(); + + if (!d->indexIsValid(index)) + return addTab(text); + + while (d->animationInProgress) + qApp->processEvents(); + + int posX = d->_tabRect(index).left(); + d->slide(index, d->tabList.size() - 1, d->cellWidth(), ANIMATION_DEFAULT_MS); + while (d->animationInProgress) + qApp->processEvents(); + + Tab *tab = new Tab(d->tabArea); + tab->move(posX, 0); + tab->setFixedHeight(d->tabArea->height()); + tab->setText(text, d->elideMode); + if (tab->icon_label->minimumSize().isNull()) { + tab->icon_label->setBaseSize(d->iconSize); + tab->icon_label->setFixedSize(d->iconSize); + } + d->tabList.insert(index, tab); + for (int i = index; i < d->tabList.size(); i++) + d->tabIndex(i) = i; + + connect(tab->close_btn, &QToolButton::clicked, this, [=]() { + emit tabCloseRequested(tab->index); + }); + connect(tab, &Tab::onTabWidthChanged, this, [=](int width) { + if (d->tab_width != width) { + d->tab_width = width; + d->onTabWidthChanged(width); + } + }); + tabInserted(index); + d->onCurrentChanged(index); + return d->currentIndex; +} + +int CTabBar::insertTab(int index, const QIcon &icon, const QString &text) +{ + const int actual_index = insertTab(index, text); + setTabIcon(actual_index, icon); + return actual_index; +} + +void CTabBar::moveTab(int from, int to) +{ + while (d->animationInProgress) + qApp->processEvents(); + + if (from == to || !d->indexIsValid(from) || !d->indexIsValid(to)) return; - } - if (d->movable) { - // Be safe! - if (d->pressedIndex != -1 && event->buttons() == Qt::NoButton) - d->moveTabFinished(d->pressedIndex); + int posX = d->_tabRect(from).x(); + d->tabList[from]->move(d->_tabRect(to).x(), 0); + d->tabList[to]->move(posX, 0); + int from_index = d->tabIndex(from); + d->tabIndex(from) = d->tabIndex(to); + d->tabIndex(to) = from_index; + Tab *from_tab = d->tabList[from]; + d->tabList[from] = d->tabList[to]; + d->tabList[to] = from_tab; + d->scrollTo(to); + emit tabMoved(from, to); +} - // Start drag - if (!d->dragInProgress && d->pressedIndex != -1) { - if ((event->pos() - d->dragStartPosition).manhattanLength() > QApplication::startDragDistance()) { - d->dragInProgress = true; - d->setupMovableTab(); - } - } +void CTabBar::removeTab(int index) +{ + while (d->animationInProgress) + qApp->processEvents(); - int offset = (event->pos() - d->dragStartPosition).manhattanLength(); - if (event->buttons() == Qt::LeftButton - && offset > QApplication::startDragDistance() && d->validIndex(d->pressedIndex)) { - if ( abs(event->pos().y() - d->dragStartPosition.y()) > 30 ) { - bool isaccepted = false; - emit tabUndock(d->pressedIndex, &isaccepted); - - if (isaccepted) - interruptTabMoving(d->pressedIndex); - return; - } - - int dragDistance = (event->pos().x() - d->dragStartPosition.x()); - - if ((d->pressedIndex == 0 && dragDistance < 0) || - (d->pressedIndex + 1 == count() && dragDistance > 0)) - { - dragDistance = 0; - } - - d->tabList[d->pressedIndex].dragOffset = dragDistance; - - QRect startingRect = tabRect(d->pressedIndex); - startingRect.moveLeft(startingRect.x() + dragDistance); - - int overIndex; - if (dragDistance < 0) - overIndex = tabAt(startingRect.topLeft()); else - overIndex = tabAt(startingRect.topRight()); - - if (overIndex != d->pressedIndex && overIndex != -1) { - int offset = 1; - if (isRightToLeft()) offset *= -1; - if (dragDistance < 0) { - dragDistance *= -1; - offset *= -1; - } - for (int i = d->pressedIndex; - offset > 0 ? i < overIndex : i > overIndex; - i += offset) { - QRect overIndexRect = tabRect(overIndex); - int needsToBeOver = overIndexRect.width() / 2; - if (dragDistance > needsToBeOver) - d->slide(i + offset, d->pressedIndex); - } - } - - // Buttons needs to follow the dragged tab - d->layoutTab(d->pressedIndex); - - update(); - } - } - - if (event->buttons() != Qt::LeftButton) { - event->ignore(); + if (!d->indexIsValid(index)) return; - } - QStyleOptionTabBarBaseV2 optTabBase; - optTabBase.init(this); - optTabBase.documentMode = d->documentMode; -} - -void CTabBar::mousePressEvent(QMouseEvent * e) -{ - QCoreApplication::postEvent(parent(), new QEvent(QEvent::MouseButtonPress)); - if ( e->button() == Qt::LeftButton ) { - QTabBar::mousePressEvent(e); -// if ( count() == 1 ) e->ignore(); - } else e->ignore(); -} - -void CTabBar::mouseReleaseEvent(QMouseEvent * e) -{ - QTabBar::mouseReleaseEvent(e); - releaseMouse(); - if (e->button() == Qt::MiddleButton) - onCloseButton(); - if (m_tabWasMoved) { - m_tabWasMoved = false; - int ind = currentIndex(); - if (ind > 0) { - blockSignals(true); - setCurrentIndex(ind - 1); - setCurrentIndex(ind); - blockSignals(false); - changeCustomScrollerState(); + d->tabList[index]->hide(); + if (d->_tabRect(0).x() <= d->tabArea->x() - d->cellWidth()) { + const int prevIndex = index - 1; + if (prevIndex > -1) { + d->slide(0, prevIndex, d->cellWidth(), ANIMATION_DEFAULT_MS); + while (d->animationInProgress) + qApp->processEvents(); } - } -} - -void CTabBar::wheelEvent(QWheelEvent *event) -{ - QTabBar::wheelEvent(event); - emit onCurrentChangedByWhell(currentIndex()); -} - -void CTabBar::drawTabCaption(QPainter * p, const QString& s, const QStyleOptionTab& t) -{ - if ( m_usePalette ) { - if ( m_palette.currentColorGroup() != QPalette::Disabled && - t.state & QStyle::State_Selected /*|| t.state & QStyle::State_MouseOver*/ ) - p->setPen( QPen(m_palette.color(QPalette::Active, QPalette::ButtonText))); - else p->setPen( QPen(m_palette.color(QPalette::Inactive, QPalette::ButtonText))); } else { - p->setPen(QPen(t.palette.foreground().color())); - } - - QPoint _lt = QPoint(15, 0) * scaling(); - QPoint _rb = QPoint(-22, -2) * scaling(); - - QRect trect(t.rect.topLeft() + QPoint(t.iconSize.width(), 0) + _lt, - t.rect.bottomRight() + _rb); - -// QFont f = font(); -// f.setPointSize(8); - -// p->setFont(f); - - QString es = fontMetrics().elidedText(s, Qt::ElideRight, trect.width(), Qt::TextShowMnemonic); - p->drawText(trect, Qt::AlignVCenter, es); -} - -void CTabBar::paintEvent(QPaintEvent * event) -{ - Q_D(QTabBar); - -#ifdef _QTVER_DOWNGRADE - if (verticalTabs(d->shape)) { - QTabBar::paintEvent(event); - return; - } - - QStyleOptionTabBarBaseV2 optTabBase; - QTabBarPrivate::initStyleBaseOption(&optTabBase, this, size()); - - QStylePainter p(this); - int selected = -1; - int cut = -1; - bool rtl = optTabBase.direction == Qt::RightToLeft; - QStyleOptionTab cutTab; - selected = d->currentIndex; - if (d->dragInProgress) - selected = d->pressedIndex; - - for (int i = 0; i < d->tabList.count(); ++i) - optTabBase.tabBarRect |= tabRect(i); - - optTabBase.selectedTabRect = tabRect(selected); - - if (d->drawBase) - p.drawPrimitive(QStyle::PE_FrameTabBarBase, optTabBase); - - for (int i = 0; i < d->tabList.count(); ++i) { - QStyleOptionTabV3 tab; - initStyleOption(&tab, i); - - if (d->paintWithOffsets && d->tabList[i].dragOffset != 0) { - tab.rect.moveLeft(tab.rect.x() + d->tabList[i].dragOffset); - } - if (!(tab.state & QStyle::State_Enabled)) { - tab.palette.setCurrentColorGroup(QPalette::Disabled); - } - // If this tab is partially obscured, make a note of it so that we can pass the information - // along when we draw the tear. - if ((!rtl && tab.rect.left() < 0) || (rtl && tab.rect.right() > width())) { - cut = i; - cutTab = tab; - } - // Don't bother drawing a tab if the entire tab is outside of the visible tab bar. - if (tab.rect.right() < 0 || tab.rect.left() > width()) - continue; - - optTabBase.tabBarRect |= tab.rect; - if (i == selected) - continue; - - QString text(tab.text); - tab.text.clear(); - p.drawControl(QStyle::CE_TabBarTab, tab); - drawTabCaption(&p, text, tab); - } - - // Draw the selected tab last to get it "on top" - if (selected >= 0) { - QStyleOptionTabV3 tab; - initStyleOption(&tab, selected); - - if (d->paintWithOffsets && d->tabList[selected].dragOffset != 0) { - tab.rect.moveLeft(tab.rect.x() + d->tabList[selected].dragOffset); - } - if (!d->dragInProgress) { - QString text(tab.text); - tab.text.clear(); - p.drawControl(QStyle::CE_TabBarTab, tab); - - if ( m_activeColor != "none" ) - fillTabColor(&p, tab, selected, m_activeColor); - drawTabCaption(&p, text, tab); - } else { - int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0, this); - d->movingTab->setGeometry(tab.rect.adjusted(-taboverlap, 0, taboverlap, 0)); + const int nextIndex = index + 1; + if (nextIndex < d->tabList.size()) { + d->slide(nextIndex, d->tabList.size() - 1, -1 * d->cellWidth(), ANIMATION_DEFAULT_MS); + while (d->animationInProgress) + qApp->processEvents(); } } - // Only draw the tear indicator if necessary. Most of the time we don't need too. - if (d->leftB->isVisible() && cut >= 0) { - cutTab.rect = rect(); - cutTab.rect = style()->subElementRect(QStyle::SE_TabBarTearIndicator, &cutTab, this); - p.drawPrimitive(QStyle::PE_IndicatorTabTear, cutTab); - } -#else - QStyleOptionTabBarBase optTabBase; - QTabBarPrivate::initStyleBaseOption(&optTabBase, this, size()); + delete d->tabList[index]; + d->tabList.remove(index); + for (int i = index; i < d->tabList.size(); i++) + d->tabIndex(i) = i; - QStylePainter p(this); - int selected = -1; - int cutLeft = -1; - int cutRight = -1; - bool vertical = verticalTabs(d->shape); - QStyleOptionTab cutTabLeft; - QStyleOptionTab cutTabRight; - selected = d->currentIndex; - if (d->dragInProgress) - selected = d->pressedIndex; - QRect scrollRect = d->normalizedScrollRect(); - - for (int i = 0; i < d->tabList.count(); ++i) - optTabBase.tabBarRect |= tabRect(i); - - optTabBase.selectedTabRect = tabRect(selected); - - if (d->drawBase) - p.drawPrimitive(QStyle::PE_FrameTabBarBase, optTabBase); - - for (int i = 0; i < d->tabList.count(); ++i) { - QStyleOptionTab tab; - initStyleOption(&tab, i); - if (d->paintWithOffsets && d->tabList[i].dragOffset != 0) { - if (vertical) { - tab.rect.moveTop(tab.rect.y() + d->tabList[i].dragOffset); + if (d->currentIndex > 0) { + if (index > 0) { + if (d->currentIndex > index) { + d->onCurrentChanged(d->currentIndex - 1); + } else + if (d->currentIndex < index) { + d->recalcWidth(); } else { - tab.rect.moveLeft(tab.rect.x() + d->tabList[i].dragOffset); + const int initialMaxIndex = d->tabList.size(); // max index before deletion + if (index < initialMaxIndex) { + d->onCurrentChanged(index); + } else { + d->onCurrentChanged(initialMaxIndex - 1); + } + } + } else { + d->onCurrentChanged(d->currentIndex - 1); + } + } else { + if (index > 0) { + d->recalcWidth(); + } else { + const int initialMaxIndex = d->tabList.size(); // max index before deletion + if (index < initialMaxIndex) { + d->onCurrentChanged(index); + } else { + d->onCurrentChanged(-1); } } - if (!(tab.state & QStyle::State_Enabled)) { - tab.palette.setCurrentColorGroup(QPalette::Disabled); - } - - // If this tab is partially obscured, make a note of it so that we can pass the information - // along when we draw the tear. - QRect tabRect = d->tabList[i].rect; - int tabStart = vertical ? tabRect.top() : tabRect.left(); - int tabEnd = vertical ? tabRect.bottom() : tabRect.right(); - if (tabStart < scrollRect.left() + d->scrollOffset) { - cutLeft = i; - cutTabLeft = tab; - } else if (tabEnd > scrollRect.right() + d->scrollOffset) { - cutRight = i; - cutTabRight = tab; - } - - // Don't bother drawing a tab if the entire tab is outside of the visible tab bar. - if ((!vertical && (tab.rect.right() < 0 || tab.rect.left() > width())) - || (vertical && (tab.rect.bottom() < 0 || tab.rect.top() > height()))) - continue; - - optTabBase.tabBarRect |= tab.rect; - if (i == selected) - continue; - - QString text(tab.text); - tab.text.clear(); - p.drawControl(QStyle::CE_TabBarTab, tab); - drawTabCaption(&p, text, tab); - } - - // Draw the selected tab last to get it "on top" - if (selected >= 0) { - QStyleOptionTab tab; - initStyleOption(&tab, selected); - if (d->paintWithOffsets && d->tabList[selected].dragOffset != 0) { - if (vertical) - tab.rect.moveTop(tab.rect.y() + d->tabList[selected].dragOffset); - else - tab.rect.moveLeft(tab.rect.x() + d->tabList[selected].dragOffset); - } - if (!d->dragInProgress) { - QString text(tab.text); - tab.text.clear(); - p.drawControl(QStyle::CE_TabBarTab, tab); - - if ( m_activeColor != "none" ) - fillTabColor(&p, tab, selected, m_activeColor); - drawTabCaption(&p, text, tab); - } else { - int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0, this); - if (verticalTabs(d->shape)) - d->movingTab->setGeometry(tab.rect.adjusted(0, -taboverlap, 0, taboverlap)); - else - d->movingTab->setGeometry(tab.rect.adjusted(-taboverlap, 0, taboverlap, 0)); - } - } - - // Only draw the tear indicator if necessary. Most of the time we don't need too. - if (d->leftB->isVisible() && cutLeft >= 0) { - cutTabLeft.rect = rect(); - cutTabLeft.rect = style()->subElementRect(QStyle::SE_TabBarTearIndicatorLeft, &cutTabLeft, this); - p.drawPrimitive(QStyle::PE_IndicatorTabTearLeft, cutTabLeft); - } - - if (d->rightB->isVisible() && cutRight >= 0) { - cutTabRight.rect = rect(); - cutTabRight.rect = style()->subElementRect(QStyle::SE_TabBarTearIndicatorRight, &cutTabRight, this); - p.drawPrimitive(QStyle::PE_IndicatorTabTearRight, cutTabRight); - } -#endif - -} - -void CTabBar::resizeEvent(QResizeEvent *event) -{ - QTabBar::resizeEvent(event); - Q_D(QTabBar); - m_scrollPos = d->scrollOffset; - changeCustomScrollerState(); -} - -void CTabBar::fillTabColor(QPainter * p, const QStyleOptionTab& tab, uint index, const QColor& color) -{ - int border_width = scaling() > 1 ? 2 : 1; - - QRect tabRect(tab.rect); - tabRect.adjust(-border_width, 0, 0, 0); - p->fillRect( tabRect, QBrush(QColor(color)) ); - - if ( !tabData(index).isNull() && tabData(index).toInt() == TabTheme::LightTab ) { - if ( !m_isUIThemeDark ) { - QPen _pen = p->pen(); - _pen.setColor(QColor("#a5a5a5")); - _pen.setWidth(border_width); - - p->setPen(_pen); - p->drawLine(tabRect.bottomLeft(), tabRect.topLeft()); - p->drawLine(tabRect.bottomRight(), tabRect.topRight()); - } } } -void CTabBar::setTabTextColor(QPalette::ColorGroup group, const QColor& color) +void CTabBar::setElideMode(Qt::TextElideMode mode) { - m_usePalette = true; - m_palette.setColor(group, QPalette::ButtonText, color); + d->elideMode = mode; } -QPalette& CTabBar::customColors() +void CTabBar::setIconSize(const QSize &size) { - return m_palette; -} - -QVariant CTabBar::tabProperty(int index, const char *name) -{ - auto *wgt = tabButton(index, QTabBar::RightSide); - if (!wgt) - wgt = tabButton(index, QTabBar::LeftSide); - if (wgt) - return wgt->property(name); - return QVariant(); -} - -void CTabBar::setTabProperty(int index, const char *name, const QVariant &value) -{ - auto *wgt = tabButton(index, QTabBar::RightSide); - if (!wgt) - wgt = tabButton(index, QTabBar::LeftSide); - if (wgt) - wgt->setProperty(name, value); -} - -void CTabBar::setUseTabCustomPalette(bool use) -{ - m_usePalette = use; -} - -void CTabBar::tabInserted(int index) -{ - QToolButton * close = new QToolButton(this); - close->setProperty("class", "tab-close"); - close->setFocusPolicy(Qt::NoFocus); - close->setFixedSize( QSize(16, 16) * scaling() ); - if ( index == currentIndex() ) - close->setProperty("state", "active"); else - close->hide(); - - connect(close, &QToolButton::clicked, this, &CTabBar::onCloseButton); - setTabButton(index, QTabBar::RightSide, close); - - CAnimatedIcon * icon = new CAnimatedIcon(this); - icon->setFixedSize(iconSize()); - setTabButton(index, QTabBar::LeftSide, icon); - - QTabBar::tabInserted(index); -} - -void CTabBar::onCurrentChanged(int index) -{ - Q_D(QTabBar); - m_scrollPos = d->scrollOffset; - if (this->count() == 0) { - this->hide(); - } else if (this->isHidden()) { - this->show(); + d->iconSize = size; + for (int i = 0; i < d->tabList.size(); i++) { + if (d->tabList[i]->icon_label->baseSize().isNull()) + break; + d->tabList[i]->icon_label->setBaseSize(size); + d->tabList[i]->icon_label->setFixedSize(size); + if (QIcon *icon = d->tabList[i]->tab_icon) + d->tabList[i]->icon_label->setPixmap(icon->pixmap(d->iconSize)); } - - QWidget * b = TAB_BTNCLOSE(m_current); -// if ( tabData(m_current).isNull() ) - { - if ( b ) { - b->hide(); -// b->setProperty("state", "normal"); -// b->style()->polish(b); - } - } - -// if ( tabData(index).isNull() ) - { - b = TAB_BTNCLOSE(index); - if ( b ) { - b->show(); -// b->setProperty("state", "active"); -// b->style()->polish(b); - } - } - - m_current = index; - changeCustomScrollerState(); } -void CTabBar::changeCustomScrollerState() +void CTabBar::setTabIconLabel(int index, QWidget *widget) { - // Bypassing the bug with tab scroller - Q_D(QTabBar); - if (m_pScrollerFrame && m_pLeftButton && m_pRightButton) { - if (d->leftB->isVisible()) { - m_pScrollerFrame->setVisible(true); - } else { - m_pScrollerFrame->setVisible(false); - } - if (d->leftB->isEnabled()) { - m_pLeftButton->setEnabled(true); - } else { - m_pLeftButton->setEnabled(false); - } - if (d->rightB->isEnabled()) { - m_pRightButton->setEnabled(true); - } else { - m_pRightButton->setEnabled(false); - } + if (!d->indexIsValid(index)) + return; + if (CAnimatedIcon *icon_label = dynamic_cast(widget)) { + Tab *tab = d->tabList[index]; + if (tab->icon_label) + delete tab->icon_label; + tab->icon_label = icon_label; + icon_label->setParent(tab); + icon_label->setObjectName("tabIcon"); + icon_label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + icon_label->setMaximumSize(DEFAULT_ICON_SIZE); + if (QHBoxLayout *lut = dynamic_cast(tab->layout())) + lut->insertWidget(0, icon_label); + icon_label->style()->polish(icon_label); } - // End bypassing the bug } -void CTabBar::tabRemoved(int index) +void CTabBar::setTabButton(int index, QWidget *widget) { - QWidget * i = TAB_ICON(index); - if ( i ) { -// qDebug() << "tab removed: " << index; - } else { -// qDebug() << "tab already removed: " << index; + if (!d->indexIsValid(index)) + return; + if (QToolButton *close_btn = dynamic_cast(widget)) { + Tab *tab = d->tabList[index]; + if (tab->close_btn) + delete tab->close_btn; + tab->close_btn = close_btn; + close_btn->setParent(tab); + close_btn->setObjectName("tabButton"); + close_btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + close_btn->setMaximumSize(DEFAULT_ICON_SIZE); + connect(close_btn, &QToolButton::clicked, this, [=]() { + emit tabCloseRequested(tab->index); + }); + if (QHBoxLayout *lut = dynamic_cast(tab->layout())) + lut->insertWidget(2, close_btn); + close_btn->style()->polish(close_btn); } - - QTabBar::tabRemoved(index); } +//void CTabBar::setTabData(int index, const QVariant &data) +//{ +// if (d->indexIsValid(index)) +// d->tabList[index]->setProperty("TabData", data); +//} + void CTabBar::setTabIcon(int index, const QIcon &icon) { - QWidget * i = TAB_ICON(index); - if ( i ) { - QSize _iconSize = iconSize(); - QRect _tabRect = tabRect(index); - int _top = (_tabRect.height() - _iconSize.height()) / 2; - double dpi_ratio = scaling(); + if (d->indexIsValid(index)) + d->tabList[index]->setIcon(icon); +} - ((CAnimatedIcon *)i)->setPixmap(icon.pixmap(_iconSize)); - int top_offset{1}; - if (dpi_ratio < 1.25) top_offset = 1; else - if (dpi_ratio < 1.5) top_offset = 2; else - if (dpi_ratio < 1.75) top_offset = 2; else - if (dpi_ratio < 2) top_offset = 3; else - if (dpi_ratio < 2.5) top_offset = 4; else - if (dpi_ratio < 3) top_offset = 5; else - if (dpi_ratio < 3.5) top_offset = 5; else - if (dpi_ratio < 4) top_offset = 6; else - if (dpi_ratio < 4.5) top_offset = 8; else - if (dpi_ratio < 5) top_offset = 9; else - top_offset = 9; +void CTabBar::setTabText(int index, const QString &text) +{ + if (d->indexIsValid(index)) + d->tabList[index]->setText(text); +} - i->setGeometry(QRect(QPoint(_tabRect.left() + 4, _top - top_offset),_iconSize)); - i->setFixedSize(_iconSize.width() + int(8 * dpi_ratio), iconSize().height() + int(4 * dpi_ratio)); +void CTabBar::setTabToolTip(int index, const QString &text) +{ + if (d->indexIsValid(index)) { + d->tabList[index]->setProperty("ToolTip", text); + d->tabList[index]->icon_label->setProperty("ToolTip", text); + d->tabList[index]->text_label->setProperty("ToolTip", text); + d->tabList[index]->close_btn->setProperty("ToolTip", text); + } +} - update(_tabRect); +void CTabBar::setCurrentIndex(int index) +{ + while (d->animationInProgress) + qApp->processEvents(); + if (!d->indexIsValid(index) || index == d->currentIndex) + return; + d->onCurrentChanged(index); +} + +void CTabBar::setActiveTabColor(int index, const QString& color) +{ + if (!d->indexIsValid(index) || color == "none") + return; + if (d->tabList[index]->tabcolor != color) { + d->tabList[index]->tabcolor = color; + d->tabList[index]->polish(); + } +} + +void CTabBar::setUseTabCustomPalette(int index, bool use) +{ + if (d->indexIsValid(index)) { + if (d->tabList[index]->property("custom").toBool() != use) { + d->tabList[index]->setProperty("custom", use); + polish(); + } } } void CTabBar::setTabLoading(int index, bool start) { - if ( start ) { -// tabStartLoading(index, index == currentIndex() && m_active ? "light" : "dark"); - } else { - CAnimatedIcon * icon = (CAnimatedIcon *)TAB_ICON(index); - if ( icon ) icon->stop(); + if (!start) { + if (CAnimatedIcon * icon = (CAnimatedIcon*)tabIconLabel(index)) + icon->stop(); } } +void CTabBar::setTabIconTheme(int index, TabTheme theme) +{ + if (CAnimatedIcon * icon = (CAnimatedIcon*)tabIconLabel(index)) + icon->setSvgElement(theme == TabTheme::LightTab ? "dark" : "light"); +} + void CTabBar::tabStartLoading(int index, const QString& theme) { - CAnimatedIcon * icon = (CAnimatedIcon *)TAB_ICON(index); - if ( icon ) { - if ( !icon->isStarted() ) - icon->startSvg(":/tabbar/icons/loader.svg", theme); - } + CAnimatedIcon * icon = (CAnimatedIcon*)tabIconLabel(index); + if (icon && !icon->isStarted() ) + icon->startSvg(":/tabbar/icons/loader.svg", theme); } -void CTabBar::onCloseButton() +void CTabBar::setIgnoreActiveTabColor(bool ignore) { - QWidget * b = sender() ? (QWidget *)sender() : - qApp->widgetAt(QCursor::pos()); - int tabToClose = -1; - for (int i(0); i < count(); ++i) { - if ( TAB_BTNCLOSE(i) == b ) { - tabToClose = i; - break; - } - } - - if ( !(tabToClose < -1) ) - emit tabCloseRequested(tabToClose); + d->ignore_tabcolor = ignore; } -void CTabBar::setTabTheme(int index, TabTheme theme) +bool CTabBar::ignoreActiveTabColor() { - setTabData(index, theme); + return d->ignore_tabcolor; +} - CAnimatedIcon * i = (CAnimatedIcon *)TAB_ICON(index); - QWidget * b = TAB_BTNCLOSE(index); - if ( theme == TabTheme::LightTab ) { - if ( i ) { - i->setSvgElement("dark"); - } +void CTabBar::polish() +{ + for (int i = 0; i < d->tabList.size(); i++) + d->tabList[i]->polish(); + d->tabArea->style()->polish(d->tabArea); + d->scrollFrame->style()->polish(d->scrollFrame); + d->leftButton->style()->polish(d->leftButton); + d->rightButton->style()->polish(d->rightButton); +} - if ( b && !(b->property("state") == "normal") ) { - b->setProperty("state", "normal"); - b->style()->polish(b); - } - } else { - if ( i ) { - i->setSvgElement("light"); +int CTabBar::tabIndexAt(const QPoint &pos) const +{ + QPoint rel_pos = d->tabArea->mapFromParent(pos); + if (d->tabArea->rect().contains(rel_pos)) { + for (int i = 0; i < d->tabList.size(); i++) { + if (d->_tabRect(i).contains(rel_pos)) + return i; } + } + return -1; +} - if ( b && !(b->property("state") == "active") ) { - b->setProperty("state", "active"); - b->style()->polish(b); +QWidget *CTabBar::tabIconLabel(int index) const +{ + return d->indexIsValid(index) ? d->tabList[index]->icon_label : nullptr; +} + +QWidget *CTabBar::tabButton(int index) const +{ + return d->indexIsValid(index) ? d->tabList[index]->close_btn : nullptr; +} + +//QVariant CTabBar::tabData(int index) const +//{ +// return d->indexIsValid(index) ? d->tabList[index]->property("TabData") : QVariant(); +//} + +QIcon CTabBar::tabIcon(int index) const +{ + if (d->indexIsValid(index) && d->tabList[index]->tab_icon) + return *d->tabList[index]->tab_icon; + return QIcon(); +} + +QRect CTabBar::tabRect(int index) const +{ + return d->indexIsValid(index) ? d->_tabRect(index) : QRect(); +} + +QString CTabBar::tabText(int index) const +{ + return (d->indexIsValid(index)) ? d->tabList[index]->text : QString(); +} + +QVariant CTabBar::tabProperty(int index, const char *name) +{ + return d->indexIsValid(index) ? d->tabList[index]->property(name) : QVariant(); +} + +void CTabBar::tabInserted(int index) +{ + Q_UNUSED(index) +} + +void CTabBar::resizeEvent(QResizeEvent *event) +{ + QFrame::resizeEvent(event); + for (int i = 0; i < d->tabList.size(); i++) + d->tabList[i]->setFixedHeight(d->tabArea->height()); + + int tabsWidth = d->tabList.isEmpty() ? 0 : count() * d->cellWidth(); + bool visible = (tabsWidth > d->tabArea->width()); + d->leftButton->setVisible(visible); + d->rightButton->setVisible(visible); + + const int lastIndex = d->tabList.size() - 1; + const int offsetX = (lastIndex == -1) ? 0 : d->tabArea->rect().right() - d->_tabRect(lastIndex).right(); + if (offsetX > TABSPACING) { + for (int i = 0; i < d->tabList.size(); i++) + d->tabList[i]->move(d->_tabRect(i).x() + offsetX - TABSPACING, 0); + } + d->changeScrollerState(); +} + +void CTabBar::wheelEvent(QWheelEvent *event) +{ + QFrame::wheelEvent(event); + if (!d->animationInProgress && d->tabArea->underMouse()) { + if (d->currentIndex > 0 && event->angleDelta().y() > 0) { + emit onCurrentChangedByWhell(d->currentIndex - 1); + d->onCurrentChanged(d->currentIndex - 1); + } else + if (d->currentIndex < count() - 1 && event->angleDelta().y() < 0) { + emit onCurrentChangedByWhell(d->currentIndex + 1); + d->onCurrentChanged(d->currentIndex + 1); } } } -void CTabBar::setUIThemeType(bool islight) +bool CTabBar::eventFilter(QObject *watched, QEvent *event) { - Q_D(QTabBar); - - m_isUIThemeDark = !islight; - if (m_pLeftButton && m_pRightButton) { - m_pLeftButton->style()->polish(m_pLeftButton); - m_pRightButton->style()->polish(m_pRightButton); - } - QTimer::singleShot(20, this, [=]() { - Q_D(QTabBar); - if (d->scrollOffset != m_scrollPos) { - const int tabWidth = this->tabSizeHint(0).width(); - if (m_scrollPos % tabWidth == 0) { - for (int i = 0; i < count(); i++) { - if (!d->rightB->isEnabled()) break; - d->rightB->click(); - } - for (int i = 0; i < count(); i++) { - if (d->scrollOffset == m_scrollPos) break; - d->leftB->click(); - } - - } else { - for (int i = 0; i < count(); i++) { - if (!d->leftB->isEnabled()) break; - d->leftB->click(); - } - for (int i = 0; i < count(); i++) { - if (d->scrollOffset == m_scrollPos) break; - d->rightB->click(); - } - } - } - }); -} - -void CTabBar::setActiveTabColor(const QString& color) -{ - m_activeColor = color; -} - -void CTabBar::changeTabTheme(int index, TabTheme theme) -{ - if ( tabData(index).isNull() ) { - CAnimatedIcon * i = (CAnimatedIcon *)TAB_ICON(index); - QWidget * b = TAB_BTNCLOSE(index); - if ( theme == TabTheme::LightTab ) { - if ( i && i->isStarted() ) { - i->setSvgElement("dark"); - } - - if ( b && !(b->property("state") == "normal") ) { - b->setProperty("state", "normal"); - b->style()->polish(b); - } - } else { - if ( i && i->isStarted() ) { - i->setSvgElement("light"); - } - - if ( b && !(b->property("state") == "active") ) { - b->setProperty("state", "active"); - b->style()->polish(b); - } - } - } -} - -void CTabBar::activate(bool a) -{ - if ( m_active != a ) { - m_active = a; - -// if ( tabData(m_current).isNull() ) - { - QWidget * b = TAB_BTNCLOSE(m_current); - if ( b ) { - if ( a ){ - b->show(); -// b->setProperty("state", "active"); - } else { - b->hide(); -// b->setProperty("state", "normal"); - m_overIndex = -1; - } - - b->style()->polish(b); - } - } - } -} - -void CTabBar::updateScalingFactor(double f) -{ - CScalingWrapper::updateScalingFactor(f); - - for (int i(count()); !(--i < 0); ) { - QWidget * b = TAB_BTNCLOSE(i); - - if ( b ) { - b->setFixedSize( QSize(16, 16) * f ); - } - } - - repaint(); -} - -bool CTabBar::event(QEvent * e) -{ - if ( e->type() == QEvent::HoverMove ) { - Q_D(QTabBar); - - if ( !d->dragInProgress ) { - QHoverEvent * _hover = static_cast(e); - - int _index = tabAt(_hover->pos()); - if ( m_overIndex != _index ) { - int _hide(m_overIndex); - m_overIndex = _index; - - QWidget * b; - if ( !(_hide < 0) && (!m_active || _hide != currentIndex()) ) { - b = TAB_BTNCLOSE(_hide); - if ( b ) b->hide(); - } - - if ( !(_index < 0) ) { - b = TAB_BTNCLOSE(_index); - if ( b ) { - b->show(); + if (watched == d->tabArea) { + switch (event->type()) { + case QEvent::MouseMove: { + QMouseEvent* me = dynamic_cast(event); + if (me->buttons().testFlag(Qt::LeftButton)) { + if (d->movedTab && !d->lock) { + d->movedTab->move(me->x() - d->movedTabPressPosX, 0); + int offsetX; + const int interIndex = d->getLayoutsIntersectedIndex(d->movedTab, offsetX); + if (/*interIndex != -1 &&*/ d->movedTab->index != interIndex && offsetX != 0) { + const int sign = (offsetX >= 0) ? 1 : -1; + if (sign * offsetX > d->movedTab->width()/2) { + if (d->indexIsValid(interIndex + sign)) { + int delta = d->tabLayouts[interIndex + sign].x() - d->_tabRect(interIndex).x(); + d->slide(interIndex, interIndex, delta, ANIMATION_MOVE_TAB_MS); + } + d->tabIndex(interIndex) += sign; + d->movedTab->index = d->tabIndex(interIndex) - sign; + d->currentIndex = d->movedTab->index; + emit tabMoved(d->currentIndex, d->tabIndex(interIndex)); + emit currentChanged(d->currentIndex); + d->reorderIndexes(); + } + } + if (!d->tabArea->rect().contains(me->pos()) && d->tabArea->rect().right() >= me->x()) { + if (d->currentIndex != d->movedTabIndex) + d->reorderIndexes(); + bool accepted = false; + emit tabUndock(d->currentIndex, accepted); + if (accepted) { + d->movedTab->hide(); + d->movedTab = nullptr; + d->movedTabIndex = -1; + QTimer::singleShot(0, this, [=]() { + removeTab(d->currentIndex); + while (d->animationInProgress) + qApp->processEvents(); + d->changeScrollerState(); + }); + } } } } + break; + } + case QEvent::MouseButtonPress: { + QMouseEvent* me = dynamic_cast(event); + if (me->button() == Qt::LeftButton) { + if (!d->animationInProgress) { + for (int i = 0; i < d->tabList.size(); i++) { + if (d->_tabRect(i).contains(me->pos())) { + d->lock = true; + d->movedTab = d->tabList[i]; + d->movedTabIndex = i; + const int offset = d->getIntersectedOffset(i); + d->movedTabPosX = d->movedTab->x() - offset; + d->movedTabPressPosX = me->x() - d->movedTabPosX; + QPoint oldCurPos = QCursor::pos(); + d->tabLayouts.clear(); + for (int j = 0; j < d->tabList.size(); j++) { + d->tabLayouts.append(d->_tabRect(j).translated(-1 * offset, 0).adjusted(0,0,TABSPACING,0)); + if (j != i) + d->tabList[j]->stackUnder(d->movedTab); + } + emit tabBarClicked(i); + if (i != d->currentIndex) + d->onCurrentChanged(i); + else + d->scrollTo(i); + while (d->animationInProgress) + qApp->processEvents(); + QCursor::setPos(oldCurPos); + d->lock = false; + return true; + } + } + } + } + break; + } + case QEvent::MouseButtonRelease: { + QMouseEvent* mouse_event = dynamic_cast(event); + if (mouse_event->button() == Qt::LeftButton) { + while (d->animationInProgress) + qApp->processEvents(); + if (d->movedTab) { + if (d->currentIndex != d->movedTabIndex) { + d->reorderIndexes(); + int posX = d->tabLayouts[d->currentIndex].x(); + d->movedTab->move(posX, 0); + } else { + d->movedTab->move(d->movedTabPosX, 0); + } + d->movedTab = nullptr; + d->movedTabIndex = -1; + d->changeScrollerState(); + return true; + } + } else + if (mouse_event->button() == Qt::MiddleButton) { + for (int i = 0; i < d->tabList.size(); i++) { + if (d->tabList[i]->close_btn->underMouse()) { + emit tabCloseRequested(i); + return true; + } + } + } + break; + } + case QEvent::MouseButtonDblClick: { + QMouseEvent* mouse_event = dynamic_cast(event); + if (mouse_event->button() == Qt::LeftButton) { + for (int i = 0; i < d->tabList.size(); i++) { + if (d->tabList[i]->underMouse()) { + emit tabBarDoubleClicked(i); + return true; + } + } + } + break; + } + default: + break; } } else - if ( e->type() == QEvent::Leave ) { - if ( !(m_overIndex < 0) && (m_overIndex != currentIndex() || !m_active) ) { - QWidget * b = TAB_BTNCLOSE(m_overIndex); - if ( b ) { - b->hide(); - } - - m_overIndex = -1; + if (watched == this) { + switch (event->type()) { + case QEvent::Enter: + setCursor(QCursor(Qt::ArrowCursor)); + break; + case QEvent::Leave: + QApplication::postEvent(d->tabArea, new QMouseEvent(QEvent::MouseButtonRelease, QCursor::pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + break; + default: + break; } } - -// qDebug() << "event: " << e; - return QTabBar::event(e); + return QFrame::eventFilter(watched, event); } -int CTabBar::draggedTabIndex() -{ - Q_D(QTabBar); - - return d->pressedIndex; -} - -QSize CTabBar::tabSizeHint(int index) const -{ - return QTabBar::tabSizeHint(index); -} - -void CTabBar::interruptTabMoving(int index) -{ - Q_D(QTabBar); - -#ifndef QT_NO_ANIMATION - for (const auto& t : d->tabList) { - if (t.animation && - t.animation->state() == QAbstractAnimation::Running ) - t.animation->stop(); - } -#endif //QT_NO_ANIMATION - bool cleanup = (d->pressedIndex == index) || (d->pressedIndex == -1) || !d->validIndex(index); - if (cleanup) { - if(d->movingTab) - d->movingTab->setVisible(false); // We might not get a mouse release - - for (auto& t : d->tabList) - t.dragOffset = 0; - - if (d->pressedIndex != -1 && d->movable) { - d->pressedIndex = -1; - d->dragInProgress = false; - d->dragStartPosition = QPoint(); - } - d->layoutWidgets(); - } else { - if (!d->validIndex(index)) - return; - d->tabList[index].dragOffset = 0; - } - - update(); -} +#include "ctabbar.moc" diff --git a/win-linux/src/components/ctabbar.h b/win-linux/src/components/ctabbar.h index 6f3b60b84..76f415de9 100644 --- a/win-linux/src/components/ctabbar.h +++ b/win-linux/src/components/ctabbar.h @@ -33,89 +33,75 @@ #ifndef CTABBAR_H #define CTABBAR_H -#include -#include #include -#include -#include -#include "cscalingwrapper.h" -#include -//class CTabBarPrivate; -class CTabBar : public QTabBar, public CScalingWrapper +class CTabBar : public QFrame { Q_OBJECT - public: - explicit CTabBar(QWidget * parent = nullptr); - virtual ~CTabBar(); - - void setTabTextColor(QPalette::ColorGroup, const QColor&); - void setUseTabCustomPalette(bool); - QPalette& customColors(); - QVariant tabProperty(int index, const char *name); - void setTabProperty(int index, const char *name, const QVariant &value); - void setTabIcon(int index, const QIcon &icon); - void setTabLoading(int, bool); - void setActiveTabColor(const QString&); - void tabStartLoading(int, const QString& theme = QString()); - void activate(bool); - - void updateScalingFactor(double) override; - int draggedTabIndex(); + CTabBar(QWidget *parent = nullptr); + ~CTabBar(); enum TabTheme { LightTab, DarkTab }; - void changeTabTheme(int, TabTheme); - void setTabTheme(int, TabTheme); - void setUIThemeType(bool islight); - void initCustomScroll(QFrame *, QToolButton *, QToolButton *); -protected: - bool event(QEvent * e) override; - void mousePressEvent (QMouseEvent *) override; - void mouseMoveEvent(QMouseEvent *) override; - void mouseReleaseEvent (QMouseEvent *) override; - void wheelEvent(QWheelEvent *event) override; - void paintEvent(QPaintEvent *) override; - void resizeEvent(QResizeEvent *) override; - void tabInserted(int) override; - void tabRemoved(int index) override; - void drawTabCaption(QPainter *, const QString&, const QStyleOptionTab&); - void fillTabColor(QPainter *, const QStyleOptionTab&, uint, const QColor&); - - QSize tabSizeHint(int index) const override; - - void interruptTabMoving(int index); - -private slots: - void onCloseButton(); - void onCurrentChanged(int); - -private: - QPalette m_palette; - bool m_usePalette = false; - int m_overIndex = -1; - int m_current = -1; - bool m_active = false; - bool m_isUIThemeDark = false; - bool m_tabWasMoved = false; - QString m_activeColor = "none"; + int addTab(const QString &text); + int addTab(const QIcon &icon, const QString &text); + int count() const; + int currentIndex() const; + Qt::TextElideMode elideMode() const; + QSize iconSize() const; + int insertTab(int index, const QString &text); + int insertTab(int index, const QIcon &icon, const QString &text); + void moveTab(int from, int to); + void removeTab(int index); + void setElideMode(Qt::TextElideMode mode); + void setIconSize(const QSize &size); + void setTabIconLabel(int index, QWidget *widget); + void setTabButton(int index, QWidget *widget); +// void setTabData(int index, const QVariant &data); + void setTabIcon(int index, const QIcon &icon); + void setTabText(int index, const QString &text); + void setTabToolTip(int index, const QString &text); + void setCurrentIndex(int index); + void setActiveTabColor(int index, const QString&); + void setUseTabCustomPalette(int, bool); + void setTabLoading(int, bool); + void setTabIconTheme(int, TabTheme); + void tabStartLoading(int, const QString& theme = QString()); + void setIgnoreActiveTabColor(bool ignore); + bool ignoreActiveTabColor(); + void polish(); + int tabIndexAt(const QPoint &pos) const; + QWidget* tabIconLabel(int index) const; + QWidget* tabButton(int index) const; +// QVariant tabData(int index) const; + QIcon tabIcon(int index) const; + QRect tabRect(int index) const; + QString tabText(int index) const; + QVariant tabProperty(int index, const char *name); + virtual void tabInserted(int index); signals: - void tabUndock(int, bool *); + void currentChanged(int index); void onCurrentChangedByWhell(int index); + void tabBarClicked(int index); + void tabBarDoubleClicked(int index); + void tabCloseRequested(int index); + void tabMoved(int from, int to); + void tabUndock(int index, bool &accepted); + +protected: + virtual void resizeEvent(QResizeEvent *event) override; + virtual void wheelEvent(QWheelEvent *event) override; + virtual bool eventFilter(QObject*, QEvent*) override; private: - Q_DECLARE_PRIVATE(QTabBar) - int m_scrollPos; - QFrame *m_pScrollerFrame; - QToolButton *m_pLeftButton, - *m_pRightButton; - void changeCustomScrollerState(); + class CTabBarPrivate; + CTabBarPrivate* d = nullptr; }; #endif // CTABBAR_H diff --git a/win-linux/src/components/ctabbarwrapper.cpp b/win-linux/src/components/ctabbarwrapper.cpp deleted file mode 100644 index 309553ab6..000000000 --- a/win-linux/src/components/ctabbarwrapper.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "components/ctabbarwrapper.h" -#include -#include - - -CTabBarWrapper::CTabBarWrapper(QWidget *parent): - QFrame(parent) -{ - setObjectName(QString::fromUtf8("tabWrapper")); - setFrameShape(QFrame::NoFrame); - setFrameShadow(QFrame::Plain); - - QGridLayout *_pTabFrameLayout = new QGridLayout(this); - _pTabFrameLayout->setSpacing(0); - _pTabFrameLayout->setContentsMargins(0,0,0,0); - this->setLayout(_pTabFrameLayout); - - // Bypassing the bug with tab scroller - m_pScrollerFrame = new QFrame(this); - m_pScrollerFrame->setObjectName("scrollerFrame"); - QHBoxLayout *_pScrollerLayout = new QHBoxLayout(m_pScrollerFrame); - _pScrollerLayout->setSpacing(0); - _pScrollerLayout->setContentsMargins(0,0,0,0); - m_pScrollerFrame->setLayout(_pScrollerLayout); - - QToolButton* _pLeftButton = new QToolButton(m_pScrollerFrame); - QToolButton* _pRightButton = new QToolButton(m_pScrollerFrame); - _pLeftButton->setObjectName("leftButton"); - _pRightButton->setObjectName("rightButton"); - - _pScrollerLayout->addWidget(_pLeftButton); - _pScrollerLayout->addWidget(_pRightButton); - _pLeftButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - _pRightButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - _pLeftButton->installEventFilter(this); - _pRightButton->installEventFilter(this); - _pLeftButton->setMouseTracking(true); - _pRightButton->setMouseTracking(true); - _pLeftButton->setAttribute(Qt::WA_Hover, true); - _pRightButton->setAttribute(Qt::WA_Hover, true); // End bypassing the bug - - m_pBar = new CTabBar(this); - m_pBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - QWidget *_pPaddingWidget = new QWidget(this); - _pPaddingWidget->setObjectName("paddingWidget"); - _pPaddingWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - QHBoxLayout *_pTabLayout = new QHBoxLayout(); -#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 2)) - _pTabLayout->setSpacing(0); -#else - _pTabLayout->setSpacing(32); -#endif - _pTabLayout->setContentsMargins(0,0,0,0); - _pTabLayout->addWidget(m_pBar); - _pTabLayout->addWidget(_pPaddingWidget); - - _pTabFrameLayout->addLayout(_pTabLayout, 0, 0, 1, 1); - _pTabFrameLayout->addWidget(m_pScrollerFrame, 0, 0, 1, 1, Qt::AlignRight); - - m_pBar->initCustomScroll(m_pScrollerFrame, _pLeftButton, _pRightButton); - -} - -CTabBarWrapper::~CTabBarWrapper() -{ - -} - -CTabBar *CTabBarWrapper::tabBar() -{ - return m_pBar; -} - -void CTabBarWrapper::applyTheme(const QString &style) -{ - this->setStyleSheet(style); - m_pScrollerFrame->setStyleSheet(style); - m_pBar->setStyleSheet(style); -} - -bool CTabBarWrapper::eventFilter(QObject *object, QEvent *event) -{ - switch (event->type()) { - case QEvent::HoverEnter: { - if (object->objectName() == QString("leftButton") || - object->objectName() == QString("rightButton")) { - m_pScrollerFrame->setCursor(QCursor(Qt::ArrowCursor)); - } - break; - } - default: - break; - } - return QWidget::eventFilter(object, event); -} diff --git a/win-linux/src/components/ctabbarwrapper.h b/win-linux/src/components/ctabbarwrapper.h deleted file mode 100644 index 676c347b3..000000000 --- a/win-linux/src/components/ctabbarwrapper.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef CTABBARWRAPPER_H -#define CTABBARWRAPPER_H - -#include -#include "ctabbar.h" - - -class CTabBarWrapper: public QFrame -{ - Q_OBJECT -public: - explicit CTabBarWrapper(QWidget *parent = nullptr); - ~CTabBarWrapper(); - CTabBar *tabBar(); - void applyTheme(const QString &style); - -private: - QFrame *m_pScrollerFrame; - CTabBar *m_pBar; - bool eventFilter(QObject *, QEvent *); -}; - -#endif // CTABBARWRAPPER_H diff --git a/win-linux/src/windows/cmainwindow.cpp b/win-linux/src/windows/cmainwindow.cpp index 36cab3d9b..692e75e66 100644 --- a/win-linux/src/windows/cmainwindow.cpp +++ b/win-linux/src/windows/cmainwindow.cpp @@ -87,16 +87,7 @@ using namespace NSEditorApi; CMainWindow::CMainWindow(const QRect &rect) : CWindowPlatform(rect), CScalingWrapper(m_dpiRatio), - m_pTabBarWrapper(nullptr), - m_pTabs(nullptr), - m_pButtonMain(nullptr), - m_pMainWidget(nullptr), - m_pButtonProfile(nullptr), - m_pWidgetDownload(nullptr), - m_savePortal(QString()), - m_isMaximized(false), - m_saveAction(0), - m_printData(nullptr) + m_savePortal(QString()) { setObjectName("MainWindow"); m_pMainPanel = createMainPanel(this); @@ -117,8 +108,7 @@ CMainWindow::CMainWindow(const QRect &rect) : CMainWindow::~CMainWindow() { - if (m_printData) - delete m_printData, m_printData = nullptr; + } /** Public **/ @@ -185,7 +175,7 @@ int CMainWindow::attachEditor(QWidget * panel, const QPoint& pt) _pt_local -= windowRect().topLeft(); # endif #endif - int _index = tabWidget()->tabBar()->tabAt(_pt_local); + int _index = tabWidget()->tabBar()->tabIndexAt(_pt_local); if ( !(_index < 0) ) { QRect _rc_tab = tabWidget()->tabBar()->tabRect(_index); if ( _pt_local.x() > _rc_tab.left() + (_rc_tab.width() / 2) ) ++_index; @@ -228,7 +218,7 @@ void CMainWindow::applyTheme(const std::wstring& theme) } } m_boxTitleBtns->style()->polish(m_boxTitleBtns); - m_pTabBarWrapper->style()->polish(m_pTabBarWrapper); + m_pTabs->tabBar()->style()->polish(m_pTabs->tabBar()); m_pButtonMain->style()->polish(m_pButtonMain); if (m_pTopButtons[BtnType::Btn_Minimize]) { foreach (auto btn, m_pTopButtons) @@ -379,14 +369,17 @@ QWidget* CMainWindow::createMainPanel(QWidget *parent) mainPanel->setLayout(_pMainGridLayout); // Set custom TabBar - m_pTabBarWrapper = new CTabBarWrapper(mainPanel); - m_pTabBarWrapper->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - _pMainGridLayout->addWidget(m_pTabBarWrapper, 0, 1, 1, 1); + CTabBar *pTabBar = new CTabBar(mainPanel); + _pMainGridLayout->addWidget(pTabBar, 0, 1, 1, 1); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(1); + pTabBar->setSizePolicy(sizePolicy); // QSize wide_btn_size(29*g_dpi_ratio, TOOLBTN_HEIGHT*g_dpi_ratio); m_boxTitleBtns = createTopPanel(mainPanel); m_boxTitleBtns->setObjectName("CX11Caption"); _pMainGridLayout->addWidget(m_boxTitleBtns, 0, 2, 1, 1); + m_boxTitleBtns->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); #ifdef __DONT_WRITE_IN_APP_TITLE QLabel * label = new QLabel(m_boxTitleBtns); @@ -421,16 +414,16 @@ QWidget* CMainWindow::createMainPanel(QWidget *parent) } // m_pTabs->setAutoFillBackground(true); // Set TabWidget - m_pTabs = new CAscTabWidget(mainPanel, tabBar()); + m_pTabs = new CAscTabWidget(mainPanel, pTabBar); m_pTabs->setObjectName(QString::fromUtf8("ascTabWidget")); - _pMainGridLayout->addWidget(m_pTabs, 1, 0, 1, 4); + _pMainGridLayout->addWidget(m_pTabs, 1, 0, 1, 3); m_pTabs->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_pTabs->activate(false); m_pTabs->applyUITheme(AscAppManager::themes().current().id()); - connect(tabWidget(), SIGNAL(currentChanged(int)), this, SLOT(onTabChanged(int))); - connect(tabBar(), SIGNAL(tabBarClicked(int)), this, SLOT(onTabClicked(int))); - connect(tabBar(), SIGNAL(tabCloseRequested(int)), this, SLOT(onTabCloseRequest(int))); + connect(m_pTabs, SIGNAL(currentChanged(int)), this, SLOT(onTabChanged(int))); + connect(pTabBar, SIGNAL(tabBarClicked(int)), this, SLOT(onTabClicked(int))); + connect(pTabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(onTabCloseRequest(int))); connect(m_pTabs, &CAscTabWidget::editorInserted, bind(&CMainWindow::onTabsCountChanged, this, _2, _1, 1)); connect(m_pTabs, &CAscTabWidget::editorRemoved, bind(&CMainWindow::onTabsCountChanged, this, _2, _1, -1)); m_pTabs->setPalette(palette); @@ -448,7 +441,7 @@ void CMainWindow::attachStartPanel(QCefView * const view) QGridLayout *_pMainGridLayout = dynamic_cast(m_pMainPanel->layout()); Q_ASSERT(_pMainGridLayout != nullptr); if (_pMainGridLayout) - _pMainGridLayout->addWidget(m_pMainWidget, 1, 0, 1, 4); + _pMainGridLayout->addWidget(m_pMainWidget, 1, 0, 1, 3); m_pMainWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); if (!m_pTabs->isActiveWidget()) m_pMainWidget->show(); @@ -546,9 +539,9 @@ void CMainWindow::onEditorAllowedClose(int uid) int _index = m_pTabs->tabIndexByView(uid); if ( !(_index < 0) ) { QWidget * _view = m_pTabs->widget(_index); + m_pTabs->removeWidget(_view); _view->deleteLater(); - m_pTabs->removeTab(_index); //m_pTabs->adjustTabsSize(); onTabChanged(m_pTabs->currentIndex()); @@ -1141,7 +1134,6 @@ void CMainWindow::onDocumentPrint(void * opts) if ( !AscAppManager::printData().isQuickPrint() ) AscAppManager::printData().setPrinterInfo(*printer); -// m_printData->_print_range = dialog->printRange(); QVector page_ranges; #ifdef Q_OS_LINUX @@ -1379,9 +1371,9 @@ void CMainWindow::updateScalingFactor(double dpiratio) m_pMainPanel->setProperty("zoom", QString::number(dpiratio) + "x"); std::vector _files{":/styles/tabbar.qss"}; QString _style = Utils::readStylesheets(&_files); - m_pTabBarWrapper->applyTheme(_style); + m_pTabs->tabBar()->setStyleSheet(_style); m_pTabs->setStyleSheet(_style); - m_pTabs->updateScalingFactor(dpiratio); +// m_pTabs->updateScalingFactor(dpiratio); m_pTabs->reloadTabIcons(); m_pButtonMain->setIcon(MAIN_ICON_PATH, AscAppManager::themes().current().isDark() ? "logo-light" : "logo-dark"); m_pButtonMain->setIconSize(MAIN_ICON_SIZE * dpiratio); @@ -1437,11 +1429,6 @@ CAscTabWidget * CMainWindow::tabWidget() return m_pTabs; } -CTabBar *CMainWindow::tabBar() -{ - return m_pTabBarWrapper->tabBar(); -} - void CMainWindow::showEvent(QShowEvent * e) { CWindowPlatform::showEvent(e); diff --git a/win-linux/src/windows/cmainwindow.h b/win-linux/src/windows/cmainwindow.h index 5c410a35f..e8b4ff62a 100644 --- a/win-linux/src/windows/cmainwindow.h +++ b/win-linux/src/windows/cmainwindow.h @@ -147,20 +147,16 @@ public slots: private: QWidget * createMainPanel(QWidget *parent); - inline CTabBar *tabBar(); int trySaveDocument(int); - CTabBarWrapper* m_pTabBarWrapper; - CAscTabWidget * m_pTabs; - CSVGPushButton* m_pButtonMain; - QWidget* m_pMainWidget; - QPushButton* m_pButtonProfile; - CDownloadWidget* m_pWidgetDownload; + CAscTabWidget * m_pTabs = nullptr; + CSVGPushButton* m_pButtonMain = nullptr; + QWidget* m_pMainWidget = nullptr; + QPushButton* m_pButtonProfile = nullptr; + CDownloadWidget* m_pWidgetDownload = nullptr; QString m_savePortal; - bool m_isMaximized; - int m_saveAction; - struct printdata; - printdata* m_printData; + bool m_isMaximized = false; + int m_saveAction = 0; bool m_isCloseAll = false; diff --git a/win-linux/src/windows/cwindowbase.cpp b/win-linux/src/windows/cwindowbase.cpp index 77162fcda..c5b223963 100644 --- a/win-linux/src/windows/cwindowbase.cpp +++ b/win-linux/src/windows/cwindowbase.cpp @@ -226,11 +226,7 @@ bool CWindowBase::event(QEvent *event) QWidget *wgt = qApp->widgetAt(hlp->globalPos()); if (wgt && !findChild()) { QString text(""); - CTabBar *bar = dynamic_cast(wgt); - if (bar) { - int index = bar->tabAt(bar->mapFromGlobal(hlp->globalPos())); - text = bar->tabProperty(index, "ToolTip").toString(); - } else + if (wgt->property("ToolTip").isValid()) text = wgt->property("ToolTip").toString(); if (m_pMainPanel && !text.isEmpty()) { CToolTip *tool = new CToolTip(m_pMainPanel, text, hlp->globalPos());