Skip to content

Commit 3174d63

Browse files
committed
New Version. Incompatible API changes
Bumped version number to 0.2 Renamed API functions: (these are doing the same) getOpen --> getActive contentPaneOpened --> isActive contentPaneClosed --> isInactive Removed API functions: (these are no longer needed) closeContentPane openContentPane ContentPane::headerClicked is the new possibility to open/close ContentPanes programmatically. You have to check with getActive yourself before calling the function to see if the result is what you want it to be. Some code cleanup in internalAddContentPane and internalInsertContentPane. collapsible feature is now working. Signed-off-by: Christian Rapp <0x2a@posteo.org>
1 parent 2d4cb03 commit 3174d63

File tree

8 files changed

+99
-85
lines changed

8 files changed

+99
-85
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ option (QACCORDION_BUILD_TESTER OFF)
55
option (QACCORDION_EXTERNAL OFF)
66

77
set (qAccordion_VERSION_MAJOR 0)
8-
set (qAccordion_VERSION_MINOR 1)
8+
set (qAccordion_VERSION_MINOR 2)
99
set (qAccordion_VERSION_PATCH 0)
1010

1111
add_subdirectory(test)

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ If you find a Bug or have a feature request head over to github and open a new [
112112
## ToDo ##
113113
* Drag and Drop support. The API already supports moving Content Panes but only programmatically.
114114
* User defined Icons and Icon position.
115-
* Changable Animation Type
116-
* Maybe much, maybe nothing. So far it covers all my use cases ;)
115+
* Definable animation type.
116+
* Trigger open / close not only on single mouse click (e.g. double click, mouse over).
117117

118118
## FAQ ##
119119

@@ -137,4 +137,4 @@ GNU General Public License for more details.
137137
138138
You should have received a copy of the GNU General Public License
139139
along with this program. If not, see <http://www.gnu.org/licenses/>.
140-
`````
140+
`````

doc/main_page.dox

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* used in the demo application located in the test folder.
2424
*
2525
* ## License
26+
* ```
2627
* Copyright (C) 2015 Christian Rapp
2728
*
2829
* This program is free software: you can redistribute it and/or modify
@@ -37,5 +38,5 @@
3738
*
3839
* You should have received a copy of the GNU General Public License
3940
* along with this program. If not, see <http://www.gnu.org/licenses/>.
40-
*
41+
* ```
4142
*/

include/qAccordion/contentpane.h

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <memory>
3030

3131
#include "clickableframe.h"
32+
#include "qaccordion.h"
3233

3334
/**
3435
* @brief Content Pane class
@@ -78,10 +79,10 @@ class ContentPane : public QWidget
7879
explicit ContentPane(QString header, QFrame *content, QWidget *parent = 0);
7980

8081
/**
81-
* @brief Check if this Content pane is open
82-
* @return boolean True if open
82+
* @brief Check if this Content pane is active
83+
* @return boolean True if active
8384
*/
84-
bool getOpen();
85+
bool getActive();
8586

8687
/**
8788
* @brief Get the content frame of the content pane
@@ -233,41 +234,29 @@ class ContentPane : public QWidget
233234
uint getAnimationDuration();
234235

235236
signals:
237+
236238
/**
237239
* @brief Clicked signal is emitted when the header is clicked
238240
*/
239241
void clicked();
240242
/**
241243
* @brief Signal will be emitted after the open animation finished
242244
*/
243-
void contentPaneOpened();
245+
void isActive();
244246
/**
245247
* @brief Signal will be emitted after the close animation finished
246248
*/
247-
void contentPaneClosed();
249+
void isInactive();
248250

249251
public slots:
250252

251-
/**
252-
* @brief Open the content pane
253-
*
254-
* @details
255-
* This will open the content pane if it is currently closed.
256-
* @warning
257-
* Currently there is no inbuild mechanism to close an already open
258-
* Content Pane when you open another one programmatically. Meaning you have
259-
* to take care of this yourself.
260-
*/
261-
void openContentPane();
262-
/**
263-
* @brief Close the content pane
264-
*
265-
* @details
266-
* This will close the content pane if it is currently open.
267-
*/
268-
void closeContentPane();
253+
void headerClicked(QPoint pos);
269254

270255
private:
256+
// yeah we are friends. this is important to keep openContentPane and
257+
// closeContentPane private
258+
friend class QAccordion;
259+
271260
ClickableFrame *header;
272261
QFrame *container;
273262
QFrame *content;
@@ -276,7 +265,7 @@ public slots:
276265
int contentPaneFrameStyle;
277266
int containerAnimationMaxHeight;
278267

279-
bool open;
268+
bool active;
280269

281270
std::unique_ptr<QPropertyAnimation> openAnimation;
282271
std::unique_ptr<QPropertyAnimation> closeAnimation;
@@ -287,7 +276,25 @@ public slots:
287276
void initAnimations();
288277

