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