diff --git a/effects/effects.h b/effects/effects.h index 247cf5bb6..b2d5396ed 100644 --- a/effects/effects.h +++ b/effects/effects.h @@ -6,6 +6,7 @@ #include class QSpinBox; class QCheckBox; +class LabelSlider; enum VideoEffects { VIDEO_TRANSFORM_EFFECT, @@ -31,15 +32,15 @@ public: void process_gl(int* anchor_x, int* anchor_y); Effect* copy(Clip* c); - QSpinBox* position_x; - QSpinBox* position_y; - QSpinBox* scale_x; - QSpinBox* scale_y; + LabelSlider* position_x; + LabelSlider* position_y; + LabelSlider* scale_x; + LabelSlider* scale_y; QCheckBox* uniform_scale_box; - QSpinBox* rotation; - QSpinBox* anchor_x_box; - QSpinBox* anchor_y_box; - QSpinBox* opacity; + LabelSlider* rotation; + LabelSlider* anchor_x_box; + LabelSlider* anchor_y_box; + LabelSlider* opacity; public slots: void toggle_uniform_scale(bool enabled); private: @@ -56,7 +57,7 @@ public: void load(QXmlStreamReader* stream); void save(QXmlStreamWriter* stream); - QSpinBox* volume_val; + LabelSlider* volume_val; }; class PanEffect : public Effect { @@ -67,7 +68,7 @@ public: void load(QXmlStreamReader* stream); void save(QXmlStreamWriter* stream); - QSpinBox* pan_val; + LabelSlider* pan_val; }; #endif // EFFECTS_H diff --git a/effects/paneffect.cpp b/effects/paneffect.cpp index 3a779939e..e11bf9de0 100644 --- a/effects/paneffect.cpp +++ b/effects/paneffect.cpp @@ -1,10 +1,10 @@ #include "effects/effects.h" #include -#include #include #include +#include "ui/labelslider.h" #include "ui/collapsiblewidget.h" PanEffect::PanEffect(Clip* c) : Effect(c) { @@ -13,9 +13,9 @@ PanEffect::PanEffect(Clip* c) : Effect(c) { QGridLayout* ui_layout = new QGridLayout(); ui_layout->addWidget(new QLabel("Pan:"), 0, 0); - pan_val = new QSpinBox(); - pan_val->setMinimum(-100); - pan_val->setMaximum(100); + pan_val = new LabelSlider(); + pan_val->set_minimum_value(-100); + pan_val->set_maximum_value(100); ui_layout->addWidget(pan_val, 0, 1); ui->setLayout(ui_layout); @@ -23,12 +23,12 @@ PanEffect::PanEffect(Clip* c) : Effect(c) { container->setContents(ui); // set defaults - pan_val->setValue(0); + pan_val->set_value(0); } Effect* PanEffect::copy(Clip* c) { PanEffect* p = new PanEffect(c); - p->pan_val->setValue(pan_val->value()); + p->pan_val->set_value(pan_val->value()); return p; } @@ -37,7 +37,7 @@ void PanEffect::load(QXmlStreamReader *stream) { stream->readNext(); if (stream->isStartElement() && stream->name() == "pan") { stream->readNext(); - pan_val->setValue(stream->text().toInt()); + pan_val->set_value(stream->text().toInt()); } } } diff --git a/effects/transformeffect.cpp b/effects/transformeffect.cpp index d9a724e24..8500fc64a 100644 --- a/effects/transformeffect.cpp +++ b/effects/transformeffect.cpp @@ -12,6 +12,7 @@ #include "project/clip.h" #include "project/sequence.h" #include "io/media.h" +#include "ui/labelslider.h" TransformEffect::TransformEffect(Clip* c) : Effect(c) { setup_effect(EFFECT_TYPE_VIDEO, VIDEO_TRANSFORM_EFFECT); @@ -19,23 +20,20 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c) { QGridLayout* ui_layout = new QGridLayout(); ui_layout->addWidget(new QLabel("Position:"), 0, 0); - position_x = new QSpinBox(); - position_x->setMinimum(-QWIDGETSIZE_MAX); - position_x->setMaximum(QWIDGETSIZE_MAX); - ui_layout->addWidget(position_x, 0, 1); - position_y = new QSpinBox(); - position_y->setMinimum(-QWIDGETSIZE_MAX); - position_y->setMaximum(QWIDGETSIZE_MAX); + position_x = new LabelSlider(); + ui_layout->addWidget(position_x, 0, 1); + + position_y = new LabelSlider(); ui_layout->addWidget(position_y, 0, 2); ui_layout->addWidget(new QLabel("Scale:"), 1, 0); - scale_x = new QSpinBox(); - scale_x->setMinimum(0); - scale_x->setMaximum(1200); + scale_x = new LabelSlider(); + scale_x->set_minimum_value(0); + scale_x->set_maximum_value(1200); ui_layout->addWidget(scale_x, 1, 1); - scale_y = new QSpinBox(); - scale_y->setMinimum(0); - scale_y->setMaximum(1200); + scale_y = new LabelSlider(); + scale_y->set_minimum_value(0); + scale_y->set_maximum_value(1200); ui_layout->addWidget(scale_y, 1, 2); uniform_scale_box = new QCheckBox(); @@ -43,25 +41,19 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c) { ui_layout->addWidget(uniform_scale_box, 2, 1); ui_layout->addWidget(new QLabel("Rotation:"), 3, 0); - rotation = new QSpinBox(); - rotation->setMinimum(-QWIDGETSIZE_MAX); - rotation->setMaximum(QWIDGETSIZE_MAX); + rotation = new LabelSlider(); ui_layout->addWidget(rotation, 3, 1); ui_layout->addWidget(new QLabel("Anchor Point:"), 4, 0); - anchor_x_box = new QSpinBox(); - anchor_x_box->setMinimum(-QWIDGETSIZE_MAX); - anchor_x_box->setMaximum(QWIDGETSIZE_MAX); + anchor_x_box = new LabelSlider(); ui_layout->addWidget(anchor_x_box, 4, 1); - anchor_y_box = new QSpinBox(); - anchor_y_box->setMinimum(-QWIDGETSIZE_MAX); - anchor_y_box->setMaximum(QWIDGETSIZE_MAX); + anchor_y_box = new LabelSlider(); ui_layout->addWidget(anchor_y_box, 4, 2); ui_layout->addWidget(new QLabel("Opacity:"), 5, 0); - opacity = new QSpinBox(); - opacity->setMinimum(0); - opacity->setMaximum(100); + opacity = new LabelSlider(); + opacity->set_minimum_value(0); + opacity->set_maximum_value(100); ui_layout->addWidget(opacity, 5, 1); ui->setLayout(ui_layout); @@ -69,41 +61,41 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c) { container->setContents(ui); // set defaults - position_x->setValue(c->sequence->width/2); - position_y->setValue(c->sequence->height/2); - scale_x->setValue(100); - scale_y->setValue(100); + position_x->set_default_value(c->sequence->width/2); + position_y->set_default_value(c->sequence->height/2); + scale_x->set_default_value(100); + scale_y->set_default_value(100); scale_y->setEnabled(false); uniform_scale_box->setChecked(true); default_anchor_x = c->media_stream->video_width/2; default_anchor_y = c->media_stream->video_height/2; - anchor_x_box->setValue(default_anchor_x); - anchor_y_box->setValue(default_anchor_y); - opacity->setValue(100); + anchor_x_box->set_default_value(default_anchor_x); + anchor_y_box->set_default_value(default_anchor_y); + opacity->set_default_value(100); - connect(position_x, SIGNAL(valueChanged(int)), this, SLOT(field_changed())); - connect(position_y, SIGNAL(valueChanged(int)), this, SLOT(field_changed())); - connect(rotation, SIGNAL(valueChanged(int)), this, SLOT(field_changed())); - connect(scale_x, SIGNAL(valueChanged(int)), this, SLOT(field_changed())); - connect(scale_y, SIGNAL(valueChanged(int)), this, SLOT(field_changed())); - connect(anchor_x_box, SIGNAL(valueChanged(int)), this, SLOT(field_changed())); - connect(anchor_y_box, SIGNAL(valueChanged(int)), this, SLOT(field_changed())); - connect(opacity, SIGNAL(valueChanged(int)), this, SLOT(field_changed())); + connect(position_x, SIGNAL(valueChanged()), this, SLOT(field_changed())); + connect(position_y, SIGNAL(valueChanged()), this, SLOT(field_changed())); + connect(rotation, SIGNAL(valueChanged()), this, SLOT(field_changed())); + connect(scale_x, SIGNAL(valueChanged()), this, SLOT(field_changed())); + connect(scale_y, SIGNAL(valueChanged()), this, SLOT(field_changed())); + connect(anchor_x_box, SIGNAL(valueChanged()), this, SLOT(field_changed())); + connect(anchor_y_box, SIGNAL(valueChanged()), this, SLOT(field_changed())); + connect(opacity, SIGNAL(valueChanged()), this, SLOT(field_changed())); connect(uniform_scale_box, SIGNAL(toggled(bool)), this, SLOT(toggle_uniform_scale(bool))); connect(uniform_scale_box, SIGNAL(toggled(bool)), this, SLOT(field_changed())); } Effect* TransformEffect::copy(Clip* c) { TransformEffect* t = new TransformEffect(c); - t->position_x->setValue(position_x->value()); - t->position_y->setValue(position_y->value()); - t->scale_x->setValue(scale_x->value()); - t->scale_y->setValue(scale_y->value()); + t->position_x->set_value(position_x->value()); + t->position_y->set_value(position_y->value()); + t->scale_x->set_value(scale_x->value()); + t->scale_y->set_value(scale_y->value()); t->uniform_scale_box->setChecked(uniform_scale_box->isChecked()); - t->rotation->setValue(rotation->value()); - t->anchor_x_box->setValue(anchor_x_box->value()); - t->anchor_y_box->setValue(anchor_y_box->value()); - t->opacity->setValue(opacity->value()); + t->rotation->set_value(rotation->value()); + t->anchor_x_box->set_value(anchor_x_box->value()); + t->anchor_y_box->set_value(anchor_y_box->value()); + t->opacity->set_value(opacity->value()); return t; } diff --git a/effects/volumeeffect.cpp b/effects/volumeeffect.cpp index a3c59fb56..977c18333 100644 --- a/effects/volumeeffect.cpp +++ b/effects/volumeeffect.cpp @@ -1,10 +1,10 @@ #include "effects/effects.h" #include -#include #include #include +#include "ui/labelslider.h" #include "ui/collapsiblewidget.h" VolumeEffect::VolumeEffect(Clip* c) : Effect(c) { @@ -13,9 +13,9 @@ VolumeEffect::VolumeEffect(Clip* c) : Effect(c) { QGridLayout* ui_layout = new QGridLayout(); ui_layout->addWidget(new QLabel("Volume:"), 0, 0); - volume_val = new QSpinBox(); - volume_val->setMinimum(0); - volume_val->setMaximum(400); + volume_val = new LabelSlider(); + volume_val->set_minimum_value(0); + volume_val->set_maximum_value(400); ui_layout->addWidget(volume_val, 0, 1); ui->setLayout(ui_layout); @@ -23,12 +23,12 @@ VolumeEffect::VolumeEffect(Clip* c) : Effect(c) { container->setContents(ui); // set defaults - volume_val->setValue(100); + volume_val->set_value(100); } Effect* VolumeEffect::copy(Clip* c) { VolumeEffect* v = new VolumeEffect(c); - v->volume_val->setValue(volume_val->value()); + v->volume_val->set_value(volume_val->value()); return v; } @@ -37,7 +37,7 @@ void VolumeEffect::load(QXmlStreamReader* stream) { stream->readNext(); if (stream->isStartElement() && stream->name() == "volume") { stream->readNext(); - volume_val->setValue(stream->text().toInt()); + volume_val->set_value(stream->text().toInt()); } } } diff --git a/io/media.cpp b/io/media.cpp index 5c0da7d43..04c1bb2fe 100644 --- a/io/media.cpp +++ b/io/media.cpp @@ -1,5 +1,7 @@ #include "media.h" +#include + extern "C" { #include } @@ -22,3 +24,12 @@ Media::~Media() { long Media::get_length_in_frames(float frame_rate) { return ceil((float) length / (float) AV_TIME_BASE * frame_rate); } + +int guess_layout_from_channels(int channel_count) { + if (channel_count == 1) { + return AV_CH_LAYOUT_MONO; + } else { + qDebug() << "[WARNING] Could not detect audio channel layout - assuming stereo"; + return AV_CH_LAYOUT_STEREO; + } +} diff --git a/io/media.h b/io/media.h index d82870380..3d6b2caf4 100644 --- a/io/media.h +++ b/io/media.h @@ -40,4 +40,6 @@ struct Media long get_length_in_frames(float frame_rate); }; +int guess_layout_from_channels(int channel_count); + #endif // MEDIA_H diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index 7b9994040..f1bc569f9 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -51,6 +51,12 @@ void PreviewGenerator::run() { codec_ctx[i] = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codec_ctx[i], fmt_ctx->streams[i]->codecpar); avcodec_open2(codec_ctx[i], codec, NULL); + + if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + if (codec_ctx[i]->channel_layout == 0) { + codec_ctx[i]->channel_layout = guess_layout_from_channels(fmt_ctx->streams[i]->codecpar->channels); + } + } } AVPacket packet; bool done = true; diff --git a/olive.pro b/olive.pro index 4c714479c..da149b355 100644 --- a/olive.pro +++ b/olive.pro @@ -1,108 +1,110 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-05-11T10:31:59 -# -#------------------------------------------------- - -QT += core gui multimedia opengl - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = olive -TEMPLATE = app - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - main.cpp \ - mainwindow.cpp \ - panels/project.cpp \ - panels/effectcontrols.cpp \ - panels/viewer.cpp \ - panels/timeline.cpp \ - ui/sourcetable.cpp \ - dialogs/aboutdialog.cpp \ - ui/timelinewidget.cpp \ - io/media.cpp \ - project/sequence.cpp \ - project/clip.cpp \ - playback/playback.cpp \ - playback/audio.cpp \ - io/config.cpp \ - dialogs/newsequencedialog.cpp \ - ui/viewerwidget.cpp \ - ui/viewercontainer.cpp \ - dialogs/exportdialog.cpp \ - ui/collapsiblewidget.cpp \ - effects/transformeffect.cpp \ - panels/panels.cpp \ - effects/volumeeffect.cpp \ - effects/paneffect.cpp \ - project/effect.cpp \ - effects/effects.cpp \ - playback/cacher.cpp \ - io/exportthread.cpp \ - ui/timelineheader.cpp \ - io/previewgenerator.cpp - -HEADERS += \ - mainwindow.h \ - panels/project.h \ - panels/effectcontrols.h \ - panels/viewer.h \ - panels/timeline.h \ - ui/sourcetable.h \ - dialogs/aboutdialog.h \ - ui/timelinewidget.h \ - io/media.h \ - project/sequence.h \ - project/clip.h \ - playback/playback.h \ - playback/audio.h \ - effects/effects.h \ - io/config.h \ - dialogs/newsequencedialog.h \ - ui/viewerwidget.h \ - ui/viewercontainer.h \ - dialogs/exportdialog.h \ - ui/collapsiblewidget.h \ - project/effect.h \ - panels/panels.h \ - playback/cacher.h \ - io/exportthread.h \ - ui/timelinetools.h \ - ui/timelineheader.h \ - io/previewgenerator.h - -FORMS += \ - mainwindow.ui \ - panels/project.ui \ - panels/effectcontrols.ui \ - panels/viewer.ui \ - panels/timeline.ui \ - dialogs/aboutdialog.ui \ - dialogs/newsequencedialog.ui \ - dialogs/exportdialog.ui - -win32 { - LIBS += -L../ffmpeg/lib -lavutil -lavformat -lavcodec -lswscale -lswresample -lopengl32 - INCLUDEPATH = ../ffmpeg/include - RC_FILE = icons/win.rc -} - -linux { - LIBS += -lavutil -lavformat -lavcodec -lswscale -lswresample -} - -RESOURCES += \ - icons/icons.qrc +#------------------------------------------------- +# +# Project created by QtCreator 2018-05-11T10:31:59 +# +#------------------------------------------------- + +QT += core gui multimedia opengl + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = olive +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + panels/project.cpp \ + panels/effectcontrols.cpp \ + panels/viewer.cpp \ + panels/timeline.cpp \ + ui/sourcetable.cpp \ + dialogs/aboutdialog.cpp \ + ui/timelinewidget.cpp \ + io/media.cpp \ + project/sequence.cpp \ + project/clip.cpp \ + playback/playback.cpp \ + playback/audio.cpp \ + io/config.cpp \ + dialogs/newsequencedialog.cpp \ + ui/viewerwidget.cpp \ + ui/viewercontainer.cpp \ + dialogs/exportdialog.cpp \ + ui/collapsiblewidget.cpp \ + effects/transformeffect.cpp \ + panels/panels.cpp \ + effects/volumeeffect.cpp \ + effects/paneffect.cpp \ + project/effect.cpp \ + effects/effects.cpp \ + playback/cacher.cpp \ + io/exportthread.cpp \ + ui/timelineheader.cpp \ + io/previewgenerator.cpp \ + ui/labelslider.cpp + +HEADERS += \ + mainwindow.h \ + panels/project.h \ + panels/effectcontrols.h \ + panels/viewer.h \ + panels/timeline.h \ + ui/sourcetable.h \ + dialogs/aboutdialog.h \ + ui/timelinewidget.h \ + io/media.h \ + project/sequence.h \ + project/clip.h \ + playback/playback.h \ + playback/audio.h \ + effects/effects.h \ + io/config.h \ + dialogs/newsequencedialog.h \ + ui/viewerwidget.h \ + ui/viewercontainer.h \ + dialogs/exportdialog.h \ + ui/collapsiblewidget.h \ + project/effect.h \ + panels/panels.h \ + playback/cacher.h \ + io/exportthread.h \ + ui/timelinetools.h \ + ui/timelineheader.h \ + io/previewgenerator.h \ + ui/labelslider.h + +FORMS += \ + mainwindow.ui \ + panels/project.ui \ + panels/effectcontrols.ui \ + panels/viewer.ui \ + panels/timeline.ui \ + dialogs/aboutdialog.ui \ + dialogs/newsequencedialog.ui \ + dialogs/exportdialog.ui + +win32 { + LIBS += -L../ffmpeg/lib -lavutil -lavformat -lavcodec -lswscale -lswresample -lopengl32 + INCLUDEPATH = ../ffmpeg/include + RC_FILE = icons/win.rc +} + +linux { + LIBS += -lavutil -lavformat -lavcodec -lswscale -lswresample +} + +RESOURCES += \ + icons/icons.qrc diff --git a/panels/project.cpp b/panels/project.cpp index 54b83c63f..7610289a2 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -406,8 +406,6 @@ void Project::load_project() { } break; } - qDebug() << "read element:" << stream.name() << "- text:" << stream.text() << "- start:" << stream.isStartElement() << "- end:" << stream.isEndElement(); - } if (stream.hasError()) { qDebug() << "[ERROR] Error parsing XML." << stream.error(); diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 312dff63f..73915f91b 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -231,13 +231,7 @@ void open_clip_worker(Clip* clip) { // if FFmpeg can't pick up the channel layout (usually WAV), assume // based on channel count (doesn't support surround sound sources yet) if (clip->codecCtx->channel_layout == 0) { - switch (clip->stream->codecpar->channels) { - case 1: clip->codecCtx->channel_layout = AV_CH_LAYOUT_MONO; - default: - clip->codecCtx->channel_layout = AV_CH_LAYOUT_STEREO; - qDebug() << "[WARNING] Could not detect audio channel layout - assuming stereo"; - break; - } + clip->codecCtx->channel_layout = guess_layout_from_channels(clip->stream->codecpar->channels); } int sample_format = AV_SAMPLE_FMT_S16; diff --git a/ui/labelslider.cpp b/ui/labelslider.cpp new file mode 100644 index 000000000..92749eb1f --- /dev/null +++ b/ui/labelslider.cpp @@ -0,0 +1,75 @@ +#include "labelslider.h" + +#include +#include + +LabelSlider::LabelSlider(QWidget* parent) : QLabel(parent) +{ + drag_start = false; + min_enabled = false; + max_enabled = false; + setStyleSheet("QLabel{color:#ffc000;text-decoration:underline;}"); + setCursor(Qt::SizeHorCursor); + set_value(0); + set_default_value(0); +} + +void LabelSlider::set_value(float v) { + if (min_enabled && v < min_value) { + internal_value = min_value; + } else if (max_enabled && v > max_value) { + internal_value = max_value; + } else { + internal_value = v; + } + setText(QString::number(v)); + emit valueChanged(); +} + +float LabelSlider::value() { + return internal_value; +} + +void LabelSlider::set_default_value(float v) { + default_value = v; + set_value(v); +} + +void LabelSlider::set_minimum_value(float v) { + min_value = v; + min_enabled = true; +} + +void LabelSlider::set_maximum_value(float v) { + max_value = v; + max_enabled = true; +} + +void LabelSlider::mousePressEvent(QMouseEvent *ev) { + if (ev->modifiers() & Qt::AltModifier) { + set_value(default_value); + } else { + qApp->setOverrideCursor(Qt::BlankCursor); + drag_start = true; + drag_start_x = cursor().pos().x(); + drag_start_y = cursor().pos().y(); + } +} + +void LabelSlider::mouseMoveEvent(QMouseEvent *ev) { + if (drag_start) { + set_value(internal_value + (cursor().pos().x()-drag_start_x) + (drag_start_y-cursor().pos().y())); + cursor().setPos(drag_start_x, drag_start_y); + drag_proc = true; + } +} + +void LabelSlider::mouseReleaseEvent(QMouseEvent *ev) { + if (drag_start) { + qApp->restoreOverrideCursor(); + drag_start = false; + if (drag_proc) { + drag_proc = false; + } + } +} diff --git a/ui/labelslider.h b/ui/labelslider.h new file mode 100644 index 000000000..21ab290de --- /dev/null +++ b/ui/labelslider.h @@ -0,0 +1,37 @@ +#ifndef LABELSLIDER_H +#define LABELSLIDER_H + +#include + +class LabelSlider : public QLabel +{ + Q_OBJECT +public: + LabelSlider(QWidget* parent = 0); + void set_value(float v); + void set_default_value(float v); + void set_minimum_value(float v); + void set_maximum_value(float v); + float value(); +protected: + void mousePressEvent(QMouseEvent *ev); + void mouseMoveEvent(QMouseEvent *ev); + void mouseReleaseEvent(QMouseEvent *ev); +private: + float internal_value; + float default_value; + + bool min_enabled; + float min_value; + bool max_enabled; + float max_value; + + bool drag_start; + bool drag_proc; + int drag_start_x; + int drag_start_y; +signals: + void valueChanged(); +}; + +#endif // LABELSLIDER_H