1 #include <Gui/Widgets/ControlPanel.hpp>
3 #include <Gui/Widgets/MatrixEditor.hpp>
5 #include <PowerSlider/PowerSlider.hpp>
8 #include <QColorDialog>
11 #include <QFileDialog>
13 #include <QPlainTextEdit>
14 #include <QPushButton>
16 #include <QVBoxLayout>
18 namespace Ra::Gui::Widgets {
22 setObjectName( name.c_str() );
24 m_currentLayout =
new QVBoxLayout(
this );
25 setLayout( m_currentLayout );
27 auto panelName =
new QLabel(
this );
28 if ( !name.empty() ) {
29 panelName->setText( name.c_str() );
32 panelName->setFrameStyle( QFrame::Box );
34 else { panelName->setFrameStyle( QFrame::HLine ); }
35 m_currentLayout->addWidget( panelName );
39 m_layouts.push( m_currentLayout );
44 std::function<
void(
bool )> callback,
46 const std::string& tooltip ) {
47 auto button =
new QCheckBox( name.c_str(),
this );
48 button->setLayoutDirection( Qt::RightToLeft );
49 button->setAutoExclusive(
false );
50 button->setChecked( set );
51 if ( !tooltip.empty() ) {
53 QString(
"<qt>%1</qt>" ).arg( QString( tooltip.c_str() ).toHtmlEscaped() ) );
55 m_currentLayout->addWidget( button );
56 connect( button, &QCheckBox::stateChanged, std::move( callback ) );
60 auto label =
new QLabel( text.c_str(),
nullptr );
61 m_currentLayout->addWidget( label );
65 std::function<
void()> callback,
66 const std::string& tooltip ) {
67 auto button =
new QPushButton( name.c_str(),
nullptr );
68 if ( !tooltip.empty() ) {
70 QString(
"<qt>%1</qt>" ).arg( QString( tooltip.c_str() ).toHtmlEscaped() ) );
72 m_currentLayout->addWidget( button );
73 connect( button, &QPushButton::clicked, std::move( callback ) );
77 std::function<
void(
int )> callback,
81 const std::string& tooltip ) {
82 auto inputLayout =
new QHBoxLayout();
83 auto inputLabel =
new QLabel( tr( name.c_str() ),
this );
84 inputLayout->addWidget( inputLabel );
85 inputLayout->addStretch();
86 auto sliderLayout =
new QHBoxLayout();
87 auto inputField =
new QSlider( Qt::Horizontal,
this );
88 if ( !tooltip.empty() ) {
89 inputLabel->setToolTip(
90 QString(
"<qt>%1</qt>" ).arg( QString( tooltip.c_str() ).toHtmlEscaped() ) );
92 auto spinbox =
new QSpinBox(
this );
93 inputField->setRange( min, max );
94 inputField->setValue( initial );
95 inputField->setTickPosition( QSlider::TicksAbove );
96 inputField->setTickInterval( 1 );
97 inputField->setFocusPolicy( Qt::StrongFocus );
98 spinbox->setRange( min, max );
99 spinbox->setValue( initial );
100 connect( inputField, &QSlider::valueChanged, spinbox, &QSpinBox::setValue );
103 spinbox, QOverload<int>::of( &QSpinBox::valueChanged ), inputField, &QSlider::setValue );
104 connect( inputField, &QSlider::valueChanged, std::move( callback ) );
105 sliderLayout->addWidget( inputField );
106 sliderLayout->addWidget( spinbox );
107 inputLayout->addLayout( sliderLayout );
108 m_currentLayout->addLayout( inputLayout );
112 std::function<
void(
double )> callback,
116 const std::string& tooltip ) {
117 auto inputLayout =
new QHBoxLayout();
118 auto inputLabel =
new QLabel( tr( name.c_str() ),
this );
119 auto inputField =
new PowerSlider();
120 if ( !tooltip.empty() ) {
121 inputLabel->setToolTip(
122 QString(
"<qt>%1</qt>" ).arg( QString( tooltip.c_str() ).toHtmlEscaped() ) );
124 inputField->setObjectName( name.c_str() );
125 inputField->setRange( min, max );
126 inputField->setValue( initial );
127 inputField->setSingleStep( 0.01 );
128 inputLayout->addWidget( inputLabel );
129 inputLayout->addStretch();
130 inputLayout->addWidget( inputField );
131 connect( inputField, &PowerSlider::valueChanged, std::move( callback ) );
132 m_currentLayout->addLayout( inputLayout );
136 std::function<
void(
const Ra::Core::MatrixN& )> callback,
137 const Ra::Core::MatrixN& initial,
139 const std::string& tooltip ) {
140 auto inputLayout =
new QHBoxLayout();
142 auto inputLabel =
new QLabel( tr( name.c_str() ),
this );
143 auto inputField =
new MatrixEditor( initial, dec,
this );
145 if ( !tooltip.empty() ) {
146 inputLabel->setToolTip(
147 QString(
"<qt>%1</qt>" ).arg( QString( tooltip.c_str() ).toHtmlEscaped() ) );
149 inputLayout->addWidget( inputLabel );
150 inputLayout->addWidget( inputField );
151 connect( inputField, &MatrixEditor::valueChanged, std::move( callback ) );
152 m_currentLayout->addLayout( inputLayout );
156 const std::string& name,
160 const std::string& tooltip ) {
161 auto button =
new QPushButton( name.c_str(),
this );
163 auto clrBttn = QColor::fromRgbF( srgbColor[0], srgbColor[1], srgbColor[2], srgbColor[3] );
164 auto clrDlg = [callback, clrBttn, withAlpha, button, name]()
mutable {
165 clrBttn = QColorDialog::getColor(
169 ( withAlpha ? QColorDialog::ShowAlphaChannel : QColorDialog::ColorDialogOptions() )
171 | QColorDialog::DontUseNativeDialog
174 if ( clrBttn.isValid() ) {
176 auto lum = 0.2126_ra * Scalar( clrBttn.redF() ) +
177 0.7151_ra * Scalar( clrBttn.greenF() ) +
178 0.0721_ra * Scalar( clrBttn.blueF() );
181 Scalar( clrBttn.greenF() ),
182 Scalar( clrBttn.blueF() ),
183 Scalar( clrBttn.alphaF() ) ) );
185 QString qss = QString(
"background-color: %1" ).arg( clrBttn.name() );
186 if ( lum > 1_ra / 3_ra ) { qss += QString(
"; color: #000000" ); }
187 else { qss += QString(
"; color: #FFFFFF" ); }
188 button->setStyleSheet( qss );
192 if ( !tooltip.empty() ) {
194 QString(
"<qt>%1</qt>" ).arg( QString( tooltip.c_str() ).toHtmlEscaped() ) );
198 auto lum = 0.2126_ra * srgbColor[0] + 0.7151_ra * srgbColor[1] + 0.0721_ra * srgbColor[2];
199 QString qss = QString(
"background-color: %1" ).arg( clrBttn.name() );
200 if ( lum > 1_ra / 3_ra ) { qss += QString(
"; color: #000000" ); }
201 else { qss += QString(
"; color: #FFFFFF" ); }
202 button->setStyleSheet( qss );
204 connect( button, &QPushButton::clicked, clrDlg );
205 m_currentLayout->addWidget( button );
209 std::function<
void( std::string )> callback,
210 const std::string& rootDirectory,
211 const std::string& filters,
212 const std::string& tooltip ) {
214 auto openFile = [
this, callback, rootDirectory, filters]() {
215 auto fltrs = QString::fromStdString( filters );
216 auto pathList = QFileDialog::getOpenFileNames(
217 this,
"Open files", QString::fromStdString( rootDirectory ), fltrs );
218 if ( !pathList.empty() ) {
219 std::string fileList;
220 for (
const auto& file : pathList ) {
221 fileList += file.toStdString() +
";";
223 fileList.erase( fileList.size() - 1 );
224 callback( fileList );
226 else { callback(
"" ); }
233 std::function<
void( std::string )> callback,
234 const std::string& rootDirectory,
235 const std::string& filters,
236 const std::string& tooltip ) {
238 auto saveFile = [
this, callback, rootDirectory, filters]() {
239 auto fltrs = QString::fromStdString( filters );
240 auto filename = QFileDialog::getSaveFileName(
241 this,
"Save file", QString::fromStdString( rootDirectory ), fltrs );
242 if ( !filename.isEmpty() ) { callback( filename.toStdString() ); }
248 m_layouts.push( m_currentLayout );
249 m_currentLayout =
new QBoxLayout( dir );
253 m_layouts.top()->addLayout( m_currentLayout );
254 m_currentLayout = m_layouts.top();
260 QFrame* line =
new QFrame();
261 switch ( m_currentLayout->direction() ) {
262 case QBoxLayout::LeftToRight:
263 case QBoxLayout::RightToLeft:
264 line->setFrameShape( QFrame::VLine );
266 case QBoxLayout::TopToBottom:
267 case QBoxLayout::BottomToTop:
268 line->setFrameShape( QFrame::HLine );
271 line->setFrameShape( QFrame::HLine );
273 line->setFrameShadow( QFrame::Sunken );
274 m_currentLayout->addWidget( line );
278 std::function<
void(
int )> callback,
280 const std::vector<std::string>& items,
281 const std::string& tooltip ) {
282 auto inputLayout =
new QHBoxLayout();
283 auto inputLabel =
new QLabel( tr( name.c_str() ),
this );
284 auto inputField =
new QComboBox(
this );
285 for (
auto v : items ) {
286 inputField->addItem( QString::fromStdString( v ) );
288 if ( !tooltip.empty() ) {
289 inputLabel->setToolTip(
290 QString(
"<qt>%1</qt>" ).arg( QString( tooltip.c_str() ).toHtmlEscaped() ) );
292 inputField->setCurrentIndex( initial );
293 inputLayout->addWidget( inputLabel );
294 inputLayout->addWidget( inputField );
296 inputField, QOverload<int>::of( &QComboBox::currentIndexChanged ), std::move( callback ) );
297 m_currentLayout->addLayout( inputLayout );
301 std::function<
void(
const QString& )> callback,
302 const std::string& initial,
303 const std::vector<std::string>& items,
304 const std::string& tooltip ) {
305 auto inputLayout =
new QHBoxLayout();
306 auto inputLabel =
new QLabel( tr( name.c_str() ),
this );
307 auto inputField =
new QComboBox(
this );
308 for (
auto v : items ) {
309 inputField->addItem( QString::fromStdString( v ) );
311 if ( !tooltip.empty() ) {
312 inputLabel->setToolTip(
313 QString(
"<qt>%1</qt>" ).arg( QString( tooltip.c_str() ).toHtmlEscaped() ) );
315 inputField->setCurrentText( QString::fromStdString( initial ) );
316 inputLayout->addWidget( inputLabel );
317 inputLayout->addWidget( inputField );
319 QOverload<const QString&>::of( &QComboBox::currentTextChanged ),
320 std::move( callback ) );
321 m_currentLayout->addLayout( inputLayout );
325 m_currentLayout->addStretch( stretch );
329 m_currentLayout->addWidget( newWidget );
static ColorBase sRGBToLinearRGB(const ColorBase &srgb)
convert the color expressed in sRGB color space to linear RGB
static ColorBase linearRGBTosRGB(const ColorBase &lrgb)
convert the color expressed in linear RGB color space to sRGB