289278
private slots:
290-
void clickableFrameClicked(QPoint pos);
279+
280+
/**
281+
* @brief Open the content pane
282+
*
283+
* @details
284+
* This will open the content pane if it is currently closed.
285+
* @warning
286+
* Currently there is no inbuild mechanism to close an already open
287+
* Content Pane when you open another one programmatically. Meaning you have
288+
* to take care of this yourself.
289+
*/
290+
void openContentPane();
291+
/**
292+
* @brief Close the content pane
293+
*
294+
* @details
295+
* This will close the content pane if it is currently open.
296+
*/
297+
void closeContentPane();
291298

292299
protected:
293300
/**

include/qAccordion/qaccordion.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include "config.h"
3636
#include "contentpane.h"
3737

38+
class ContentPane;
39+
3840
/**
3941
* @brief QAccordion base class
4042
*
@@ -365,6 +367,7 @@ public slots:
365367

366368
bool checkIndexError(uint index, bool sizeIndexAllowed,
367369
const QString &errMessage);
370+
void handleClickedSignal(ContentPane *cpane);
368371

369372
private slots:
370373
void numberOfPanesChanged(int number);

src/contentpane.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ ContentPane::ContentPane(QString header, QFrame *content, QWidget *parent)
3131
this->initDefaults(std::move(header));
3232
}
3333

34-
bool ContentPane::getOpen() { return this->open; }
34+
bool ContentPane::getActive() { return this->active; }
3535

3636
QFrame *ContentPane::getContentFrame() { return this->content; }
3737

@@ -51,7 +51,7 @@ void ContentPane::setMaximumHeight(int maxHeight)
5151
{
5252
this->containerAnimationMaxHeight = maxHeight;
5353

54-
if (this->open)
54+
if (this->getActive())
5555
this->container->setMaximumHeight(this->containerAnimationMaxHeight);
5656
this->openAnimation->setEndValue(this->containerAnimationMaxHeight);
5757
this->closeAnimation->setStartValue(this->containerAnimationMaxHeight);
@@ -110,25 +110,25 @@ int ContentPane::getContainerFrameStyle()
110110

111111
void ContentPane::openContentPane()
112112
{
113-
if (this->open)
113+
if (this->getActive())
114114
return;
115115
this->openAnimation->start();
116116
this->header->setCaretPixmap(clickcon::CARRET_ICON_OPENED);
117-
this->open = true;
117+
this->active = true;
118118
}
119119

120120
void ContentPane::closeContentPane()
121121
{
122-
if (!this->open)
122+
if (!this->getActive())
123123
return;
124124
this->closeAnimation->start();
125125
this->header->setCaretPixmap(clickcon::CARRET_ICON_CLOSED);
126-
this->open = false;
126+
this->active = false;
127127
}
128128

129129
void ContentPane::initDefaults(QString header)
130130
{
131-
this->open = false;
131+
this->active = false;
132132

133133
this->headerFrameStyle = QFrame::Shape::StyledPanel | QFrame::Shadow::Raised;
134134
this->contentPaneFrameStyle =
@@ -155,7 +155,7 @@ void ContentPane::initHeaderFrame(QString header)
155155
this->layout()->addWidget(this->header);
156156

157157
QObject::connect(this->header, &ClickableFrame::singleClick, this,
158-
&ContentPane::clickableFrameClicked);
158+
&ContentPane::headerClicked);
159159
}
160160

161161
void ContentPane::initContainerContentFrame()
@@ -201,10 +201,12 @@ void ContentPane::initAnimations()
201201
this->openAnimation->setEasingCurve(
202202
QEasingCurve(QEasingCurve::Type::Linear));
203203
this->closeAnimation->setEasingCurve(
204-
QEasingCurve(QEasingCurve::Type::Linear));
204+
QEasingCurve(QEasingCurve::Type::Linear));
205205
}
206206

207-
void ContentPane::clickableFrameClicked(__attribute__((unused)) QPoint pos) { emit this->clicked(); }
207+
void ContentPane::headerClicked(__attribute__((unused)) QPoint pos) {
208+
emit this->clicked();
209+
}
208210

209211
void ContentPane::paintEvent(__attribute__((unused)) QPaintEvent *event)
210212
{

src/qaccordion.cpp

Lines changed: 41 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ void QAccordion::getActiveContentPaneIndex(std::vector<int> &indexVector)
184184
indexVector.clear();
185185
std::for_each(this->contentPanes.begin(), this->contentPanes.end(),
186186
[&indexVector, this](ContentPane *pane) {
187-
if (pane->getOpen()) {
187+
if (pane->getActive()) {
188188
indexVector.push_back(
189189
this->findContentPaneIndex("", nullptr, pane));
190190
}
@@ -223,27 +223,8 @@ int QAccordion::internalAddContentPane(QString header, QFrame *cframe,
223223
this->contentPanes.push_back(cpane);
224224

225225
// manage the clicked signal in a lambda expression
226-
QObject::connect(cpane, &ContentPane::clicked, [this, cpane]() {
227-
// if the clicked content pane is open we simply close it and return
228-
if (cpane->getOpen()) {
229-
cpane->closeContentPane();
230-
return;
231-
}
232-
// if it is not open we will open it and search our vector for other
233-
// panes that are already open.
234-
// TODO: Is it really necessary to search for more than one open cpane?
235-
if (!cpane->getOpen()) {
236-
// check if multiActive is allowed
237-
if (!this->getMultiActive()) {
238-
std::for_each(this->contentPanes.begin(),
239-
this->contentPanes.end(), [](ContentPane *pane) {
240-
if (pane->getOpen())
241-
pane->closeContentPane();
242-
});
243-
}
244-
cpane->openContentPane();
245-
}
246-
});
226+
QObject::connect(cpane, &ContentPane::clicked,
227+
[this, cpane]() { this->handleClickedSignal(cpane); });
247228

248229
emit numberOfContentPanesChanged(this->contentPanes.size());
249230

@@ -276,29 +257,9 @@ bool QAccordion::internalInsertContentPane(uint index, QString header,
276257

277258
this->contentPanes.insert(this->contentPanes.begin() + index, cpane);
278259

279-
// TODO: This code has to be merged with internalAddContentPane.
280260
// manage the clicked signal in a lambda expression
281-
QObject::connect(cpane, &ContentPane::clicked, [this, cpane]() {
282-
// if the clicked content pane is open we simply close it and return
283-
if (cpane->getOpen()) {
284-
cpane->closeContentPane();
285-
return;
286-
}
287-
// if it is not open we will open it and search our vector for other
288-
// panes that are already open.
289-
// TODO: Is it really necessary to search for more than one open cpane?
290-
if (!cpane->getOpen()) {
291-
// check if multiActive is allowed
292-
if (!this->getMultiActive()) {
293-
std::for_each(this->contentPanes.begin(),
294-
this->contentPanes.end(), [](ContentPane *pane) {
295-
if (pane->getOpen())
296-
pane->closeContentPane();
297-
});
298-
}
299-
cpane->openContentPane();
300-
}
301-
});
261+
QObject::connect(cpane, &ContentPane::clicked,
262+
[this, cpane]() { this->handleClickedSignal(cpane); });
302263

303264
emit numberOfContentPanesChanged(this->contentPanes.size());
304265

@@ -404,6 +365,42 @@ bool QAccordion::checkIndexError(uint index, bool sizeIndexAllowed,
404365
return false;
405366
}
406367

368+
void QAccordion::handleClickedSignal(ContentPane *cpane)
369+
{
370+
// if the clicked content pane is open we simply close it and return
371+
if (cpane->getActive()) {
372+
// if collapsible and multiActive are false we are not allowed to close
373+
// this pane
374+
if (!this->collapsible && !this->multiActive) {
375+
return;
376+
}
377+
// when multiActive is true we have to check if there is any other open
378+
// cpane. if so we can close this one
379+
std::vector<int> activePanes;
380+
if (!this->collapsible) {
381+
this->getActiveContentPaneIndex(activePanes);
382+
if (activePanes.size() == 1)
383+
return; // only one active --> good bye :)
384+
}
385+
cpane->closeContentPane();
386+
return;
387+
}
388+
// if it is not open we will open it and search our vector for other
389+
// panes that are already open.
390+
// TODO: Is it really necessary to search for more than one open cpane?
391+
if (!cpane->getActive()) {
392+
// check if multiActive is allowed
393+
if (!this->getMultiActive()) {
394+
std::for_each(this->contentPanes.begin(), this->contentPanes.end(),
395+
[](ContentPane *pane) {
396+
if (pane->getActive())
397+
pane->closeContentPane();
398+
});
399+
}
400+
cpane->openContentPane();
401+
}
402+
}
403+
407404
void QAccordion::numberOfPanesChanged(int number)
408405
{
409406
// automatically open contentpane if we have only one and collapsible is

test/mainwindow.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ void MainWindow::networkRequestFinished(QNetworkReply *reply)
7272

7373
void MainWindow::contentPaneAdd(QAccordion *topAccordion)
7474
{
75+
ui->widgetControlAccordion->setCollapsible(false);
76+
// good pratice is to check the return value of addContentPane. see the API
77+
// Reference for more details
7578
int indexAddPane = ui->widgetControlAccordion->addContentPane("Add Pane");
7679

7780
// Get the content frame
@@ -187,7 +190,8 @@ void MainWindow::contentPaneRemove(QAccordion *topAccordion)
187190
topAccordion,
188191
this]() {
189192
if (headerName->text() != "") {
190-
bool status = topAccordion->removeContentPane(true, headerName->text());
193+
bool status =
194+
topAccordion->removeContentPane(true, headerName->text());
191195
if (status) {
192196
this->statusBar()->showMessage(
193197
"Content Pane \"" + headerName->text() + "\" removed", 3000);

0 commit comments

Comments
 (0)