[win-nix] refactoring. dock/undock tab

This commit is contained in:
maxkadushkin
2018-03-08 01:06:10 +03:00
parent a0358ced4e
commit b9d89dcbc4
11 changed files with 219 additions and 133 deletions

View File

@ -47,7 +47,8 @@ HEADERS += \
$$PWD/src/clangater.h \
$$PWD/src/cwindowbase.h \
$$PWD/src/canimatedicon.h \
$$PWD/src/cscalingwrapper.h
$$PWD/src/cscalingwrapper.h \
$$PWD/src/ctabundockevent.h
# src/ctabbar_p.h \
# src/ctabstyle.h \
# src/ctabstyle_p.h
@ -73,7 +74,8 @@ SOURCES += \
$$PWD/src/clogger.cpp \
$$PWD/src/clangater.cpp \
$$PWD/src/canimatedicon.cpp \
$$PWD/src/cscalingwrapper.cpp
$$PWD/src/cscalingwrapper.cpp \
$$PWD/src/ctabundockevent.cpp
# src/ctabstyle.cpp
# src/casclabel.cpp

View File

@ -51,6 +51,7 @@
#include "cfilechecker.h"
#include "cascapplicationmanagerwrapper.h"
#include "ctabundockevent.h"
#include "private/qtabbar_p.h"
@ -166,10 +167,22 @@ CAscTabWidget::CAscTabWidget(QWidget *parent)
setProperty("active", false);
setProperty("empty", true);
QObject::connect(this, &QTabWidget::currentChanged, [=](){updateIcons(); setFocusedView();});
QObject::connect(this, &QTabWidget::currentChanged, [=](){
updateIcons();
setFocusedView();
m_dragIndex = -1;
});
#if defined(APP_MULTI_WINDOW)
QObject::connect(tabs, &CTabBar::tabUndock, [=](int index){
QTimer::singleShot(0, this, [=]{ emit tabUndockRequest(index);});
if ( m_dragIndex != index ) {
CTabUndockEvent event(widget(index));
QObject * obj = qobject_cast<QObject *>(
static_cast<CAscApplicationManagerWrapper *>(&AscAppManager::getInstance()));
if ( QApplication::sendEvent(obj, &event) && event.isAccepted() ) {
m_dragIndex = index;
}
}
});
#endif
}
@ -341,18 +354,40 @@ int CAscTabWidget::addOAuthPortal(const QString& portal, const QString& type, c
return tab_index;
}
int CAscTabWidget::pickupTab(QWidget * panel)
int CAscTabWidget::insertPanel(QWidget * panel, int index)
{
CAscTabData * tabdata = ((CTabPanel *)panel)->data();
int tabindex = -1;
int tabindex = insertTab(count(), panel, tabdata->title());
tabBar()->setTabToolTip(tabindex, QString::fromStdWString(tabdata->url()));
CTabPanel * _panel = dynamic_cast<CTabPanel *>(panel);
if ( _panel ) {
CAscTabData * tabdata = _panel->data();
resizeEvent(nullptr);
tabindex = insertTab(index, panel, tabdata->title());
tabBar()->setTabToolTip(tabindex, QString::fromStdWString(tabdata->url()));
resizeEvent(nullptr);
}
return tabindex;
}
QWidget * CAscTabWidget::releaseEditor(int index)
{
if ( index < 0 || index >= count() )
index = currentIndex();
if ( index < 0 )
return nullptr;
else {
QApplication::sendEvent( tabBar(),
&QMouseEvent(QEvent::MouseButtonRelease,
tabBar()->tabRect(index).topLeft() + (QPoint(5, 5)),
Qt::LeftButton, Qt::LeftButton, Qt::NoModifier) );
return widget(index);
}
}
void CAscTabWidget::resizeEvent(QResizeEvent* e)
{
Q_UNUSED(e);

View File

@ -126,6 +126,7 @@ private:
bool m_isCustomStyle;
CTabIconSet m_mapTabIcons;
QSize m_tabIconSize;
int m_dragIndex = -1;
signals:
@ -133,7 +134,6 @@ signals:
void closeAppRequest();
void editorInserted(int, int);
void editorRemoved(int, int);
void tabUndockRequest(int);
public:
CAscTabWidget(QWidget *parent = 0);
@ -142,11 +142,12 @@ public:
int addEditor(COpenOptions&);
int addPortal(QString url, QString name);
int addOAuthPortal(const QString& portal, const QString& type, const QString& service);
int pickupTab(QWidget * panel);
int insertPanel(QWidget *, int);
void closeEditorByIndex(int index, bool checkmodified = false);
void closeAllEditors();
void closePortal(const QString&, bool editors = false);
void setStyleSheet(const QString&);
QWidget * releaseEditor(int);
void updateScaling(int);
protected:

View File

@ -13,6 +13,7 @@
#include "cfiledialog.h"
#include "utils.h"
#include "common/Types.h"
#include "ctabundockevent.h"
#ifdef _WIN32
#include "csplash.h"
@ -492,30 +493,22 @@ CSingleWindow * CAscApplicationManagerWrapper::editorWindowFromViewId(int uid) c
void CAscApplicationManagerWrapper::processMainWindowMoving(const size_t s, const QPoint& c)
{
#define GET_CURRENT_PANEL -1
APP_CAST(_app);
if ( _app.m_vecWidows.size() > 1 ) {
QPoint _local_pos;
CMainWindow * _window = nullptr,
* _source = reinterpret_cast<CMainWindow *>(s);
for (auto const& w : _app.m_vecWidows) {
if ( w != s ) {
_window = reinterpret_cast<CMainWindow *>(w);
_local_pos = _window->mainPanel()->mapFromGlobal(c);
if ( _window->mainPanel()->isPointInTabs(_local_pos) ) {
QTimer::singleShot(0, [=] {
QPoint pos = QCursor::pos();
#ifdef _WIN32
PostMessage(_source->hWnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(pos.x(), pos.y()));
QWidget * panel = _source->mainPanel()->releaseEditor();
_window->joinTab(panel);
closeMainWindow(s);
#endif
});
if ( _window->pointInTabs(c) ) {
_source->hide();
_window->attachEditor(
_source->editorPanel(GET_CURRENT_PANEL), c );
closeMainWindow(s);
break;
}
}
@ -565,3 +558,40 @@ QString CAscApplicationManagerWrapper::getWindowStylesheets(uint dpifactor)
APP_CAST(_app);
return Utils::readStylesheets(&_app.m_vecStyles, &_app.m_vecStyles2x, dpifactor);
}
bool CAscApplicationManagerWrapper::event(QEvent *event)
{
if ( event->type() == CTabUndockEvent::type() ) {
CTabUndockEvent * e = (CTabUndockEvent *)event;
if ( e->panel() ) {
e->accept();
QWidget * _panel = e->panel();
QTimer::singleShot(0, this, [=]{
CMainWindow * _main_window = nullptr;
#ifdef _WIN32
CWinPanel * _wp = dynamic_cast<CWinPanel *>(_panel->window());
if ( _wp ) _main_window = _wp->parent();
#else
_main_window = dynamic_cast<CMainWindow *>(_panel->window());
#endif
if ( _main_window ) {
QRect _win_rect = _main_window->windowRect();
_win_rect.moveTo(QCursor::pos() - QPoint(BUTTON_MAIN_WIDTH + 50, 20));
CMainWindow * window = createMainWindow(_win_rect);
bool _is_maximized = _main_window->isMaximized();
window->show(_is_maximized);
window->toggleBorderless(_is_maximized);
window->attachEditor( _panel );
}
});
}
return true;
}
return QObject::event(event);
}

View File

@ -108,6 +108,7 @@ public:
static void sendEvent(int type, void * data);
static QString getWindowStylesheets(uint);
bool event(QEvent *event);
private:
class CAscApplicationManagerWrapper_Private;
std::unique_ptr<CAscApplicationManagerWrapper_Private> m_private;

View File

@ -125,7 +125,6 @@ CMainPanel::CMainPanel(QWidget *parent, bool isCustomWindow, uchar dpi_ratio)
connect(m_pTabs, &CAscTabWidget::closeAppRequest, this, &CMainPanel::onAppCloseRequest);
connect(m_pTabs, &CAscTabWidget::editorInserted, bind(&CMainPanel::onTabsCountChanged, this, _2, _1, 1));
connect(m_pTabs, &CAscTabWidget::editorRemoved, bind(&CMainPanel::onTabsCountChanged, this, _2, _1, -1));
connect(m_pTabs, &CAscTabWidget::tabUndockRequest, this, &CMainPanel::onTabUndockRequest);
QSize small_btn_size(28 * dpi_ratio, TOOLBTN_HEIGHT * dpi_ratio);
// QSize wide_btn_size(29*g_dpi_ratio, TOOLBTN_HEIGHT*g_dpi_ratio);
@ -428,16 +427,21 @@ void CMainPanel::onTabClicked(int index)
}
}
void CMainPanel::onTabClosed(int index, int curcount)
void CMainPanel::onTabsCountChanged(int count, int i, int d)
{
Q_UNUSED(index)
Q_UNUSED(i)
Q_UNUSED(d)
if (curcount == 0) {
if ( count == 0 ) {
toggleButtonMain(true);
}
onTabChanged(m_pTabs->currentIndex());
RecalculatePlaces();
if ( d < 0 ) {
RecalculatePlaces();
} else
QTimer::singleShot(200, [=]{
RecalculatePlaces();
});
}
void CMainPanel::onEditorAllowedClose(int uid)
@ -491,18 +495,9 @@ void CMainPanel::onTabCloseRequest(int index)
{
if (trySaveDocument(index) == MODAL_RESULT_NO) {
m_pTabs->closeEditorByIndex(index, false);
// if ( !m_pTabs->count() ) {
// emit abandoned();
// }
}
}
void CMainPanel::onTabUndockRequest(int index)
{
emit undockTab( releaseEditor(index) );
}
int CMainPanel::trySaveDocument(int index)
{
if (m_pTabs->closedByIndex(index)) return MODAL_RESULT_YES;
@ -1374,36 +1369,3 @@ bool CMainPanel::holdUrl(const QString& url, AscEditorType type) const
}
CAscTabWidget * CMainPanel::tabWidget(){return m_pTabs;}
bool CMainPanel::isPointInTabs(const QPoint& p) const
{
QRect _rect_title = m_pTabs->geometry();
_rect_title.setHeight(TITLE_HEIGHT * scaling());
return _rect_title.contains(p);
}
QWidget * CMainPanel::releaseEditor(int index)
{
if ( index < 0 )
index = m_pTabs->currentIndex();
m_dockTab == index && (m_dockTab = -1);
QWidget * panel = m_pTabs->widget(index);
m_pTabs->removeTab(index);
RecalculatePlaces();
return panel;
}
void CMainPanel::adoptEditor(QWidget * widget)
{
int _index = m_pTabs->pickupTab(widget);
if ( !(_index < 0) ) {
toggleButtonMain(false);
m_pTabs->setCurrentIndex(_index);
RecalculatePlaces();
}
}

View File

@ -68,9 +68,6 @@ public:
bool holdUrl(const QString&, AscEditorType) const;
void toggleButtonMain(bool, bool delay = false);
CAscTabWidget * tabWidget();
bool isPointInTabs(const QPoint&) const;
void adoptEditor(QWidget *);
QWidget * releaseEditor(int index = -1);
virtual void updateScaling(int);
@ -103,9 +100,6 @@ signals:
void mainPageReady();
void checkUpdates();
void undockTab(QWidget *);
void abandoned();
public slots:
void pushButtonMinimizeClicked();
void pushButtonMaximizeClicked();
@ -115,8 +109,8 @@ public slots:
void onTabClicked(int);
void onTabChanged(int);
void onTabCloseRequest(int);
void onTabUndockRequest(int);
void onAppCloseRequest();
void onTabsCountChanged(int, int, int);
void onCloudDocumentOpen(std::wstring, int, bool);
void onDocumentType(int id, int type);

View File

@ -0,0 +1,6 @@
#include "ctabundockevent.h"
//CTabUndockEvent::CTabUndockEvent()
// : QEvent((QEvent::Type)TabUndock)
//{
//}

View File

@ -0,0 +1,33 @@
#ifndef CTABUNDOCKEVENT_H
#define CTABUNDOCKEVENT_H
#include <QEvent>
#include <QWidget>
//const QEvent::Type TAB_UNDOCK_EVENT = static_cast<QEvent::Type>(QEvent::User + 1);
class CTabUndockEvent : public QEvent
{
public:
CTabUndockEvent(QWidget * panel)
: QEvent(CTabUndockEvent::type())
, m_widget(panel)
{
ignore();
}
static QEvent::Type type()
{
return static_cast<QEvent::Type>(QEvent::User + 1);
}
QWidget * panel()
{
return m_widget;
}
private:
QWidget * m_widget;
};
#endif // CTABUNDOCKEVENT_H

View File

@ -133,11 +133,9 @@ CMainWindow::CMainWindow(QRect& rect) :
setMinimumSize( MAIN_WINDOW_MIN_WIDTH*m_dpiRatio, MAIN_WINDOW_MIN_HEIGHT*m_dpiRatio );
CMainPanel * mainpanel = m_pMainPanel;
QObject::connect(mainpanel, &CMainPanel::undockTab, bind(&CMainWindow::slot_undockWindow, this, _1));
QObject::connect(mainpanel, &CMainPanel::mainWindowChangeState, bind(&CMainWindow::slot_windowChangeState, this, _1));
QObject::connect(mainpanel, &CMainPanel::mainWindowClose, bind(&CMainWindow::slot_windowClose, this));
QObject::connect(mainpanel, &CMainPanel::mainPageReady, bind(&CMainWindow::slot_mainPageReady, this));
QObject::connect(mainpanel, &CMainPanel::abandoned, bind(&CMainWindow::slot_finalTabClosed, this));
m_pWinPanel->show();
@ -368,6 +366,7 @@ qDebug() << "WM_CLOSE";
break;
case WM_MOVING: {
#if defined(APP_MULTI_WINDOW)
if ( window->moveByTab() ) {
POINT pt{0};
@ -377,6 +376,7 @@ qDebug() << "WM_CLOSE";
}
break;
#endif
}
case WM_EXITSIZEMOVE: {
@ -689,24 +689,63 @@ void CMainWindow::setScreenScalingFactor(uchar factor)
}
}
int CMainWindow::joinTab(QWidget * panel)
int CMainWindow::attachEditor(QWidget * panel, int index)
{
m_pMainPanel->adoptEditor(panel);
int _index = m_pMainPanel->tabWidget()->insertPanel(panel, index);
if ( !(_index < 0) ) {
m_pMainPanel->toggleButtonMain(false);
QTabBar * tabs = m_pMainPanel->tabWidget()->tabBar();
tabs->setCurrentIndex(_index);
if ( false ) {
QApplication::sendEvent( tabs,
&QMouseEvent(QEvent::MouseButtonPress,
tabs->tabRect(_index).topLeft() + (QPoint(10, 65)*m_dpiRatio),
Qt::LeftButton, Qt::LeftButton, Qt::NoModifier) );
}
}
return 0;
}
int CMainWindow::attachEditor(QWidget * panel, const QPoint& pt)
{
QPoint _pt_local = m_pMainPanel->tabWidget()->tabBar()->mapFromGlobal(pt);
int _index = m_pMainPanel->tabWidget()->tabBar()->tabAt(_pt_local);
if ( !(_index < 0) ) {
QRect _rc_tab = m_pMainPanel->tabWidget()->tabBar()->tabRect(_index);
if ( _pt_local.x() > _rc_tab.left() + (_rc_tab.width() / 2) ) ++_index;
}
return attachEditor(panel, _index);
}
bool CMainWindow::moveByTab()
{
return mainPanel()->tabWidget()->count() == 1 &&
((CTabBar *)mainPanel()->tabWidget()->tabBar())->draggedTabIndex() == 0;
}
QWidget * CMainWindow::editorPanel(int index)
{
return m_pMainPanel->tabWidget()->releaseEditor(index);
}
bool CMainWindow::holdView(int id)
{
return m_pMainPanel->holdUid(id);
}
bool CMainWindow::pointInTabs(const QPoint& pt)
{
QRect _rc_title(m_pMainPanel->geometry());
_rc_title.setHeight(TITLE_HEIGHT * m_dpiRatio);
return _rc_title.contains(m_pMainPanel->mapFromGlobal(pt));
}
void CMainWindow::slot_windowChangeState(Qt::WindowState s)
{
int cmdShow = SW_RESTORE;
@ -726,52 +765,6 @@ void CMainWindow::slot_windowClose()
AscAppManager::closeMainWindow( size_t(this) );
}
void CMainWindow::slot_finalTabClosed()
{
qDebug() << "final tab close";
if ( AscAppManager::countMainWindow() > 1 ) {
AscAppManager::closeMainWindow( size_t(this) );
}
}
void CMainWindow::slot_undockWindow(QWidget * editorpanel)
{
QRect _win_rect;
QPoint _top_left;
bool _is_maximized = false;
WINDOWPLACEMENT wp{sizeof(WINDOWPLACEMENT)};
if (GetWindowPlacement(hWnd, &wp)) {
_is_maximized = wp.showCmd == SW_MAXIMIZE;
_top_left = QPoint(wp.rcNormalPosition.left, wp.rcNormalPosition.top);
_win_rect = QRect( _top_left, QPoint(wp.rcNormalPosition.right, wp.rcNormalPosition.bottom));
_win_rect.adjust(30,30,-1+30,-1+30);
}
CMainWindow * window = AscAppManager::createMainWindow(_win_rect);
window->show(_is_maximized);
window->toggleBorderless(_is_maximized);
window->joinTab(editorpanel);
if ( !_is_maximized ) {
QTimer::singleShot(0, [=]{
QPoint cursor = QCursor::pos() + QPoint(-120, -12);
QPoint pos;
SetWindowPos(HWND(window->hWnd), NULL, cursor.x(), cursor.y(), 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE);
QObject * _receiver = window->m_pWinPanel;
QMouseEvent * event = new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QApplication::postEvent(_receiver, event);
});
} else {
wp.rcNormalPosition = {_win_rect.x(), _win_rect.y(), _win_rect.right(), _win_rect.bottom()};
SetWindowPlacement(window->hWnd, &wp);
}
}
void CMainWindow::slot_mainPageReady()
{
CSplash::hideSplash();
@ -842,3 +835,29 @@ CMainPanel * CMainWindow::mainPanel() const
{
return m_pMainPanel;
}
QRect CMainWindow::windowRect() const
{
QRect _win_rect;
QPoint _top_left;
WINDOWPLACEMENT wp{sizeof(WINDOWPLACEMENT)};
if ( GetWindowPlacement(hWnd, &wp) ) {
_top_left = QPoint(wp.rcNormalPosition.left, wp.rcNormalPosition.top);
_win_rect = QRect( _top_left, QPoint(wp.rcNormalPosition.right, wp.rcNormalPosition.bottom));
}
return _win_rect;
}
bool CMainWindow::isMaximized() const
{
bool _is_maximized = false;
WINDOWPLACEMENT wp{sizeof(WINDOWPLACEMENT)};
if ( GetWindowPlacement(hWnd, &wp) ) {
_is_maximized = wp.showCmd == SW_MAXIMIZE;
}
return _is_maximized;
}

View File

@ -73,20 +73,23 @@ public:
void adjustGeometry();
bool holdView(int id);
int joinTab(QWidget *);
int attachEditor(QWidget *, int index = -1);
int attachEditor(QWidget *, const QPoint&);
QWidget * editorPanel(int);
bool pointInTabs(const QPoint&);
bool moveByTab();
CMainPanel * mainPanel() const;
QRect windowRect() const;
bool isMaximized() const;
private:
void setScreenScalingFactor(uchar);
void doClose();
void slot_undockWindow(QWidget *);
void slot_windowChangeState(Qt::WindowState);
void slot_windowClose();
void slot_mainPageReady();
void slot_finalTabClosed();
#ifdef _UPDMODULE
static void updateFound();