玉兔远程控制 0.1.0-bate11
载入中...
搜索中...
未找到
ViewSplitter.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include "ViewSplitter.h"
4#include <QVBoxLayout>
5#include <QLoggingCategory>
6#include <QEvent>
7#include <QTimer>
8#include "ViewSplitterContainer.h"
9
10static Q_LOGGING_CATEGORY(log, "App.View.Splitter")
11
12CViewSplitter::CViewSplitter(CParameterApp *pPara, QWidget *parent)
13 : CView(pPara, parent)
14 , m_nRow(0)
15 , m_nCount(0)
16 , m_nIdxRow(-1)
17 , m_nIdxCol(-1)
18{
19 qDebug(log) << Q_FUNC_INFO << this;
20
21 QVBoxLayout* p = new QVBoxLayout(this);
22 if(!p) {
23 qCritical(log) << "new QVBoxLayout fail";
24 return;
25 }
26 p->setContentsMargins(0, 0, 0, 0);
27 setLayout(p);
28 m_pMainSplitter = new QSplitter(Qt::Vertical, this);
29 if(!m_pMainSplitter) {
30 //m_pMain->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
31 qCritical(log) << "m_pMain is nullptr";
32 return;
33 }
34 p->addWidget(m_pMainSplitter);
35 m_HandleWidth = m_pMainSplitter->handleWidth();
36 /*
37 setStyleSheet("QWidget { background-color: red }");
38 m_pMain->setStyleSheet("QSplitter::handle { background-color: white }");//*/
39}
40
41CViewSplitter::~CViewSplitter()
42{
43 qDebug(log) << Q_FUNC_INFO << this;
44 for(int i = 0; i < m_nRow; i++)
45 {
46 auto sp = m_Row[i];
47 for(int j = 0; j < sp->count(); j++)
48 {
49 auto pw = sp->widget(j);
50 pw->setParent(nullptr);
51 }
52 }
53}
54
55int CViewSplitter::AddView(QWidget *pView)
56{
57 int nRet = 0;
58 QSplitter* sp = nullptr;
59 if(!pView) {
60 qCritical(log) << "The view is null";
61 Q_ASSERT(pView);
62 return -1;
63 }
64
65 //TODO: 增加检查 pView 是否已存在?
66
67 // 是否需要新增加一行
68 if(m_nCount + 1 > m_nRow * m_nRow) {
69 QSplitter* p = new QSplitter(Qt::Horizontal, m_pMainSplitter);
70 if(p) {
71 p->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
72 //p->setStyleSheet("QSplitter::handle { background-color: blue }");
73 m_Row.append(p);
74 m_nRow++;
75 }
76 }
77 // 顺序查找哪行没满,加到未尾
78 int i = 0;
79 for(i = 0; i < m_nRow; i++) {
80 auto p = m_Row[i];
81 if(p->count() < m_nRow) {
82 sp = p;
83 break;
84 }
85 }
86 if(!sp)
87 return nRet;
88
89 auto pContainer = new CViewSplitterContainer(pView, m_pParameterApp);
90 if(pContainer) {
91 // 设置当前视图索引
92 m_nIdxRow = i;
93 m_nIdxCol = sp->count();
94 sp->addWidget(pContainer);
95 pContainer->SetVisibleTab(m_pParameterApp->GetTabBar());
96 pContainer->show();
97 m_Container.insert(pView, pContainer);
98 ActiveContainer(pView);
99 bool check = connect(
100 pContainer,
101 SIGNAL(customContextMenuRequested(const QPoint&)),
102 this, SIGNAL(customContextMenuRequested(const QPoint&)));
103 Q_ASSERT(check);
104 check = connect(pContainer, &CViewSplitterContainer::sigFouceIn,
105 this, [&](QWidget* pView){
106 SetCurrentView(pView);
107 });
108 if(m_pParameterApp)
109 {
110 check = connect(m_pParameterApp, SIGNAL(sigTabPositionChanged()),
111 pContainer, SLOT(slotTabPositionChanged()));
112 Q_ASSERT(check);
113 check = connect(pContainer, SIGNAL(sigCloseView(const QWidget*)),
114 this, SIGNAL(sigCloseView(const QWidget*)));
115 Q_ASSERT(check);
116 }
117 m_nCount++;
118 } else
119 return -1;
120
121 SetSizes();
122
123 qDebug(log) << Q_FUNC_INFO << "Row:" << m_nRow << m_pMainSplitter->count() << "Count:" << m_nCount
124 << "Current row:" << m_nIdxRow << "Current col:" << m_nIdxCol
125 << "Current count:" << sp->count();
126 emit sigCurrentChanged(pView);
127 return nRet;
128}
129
130int CViewSplitter::RemoveView(QWidget *pView)
131{
132 int nRet = 0;
133 if(!pView)
134 return -1;
135
136 // Get view position
137 int nRow = -1;
138 int nCol = -1;
139 nRet = GetIndex(pView, nRow, nCol);
140 if(nRet)
141 return nRet;
142
143 CViewSplitterContainer* pContainerNext = nullptr;
144 QWidget* pCurView = GetCurrentView();
145 if(pView == pCurView)
146 {
147 // Get next
148 if(m_Row[nRow]->count() > nCol + 1)
149 pContainerNext = GetContainer(nRow, nCol + 1);
150 else if(m_Row[nRow]->count() - 1 == nCol && 0 != nCol)
151 pContainerNext = GetContainer(nRow, nCol -1);
152 else if(0 == nCol && nRow + 1 < m_nRow) {
153 for(int i = nRow + 1; i < m_nRow; i++) {
154 if(m_Row[i]->count() > 0) {
155 pContainerNext = GetContainer(nRow + 1, 0);
156 break;
157 }
158 }
159 }
160 if(!pContainerNext) {
161 for(int i = nRow - 1; i >= 0; i--) {
162 if(m_Row[i]->count() > 0) {
163 pContainerNext = GetContainer(i, m_Row[i]->count() - 1);
164 break;
165 }
166 }
167 }
168 }
169
170 // Delete view
171 pView->setParent(nullptr);
172 auto pContainer = GetContainer(pView);
173 if(pContainer) {
174 // Remove from QSplitter
175 pContainer->setParent(nullptr);
176 m_Container.remove(pView);
177 delete pContainer;
178 }
179 qDebug(log) << "Row:" << nRow << "remain:" << m_Row[nRow]->count();
180 m_nCount--;
181
182 qDebug(log) << "Row:" << m_nRow << "Count:" << m_nCount
183 << "Current row:" << m_nIdxRow << "Current col:" << m_nIdxCol;
184
185 if(pContainerNext) {
186 pCurView = pContainerNext->GetView();
187 // When full screen
188 if(pContainerNext->isHidden())
189 pContainerNext->show();
190 }
191 if(pCurView)
192 pCurView->setFocus();
193
194 return SetCurrentView(pCurView);
195}
196
198{
199 auto p = GetContainer(m_nIdxRow, m_nIdxCol);
200 if(p)
201 return p->GetView();
202 return nullptr;
203}
204
205int CViewSplitter::SetCurrentView(QWidget *pView)
206{
207 int nRet = 0;
208 if(!pView)
209 return -1;
210 int nRow = -1;
211 int nCol = -1;
212 nRet = GetIndex(pView, nRow, nCol);
213 if(nRet) return nRet;
214
215 if(m_nIdxCol == nCol && m_nIdxRow == nRow)
216 return 0;
217
218 m_nIdxRow = nRow;
219 m_nIdxCol = nCol;
220 pView->setFocus();
221 ActiveContainer(pView);
222 emit sigCurrentChanged(pView);
223
224 return nRet;
225}
226
227void CViewSplitter::SetWidowsTitle(
228 QWidget *pView, const QString &szTitle,
229 const QIcon &icon, const QString &szToolTip)
230{
231 if(!pView)
232 return;
233 auto pContainer = GetContainer(pView);
234 if(!pContainer)
235 return;
236 pContainer->setWindowTitle(szTitle);
237 if(m_pParameterApp->GetEnableTabIcon())
238 pContainer->setWindowIcon(icon);
239 else
240 pContainer->setWindowIcon(QIcon());
241 if(m_pParameterApp->GetEnableTabToolTip())
242 pContainer->SetPrompt(szToolTip);
243 else
244 pContainer->SetPrompt(QString());
245
246 SetSizes();
247}
248
249int CViewSplitter::SetFullScreen(bool bFull)
250{
251 int nRet = 0;
252 if(0 >= m_nCount) return 0;
253
254 if(m_pParameterApp && m_pParameterApp->GetKeepSplitViewWhenFullScreen())
255 return 0;
256
257 QWidget* p = GetCurrentView();
258 qDebug(log) << "CurrentView:" << p;
259 if(!p) return 0;
260 if(bFull) {
261 m_szStyleSheet = styleSheet();
262 //qDebug(log) << "Style:" << m_szStyleSheet;
263 setStyleSheet("QWidget::pane{top:0px;left:0px;border:none;}");
264 m_HandleWidth = m_pMainSplitter->handleWidth();
265 m_pMainSplitter->setHandleWidth(0);
266 for(int i = 0; i < m_nRow; i++) {
267 auto sp = m_Row[i];
268 if(!sp) {
269 qCritical(log) << "Row" << i << "is null";
270 continue;
271 }
272 sp->setHandleWidth(0);
273 for(int j = 0; j < m_nRow; j++) {
274 if(m_nIdxRow == i && m_nIdxCol == j) {
275 ActiveContainer(nullptr);
276 SetVisibleTab(false);
277 continue;
278 }
279 auto p = sp->widget(j);
280 if(p) {
281 p->hide();
282 } else {
283 qCritical(log) << "Widget: Row" << i << "Col" << j << "is null";
284 }
285 }
286 }
287 } else {
288 setStyleSheet(m_szStyleSheet);
289 m_pMainSplitter->setHandleWidth(m_HandleWidth);
290 for(int i = 0; i < m_nRow; i++) {
291 auto sp = m_Row[i];
292 sp->setHandleWidth(m_HandleWidth);
293 if(!sp) continue;
294 for(int j = 0; j < m_nRow; j++) {
295 auto p = sp->widget(j);
296 if(p) {
297 SetVisibleTab(m_pParameterApp->GetTabBar());
298 p->show();
299 if(m_nIdxRow == i && m_nIdxCol == j) {
300 CViewSplitterContainer* pView = qobject_cast<CViewSplitterContainer*>(p);
301 if(pView)
302 ActiveContainer(pView->GetView());
303 }
304 }
305 }
306 }
307 }
308 return nRet;
309}
310
311int CViewSplitter::SetVisibleTab(bool bVisible)
312{
313 foreach (auto c, m_Container) {
314 if(c)
315 c->SetVisibleTab(bVisible);
316 }
317 SetSizes();
318 return 0;
319}
320
321int CViewSplitter::GetIndex(QWidget* pView, int &nRow, int &nCol)
322{
323 if(!pView)
324 return -1;
325
326 nCol = -1;
327
328 auto pContainer = m_Container[pView];
329 for(nRow = 0; nRow < m_nRow; nRow++)
330 {
331 auto sp = m_Row[nRow];
332 if(!sp) continue;
333 nCol = sp->indexOf(pContainer);
334 if(-1 < nCol)
335 return 0;
336 }
337
338 return -1;
339}
340
341CViewSplitterContainer* CViewSplitter::GetContainer(const int &nRow, const int &nCol)
342{
343 QWidget* pContainer = nullptr;
344 QSplitter* sp = nullptr;
345 if(-1 < nRow && nRow < m_nRow)
346 sp = m_Row[nRow];
347 if(sp && -1 < nCol && nCol < sp->count())
348 pContainer = sp->widget(nCol);
349 qDebug(log) << "Container" << "Row number:" << m_nRow << m_Row.size()
350 << "Count:" << m_nCount
351 << "row:" << m_nIdxRow << "col:" << m_nIdxCol;
352 return qobject_cast<CViewSplitterContainer*>(pContainer);
353}
354
355CViewSplitterContainer* CViewSplitter::GetContainer(QWidget *pView)
356{
357 auto it = m_Container.find(pView);
358 if(m_Container.end() == it)
359 return nullptr;
360 return *it;
361}
362
364{
365 foreach (auto c, m_Container) {
366 if(!c) continue;
367 if(c->GetView() == pView && nullptr != pView) {
368 c->setFrameStyle(QFrame::Panel | QFrame::Raised);
369 c->setLineWidth(5);
370 c->setMidLineWidth(5);
371 } else {
372 c->setFrameStyle(QFrame::NoFrame);
373 c->setLineWidth(0);
374 c->setMidLineWidth(0);
375 }
376 }
377 return 0;
378}
379
380int CViewSplitter::SetSizes()
381{
382 int w = 0, h = 0;
383 if(0 == m_nCount)
384 return 0;
385
386 foreach(auto sp, m_Row) {
387 for(int i = 0; i < sp->count(); i++) {
388 auto pContainer = sp->widget(i);
389 if(pContainer) {
390 pContainer->adjustSize();
391 w = qMax(w, pContainer->frameGeometry().width());
392 h = qMax(h, pContainer->frameGeometry().height());
393 }
394 }
395 }
396
397 qDebug(log) << Q_FUNC_INFO << "Width:" << w << "Height:" << h;
398
399 QList<int> wSizes, hSizes;
400 foreach(auto sp, m_Row) {
401 wSizes.clear();
402 for(int i = 0; i < sp->count(); i++) {
403 wSizes.push_back(w);
404 }
405 sp->setSizes(wSizes);
406 qDebug(log) << Q_FUNC_INFO << "wSizes:" << wSizes << sp->sizes();
407 hSizes.push_back(h);
408 }
409 m_pMainSplitter->setSizes(hSizes);
410 qDebug(log) << Q_FUNC_INFO << "hSizes:" << hSizes << m_pMainSplitter->sizes();
411
412 return 0;
413}
The split view class
virtual int RemoveView(QWidget *pView) override
int ActiveContainer(QWidget *pView)
突出当前视图
virtual QWidget * GetCurrentView() override
virtual int AddView(QWidget *pView) override
The CView class
定义 View.h:25
void sigCloseView(const QWidget *pView)