1 /***
2 
3     Olive - Non-Linear Video Editor
4     Copyright (C) 2019  Olive Team
5 
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 
19 ***/
20 
21 #include "collapsiblewidget.h"
22 
23 #include <QDebug>
24 #include <QLabel>
25 #include <QLayout>
26 #include <QHBoxLayout>
27 #include <QVBoxLayout>
28 #include <QPushButton>
29 #include <QMouseEvent>
30 #include <QWidget>
31 #include <QPainter>
32 
33 #include "ui/icons.h"
34 #include "global/debug.h"
35 
CollapsibleWidget(QWidget * parent)36 CollapsibleWidget::CollapsibleWidget(QWidget* parent) : QWidget(parent) {
37   selected = false;
38 
39   layout = new QVBoxLayout(this);
40   layout->setMargin(0);
41   layout->setSpacing(0);
42 
43   title_bar = new CollapsibleWidgetHeader(this);
44   title_bar->setFocusPolicy(Qt::ClickFocus);
45   title_bar->setAutoFillBackground(true);
46   title_bar_layout = new QHBoxLayout(title_bar);
47   title_bar_layout->setMargin(5);
48   enabled_check = new QCheckBox(title_bar);
49   enabled_check->setChecked(true);
50   header = new QLabel(title_bar);
51   collapse_button = new QPushButton(title_bar);
52   collapse_button->setIconSize(collapse_button->iconSize()*0.5);
53   collapse_button->setFlat(true);
54   SetTitle(tr("<untitled>"));
55   title_bar_layout->addWidget(collapse_button);
56   title_bar_layout->addWidget(enabled_check);
57   title_bar_layout->addWidget(header);
58   title_bar_layout->addStretch();
59   layout->addWidget(title_bar);
60 
61   connect(title_bar, SIGNAL(select(bool, bool)), this, SLOT(header_click(bool, bool)));
62 
63   set_button_icon(true);
64 
65   contents = nullptr;
66 }
67 
header_click(bool s,bool deselect)68 void CollapsibleWidget::header_click(bool s, bool deselect) {
69   selected = s;
70   title_bar->selected = s;
71   if (s) {
72     QPalette p = title_bar->palette();
73     p.setColor(QPalette::Background, QColor(255, 255, 255, 64));
74     title_bar->setPalette(p);
75   } else {
76     title_bar->setPalette(palette());
77   }
78   if (deselect) emit deselect_others(this);
79 }
80 
IsFocused()81 bool CollapsibleWidget::IsFocused() {
82   if (hasFocus()) return true;
83   return title_bar->hasFocus();
84 }
85 
IsExpanded()86 bool CollapsibleWidget::IsExpanded() {
87   return contents->isVisible();
88 }
89 
SetExpanded(bool s)90 void CollapsibleWidget::SetExpanded(bool s)
91 {
92   contents->setVisible(s);
93   set_button_icon(s);
94   emit visibleChanged(s);
95 }
96 
IsSelected()97 bool CollapsibleWidget::IsSelected()
98 {
99   return selected;
100 }
101 
set_button_icon(bool open)102 void CollapsibleWidget::set_button_icon(bool open) {
103   collapse_button->setIcon(open ? olive::icon::DownArrow : olive::icon::RightArrow);
104 }
105 
SetContents(QWidget * c)106 void CollapsibleWidget::SetContents(QWidget* c) {
107   bool existing = (contents != nullptr);
108   contents = c;
109   if (!existing) {
110     layout->addWidget(contents);
111     connect(enabled_check, SIGNAL(toggled(bool)), contents, SLOT(setEnabled(bool)));
112     connect(collapse_button, SIGNAL(clicked()), this, SLOT(on_visible_change()));
113   }
114 }
115 
Title()116 QString CollapsibleWidget::Title()
117 {
118   return header->text();
119 }
120 
SetTitle(const QString & s)121 void CollapsibleWidget::SetTitle(const QString &s) {
122   header->setText(s);
123 }
124 
on_visible_change()125 void CollapsibleWidget::on_visible_change() {
126   SetExpanded(!IsExpanded());
127 }
128 
CollapsibleWidgetHeader(QWidget * parent)129 CollapsibleWidgetHeader::CollapsibleWidgetHeader(QWidget* parent) : QWidget(parent), selected(false) {
130   setContextMenuPolicy(Qt::CustomContextMenu);
131 }
132 
mousePressEvent(QMouseEvent * event)133 void CollapsibleWidgetHeader::mousePressEvent(QMouseEvent* event) {
134   if (selected) {
135     if ((event->modifiers() & Qt::ShiftModifier)) {
136       selected = false;
137       emit select(selected, false);
138     }
139   } else {
140     selected = true;
141     emit select(selected, !(event->modifiers() & Qt::ShiftModifier));
142   }
143 }
144 
paintEvent(QPaintEvent * event)145 void CollapsibleWidgetHeader::paintEvent(QPaintEvent *event) {
146   QWidget::paintEvent(event);
147   QPainter p(this);
148   p.setPen(Qt::white);
149   int line_y = height() - 1;
150   p.drawLine(0, line_y, width(), line_y);
151 }
152