玉兔远程控制 0.1.0-bate4
载入中...
搜索中...
未找到
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_pMain = new QSplitter(Qt::Vertical, this);
29 if(!m_pMain) {
30 m_pMain->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
31 qCritical(log) << "m_pMain is nullptr";
32 return;
33 }
34 p->addWidget(m_pMain);
35 m_HandleWidth = m_pMain->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_pMain);
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_pMain->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_pMain->handleWidth();
265 m_pMain->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 }
288 else {
289 setStyleSheet(m_szStyleSheet);
290 m_pMain->setHandleWidth(m_HandleWidth);
291 for(int i = 0; i < m_nRow; i++) {
292 auto sp = m_Row[i];
293 sp->setHandleWidth(m_HandleWidth);
294 if(!sp) continue;
295 for(int j = 0; j < m_nRow; j++) {
296 auto p = sp->widget(j);
297 if(p) {
298 SetVisibleTab(m_pParameterApp->GetTabBar());
299 p->show();
300 if(m_nIdxRow == i && m_nIdxCol == j) {
301 CViewSplitterContainer* pView = qobject_cast<CViewSplitterContainer*>(p);
302 if(pView)
303 ActiveContainer(pView->GetView());
304 }
305 }
306 }
307 }
308 }
309 return nRet;
310}
311
312int CViewSplitter::SetVisibleTab(bool bVisible)
313{
314 foreach (auto c, m_Container) {
315 if(c)
316 c->SetVisibleTab(bVisible);
317 }
318 SetSizes();
319 return 0;
320}
321
322int CViewSplitter::GetIndex(QWidget* pView, int &nRow, int &nCol)
323{
324 if(!pView)
325 return -1;
326
327 nCol = -1;
328
329 auto pContainer = m_Container[pView];
330 for(nRow = 0; nRow < m_nRow; nRow++)
331 {
332 auto sp = m_Row[nRow];
333 if(!sp) continue;
334 nCol = sp->indexOf(pContainer);
335 if(-1 < nCol)
336 return 0;
337 }
338
339 return -1;
340}
341
342CViewSplitterContainer* CViewSplitter::GetContainer(const int &nRow, const int &nCol)
343{
344 QWidget* pContainer = nullptr;
345 QSplitter* sp = nullptr;
346 if(-1 < nRow && nRow < m_nRow)
347 sp = m_Row[nRow];
348 if(sp && -1 < nCol && nCol < sp->count())
349 pContainer = sp->widget(nCol);
350 qDebug(log) << "Container" << "Row number:" << m_nRow << m_Row.size()
351 << "Count:" << m_nCount
352 << "row:" << m_nIdxRow << "col:" << m_nIdxCol;
353 return qobject_cast<CViewSplitterContainer*>(pContainer);
354}
355
356CViewSplitterContainer* CViewSplitter::GetContainer(QWidget *pView)
357{
358 auto it = m_Container.find(pView);
359 if(m_Container.end() == it)
360 return nullptr;
361 return *it;
362}
363
365{
366 foreach (auto c, m_Container) {
367 if(!c) continue;
368 if(c->GetView() == pView && nullptr != pView) {
369 c->setFrameStyle(QFrame::Panel|QFrame::Raised);
370 c->setLineWidth(5);
371 c->setMidLineWidth(5);
372 } else {
373 c->setFrameStyle(QFrame::NoFrame);
374 c->setLineWidth(0);
375 c->setMidLineWidth(0);
376 }
377 }
378 return 0;
379}
380
381int CViewSplitter::SetSizes()
382{
383 int w = 0, h = 0;
384 if(0 == m_nCount)
385 return 0;
386 foreach(auto sp, m_Row) {
387 for(int i = 0; i < sp->count(); i++) {
388 auto pContainer = sp->widget(i);
389 w = qMax(w, pContainer->frameGeometry().width());
390 h = qMax(h, pContainer->frameGeometry().height());
391 }
392 }
393
394 qDebug(log) << "Width:" << w << "Height:" << h;
395
396 QList<int> wSizes, hSizes;
397 foreach(auto sp, m_Row) {
398 wSizes.clear();
399 for(int i = 0; i < sp->count(); i++) {
400 wSizes.push_back(w);
401 }
402 sp->setSizes(wSizes);
403 qDebug(log) << "wSizes:" << wSizes << sp->sizes();
404 hSizes.push_back(h);
405 }
406 m_pMain->setSizes(hSizes);
407 qDebug(log) << "hSizes:" << hSizes << m_pMain->sizes();
408
409 return 0;
410}
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
Definition View.h:25
void sigCloseView(const QWidget *pView)