change: change code style to Linux style except indent.

This commit is contained in:
Mike Solar
2025-08-03 03:09:40 +08:00
parent 65ab76edc8
commit 74f73ab3be
789 changed files with 77113 additions and 68888 deletions
+49 -45
View File
@@ -27,76 +27,80 @@
#include "config/config.h"
#include "timeline/timelinecommon.h"
namespace olive {
namespace olive
{
#define super SeekableWidget
AudioWaveformView::AudioWaveformView(QWidget *parent) :
super(parent),
playback_(nullptr)
AudioWaveformView::AudioWaveformView(QWidget *parent)
: super(parent)
, playback_(nullptr)
{
setAutoFillBackground(true);
setBackgroundRole(QPalette::Base);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setAutoFillBackground(true);
setBackgroundRole(QPalette::Base);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// NOTE: At some point it might make sense for this to be AlignCenter since the waveform
// originates from the center. But we're leaving it top/left for now since it was just
// ported from a QWidget's paintEvent.
setAlignment(Qt::AlignLeft | Qt::AlignTop);
// NOTE: At some point it might make sense for this to be AlignCenter since the waveform
// originates from the center. But we're leaving it top/left for now since it was just
// ported from a QWidget's paintEvent.
setAlignment(Qt::AlignLeft | Qt::AlignTop);
}
void AudioWaveformView::SetViewer(ViewerOutput *playback)
{
if (playback_) {
pool_.clear();
pool_.waitForDone();
if (playback_) {
pool_.clear();
pool_.waitForDone();
disconnect(playback_, &ViewerOutput::ConnectedWaveformChanged, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
disconnect(playback_, &ViewerOutput::ConnectedWaveformChanged,
viewport(),
static_cast<void (QWidget::*)()>(&QWidget::update));
SetTimebase(0);
}
SetTimebase(0);
}
playback_ = playback;
playback_ = playback;
if (playback_) {
connect(playback_, &ViewerOutput::ConnectedWaveformChanged, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
if (playback_) {
connect(playback_, &ViewerOutput::ConnectedWaveformChanged, viewport(),
static_cast<void (QWidget::*)()>(&QWidget::update));
SetTimebase(playback_->GetAudioParams().sample_rate_as_time_base());
}
SetTimebase(playback_->GetAudioParams().sample_rate_as_time_base());
}
}
void AudioWaveformView::drawForeground(QPainter *p, const QRectF &rect)
{
super::drawForeground(p, rect);
super::drawForeground(p, rect);
if (!playback_) {
return;
}
if (!playback_) {
return;
}
const AudioWaveformCache *wave = playback_->GetConnectedWaveform();
if (!wave) {
return;
}
const AudioWaveformCache *wave = playback_->GetConnectedWaveform();
if (!wave) {
return;
}
const AudioParams& params = wave->GetParameters();
if (!params.is_valid()) {
return;
}
const AudioParams &params = wave->GetParameters();
if (!params.is_valid()) {
return;
}
// Draw in/out points
DrawWorkArea(p);
DrawMarkers(p);
// Draw in/out points
DrawWorkArea(p);
DrawMarkers(p);
// Draw waveform
p->setPen(QColor(64, 255, 160)); // FIXME: Hardcoded color
wave->Draw(p, rect.toRect(), GetScale(), SceneToTime(GetScroll()));
// Draw waveform
p->setPen(QColor(64, 255, 160)); // FIXME: Hardcoded color
wave->Draw(p, rect.toRect(), GetScale(), SceneToTime(GetScroll()));
// Draw playhead
p->setPen(PLAYHEAD_COLOR);
// Draw playhead
p->setPen(PLAYHEAD_COLOR);
int playhead_x = TimeToScene(GetViewerNode()->GetPlayhead());
p->drawLine(playhead_x, 0, playhead_x, height());
int playhead_x = TimeToScene(GetViewerNode()->GetPlayhead());
p->drawLine(playhead_x, 0, playhead_x, height());
}
}
+10 -11
View File
@@ -27,24 +27,23 @@
#include "render/audioplaybackcache.h"
#include "widget/timeruler/seekablewidget.h"
namespace olive {
class AudioWaveformView : public SeekableWidget
namespace olive
{
Q_OBJECT
public:
AudioWaveformView(QWidget* parent = nullptr);
void SetViewer(ViewerOutput *playback);
class AudioWaveformView : public SeekableWidget {
Q_OBJECT
public:
AudioWaveformView(QWidget *parent = nullptr);
void SetViewer(ViewerOutput *playback);
protected:
virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
private:
QThreadPool pool_;
ViewerOutput *playback_;
QThreadPool pool_;
ViewerOutput *playback_;
};
}
+57 -47
View File
@@ -26,98 +26,108 @@
#include "config/config.h"
#include "node/project.h"
namespace olive {
namespace olive
{
#define super ViewerWidget
FootageViewerWidget::FootageViewerWidget(QWidget *parent) :
super(parent)
FootageViewerWidget::FootageViewerWidget(QWidget *parent)
: super(parent)
{
connect(display_widget(), &ViewerDisplayWidget::DragStarted, this, &FootageViewerWidget::StartFootageDrag);
connect(display_widget(), &ViewerDisplayWidget::DragStarted, this,
&FootageViewerWidget::StartFootageDrag);
controls_->SetAudioVideoDragButtonsVisible(true);
connect(controls_, &PlaybackControls::VideoClicked, this, &FootageViewerWidget::VideoButtonClicked);
connect(controls_, &PlaybackControls::AudioClicked, this, &FootageViewerWidget::AudioButtonClicked);
connect(controls_, &PlaybackControls::VideoDragged, this, &FootageViewerWidget::StartVideoDrag);
connect(controls_, &PlaybackControls::AudioDragged, this, &FootageViewerWidget::StartAudioDrag);
controls_->SetAudioVideoDragButtonsVisible(true);
connect(controls_, &PlaybackControls::VideoClicked, this,
&FootageViewerWidget::VideoButtonClicked);
connect(controls_, &PlaybackControls::AudioClicked, this,
&FootageViewerWidget::AudioButtonClicked);
connect(controls_, &PlaybackControls::VideoDragged, this,
&FootageViewerWidget::StartVideoDrag);
connect(controls_, &PlaybackControls::AudioDragged, this,
&FootageViewerWidget::StartAudioDrag);
override_workarea_ = new TimelineWorkArea(this);
override_workarea_ = new TimelineWorkArea(this);
}
void FootageViewerWidget::OverrideWorkArea(const TimeRange &r)
{
override_workarea_->set_enabled(true);
override_workarea_->set_range(r);
this->ConnectWorkArea(override_workarea_);
override_workarea_->set_enabled(true);
override_workarea_->set_range(r);
this->ConnectWorkArea(override_workarea_);
}
void FootageViewerWidget::ResetWorkArea()
{
if (GetConnectedWorkArea() == override_workarea_) {
this->ConnectWorkArea(GetConnectedNode() ? GetConnectedNode()->GetWorkArea() : nullptr);
}
if (GetConnectedWorkArea() == override_workarea_) {
this->ConnectWorkArea(
GetConnectedNode() ? GetConnectedNode()->GetWorkArea() : nullptr);
}
}
void FootageViewerWidget::StartFootageDragInternal(bool enable_video, bool enable_audio)
void FootageViewerWidget::StartFootageDragInternal(bool enable_video,
bool enable_audio)
{
if (!GetConnectedNode()) {
return;
}
if (!GetConnectedNode()) {
return;
}
QDrag* drag = new QDrag(this);
QMimeData* mimedata = new QMimeData();
QDrag *drag = new QDrag(this);
QMimeData *mimedata = new QMimeData();
QByteArray encoded_data;
QDataStream data_stream(&encoded_data, QIODevice::WriteOnly);
QByteArray encoded_data;
QDataStream data_stream(&encoded_data, QIODevice::WriteOnly);
QVector<Track::Reference> streams = GetConnectedNode()->GetEnabledStreamsAsReferences();
QVector<Track::Reference> streams =
GetConnectedNode()->GetEnabledStreamsAsReferences();
// Disable streams that have been disabled
if (!enable_video || !enable_audio) {
for (int i=0; i<streams.size(); i++) {
const Track::Reference& ref = streams.at(i);
// Disable streams that have been disabled
if (!enable_video || !enable_audio) {
for (int i = 0; i < streams.size(); i++) {
const Track::Reference &ref = streams.at(i);
if ((ref.type() == Track::kVideo && !enable_video)
|| (ref.type() == Track::kAudio && !enable_audio)) {
streams.removeAt(i);
i--;
}
}
}
if ((ref.type() == Track::kVideo && !enable_video) ||
(ref.type() == Track::kAudio && !enable_audio)) {
streams.removeAt(i);
i--;
}
}
}
if (!streams.isEmpty()) {
data_stream << streams << reinterpret_cast<quintptr>(GetConnectedNode());
if (!streams.isEmpty()) {
data_stream << streams
<< reinterpret_cast<quintptr>(GetConnectedNode());
mimedata->setData(Project::kItemMimeType, encoded_data);
drag->setMimeData(mimedata);
mimedata->setData(Project::kItemMimeType, encoded_data);
drag->setMimeData(mimedata);
drag->exec();
}
drag->exec();
}
}
void FootageViewerWidget::StartFootageDrag()
{
StartFootageDragInternal(true, true);
StartFootageDragInternal(true, true);
}
void FootageViewerWidget::StartVideoDrag()
{
StartFootageDragInternal(true, false);
StartFootageDragInternal(true, false);
}
void FootageViewerWidget::StartAudioDrag()
{
StartFootageDragInternal(false, true);
StartFootageDragInternal(false, true);
}
void FootageViewerWidget::VideoButtonClicked()
{
this->SetWaveformMode(kWFAutomatic);
this->SetWaveformMode(kWFAutomatic);
}
void FootageViewerWidget::AudioButtonClicked()
{
this->SetWaveformMode(kWFWaveformOnly);
this->SetWaveformMode(kWFWaveformOnly);
}
}
+15 -16
View File
@@ -24,33 +24,32 @@
#include "node/output/viewer/viewer.h"
#include "viewer.h"
namespace olive {
class FootageViewerWidget : public ViewerWidget
namespace olive
{
Q_OBJECT
public:
FootageViewerWidget(QWidget* parent = nullptr);
void OverrideWorkArea(const TimeRange &r);
void ResetWorkArea();
class FootageViewerWidget : public ViewerWidget {
Q_OBJECT
public:
FootageViewerWidget(QWidget *parent = nullptr);
void OverrideWorkArea(const TimeRange &r);
void ResetWorkArea();
private:
void StartFootageDragInternal(bool enable_video, bool enable_audio);
void StartFootageDragInternal(bool enable_video, bool enable_audio);
TimelineWorkArea *override_workarea_;
TimelineWorkArea *override_workarea_;
private slots:
void StartFootageDrag();
void StartFootageDrag();
void StartVideoDrag();
void StartVideoDrag();
void StartAudioDrag();
void StartAudioDrag();
void VideoButtonClicked();
void AudioButtonClicked();
void VideoButtonClicked();
void AudioButtonClicked();
};
}
+1371 -1176
View File
File diff suppressed because it is too large Load Diff
+217 -210
View File
@@ -40,381 +40,388 @@
#include "widget/timebased/timebasedwidget.h"
#include "widget/timelinewidget/timelinewidget.h"
namespace olive {
namespace olive
{
class MulticamWidget;
/**
* @brief An OpenGL-based viewer widget with playback controls (a PlaybackControls widget).
*/
class ViewerWidget : public TimeBasedWidget
{
Q_OBJECT
class ViewerWidget : public TimeBasedWidget {
Q_OBJECT
public:
enum WaveformMode {
kWFAutomatic,
kWFViewerOnly,
kWFWaveformOnly,
kWFViewerAndWaveform
};
enum WaveformMode {
kWFAutomatic,
kWFViewerOnly,
kWFWaveformOnly,
kWFViewerAndWaveform
};
ViewerWidget(QWidget* parent = nullptr) :
ViewerWidget(new ViewerDisplayWidget(), parent)
{}
ViewerWidget(QWidget *parent = nullptr)
: ViewerWidget(new ViewerDisplayWidget(), parent)
{
}
virtual ~ViewerWidget() override;
virtual ~ViewerWidget() override;
void SetPlaybackControlsEnabled(bool enabled);
void SetPlaybackControlsEnabled(bool enabled);
void SetTimeRulerEnabled(bool enabled);
void SetTimeRulerEnabled(bool enabled);
void TogglePlayPause();
void TogglePlayPause();
bool IsPlaying() const;
bool IsPlaying() const;
/**
/**
* @brief Enable or disable the color management menu
*
* While the Viewer is _always_ color managed, In some contexts, the color management may be controlled from an
* external UI making the menu unnecessary.
*/
void SetColorMenuEnabled(bool enabled);
void SetColorMenuEnabled(bool enabled);
void SetMatrix(const QMatrix4x4& mat);
void SetMatrix(const QMatrix4x4 &mat);
/**
/**
* @brief Creates a ViewerWindow widget and places it full screen on another screen
*
* If `screen` is nullptr, the screen will be automatically selected as whichever one contains the mouse cursor.
*/
void SetFullScreen(QScreen* screen = nullptr);
void SetFullScreen(QScreen *screen = nullptr);
ColorManager* color_manager() const
{
return display_widget_->color_manager();
}
ColorManager *color_manager() const
{
return display_widget_->color_manager();
}
void SetGizmos(Node* node);
void SetGizmos(Node *node);
void StartCapture(TimelineWidget *source, const TimeRange &time, const Track::Reference &track);
void StartCapture(TimelineWidget *source, const TimeRange &time,
const Track::Reference &track);
void SetAudioScrubbingEnabled(bool e)
{
enable_audio_scrubbing_ = e;
}
void SetAudioScrubbingEnabled(bool e)
{
enable_audio_scrubbing_ = e;
}
void AddPlaybackDevice(ViewerDisplayWidget *vw)
{
playback_devices_.push_back(vw);
}
void AddPlaybackDevice(ViewerDisplayWidget *vw)
{
playback_devices_.push_back(vw);
}
void SetTimelineSelectedBlocks(const QVector<Block*> &b)
{
timeline_selected_blocks_ = b;
void SetTimelineSelectedBlocks(const QVector<Block *> &b)
{
timeline_selected_blocks_ = b;
if (!IsPlaying()) {
// If is playing, this will happen by the next frame automatically
DetectMulticamNodeNow();
UpdateTextureFromNode();
}
}
if (!IsPlaying()) {
// If is playing, this will happen by the next frame automatically
DetectMulticamNodeNow();
UpdateTextureFromNode();
}
}
void SetNodeViewSelections(const QVector<Node*> &n)
{
node_view_selected_ = n;
void SetNodeViewSelections(const QVector<Node *> &n)
{
node_view_selected_ = n;
if (!IsPlaying()) {
// If is playing, this will happen by the next frame automatically
DetectMulticamNodeNow();
UpdateTextureFromNode();
}
}
if (!IsPlaying()) {
// If is playing, this will happen by the next frame automatically
DetectMulticamNodeNow();
UpdateTextureFromNode();
}
}
void ConnectMulticamWidget(MulticamWidget *p);
void ConnectMulticamWidget(MulticamWidget *p);
public slots:
void Play(bool in_to_out_only);
void Play(bool in_to_out_only);
void Play();
void Play();
void Pause();
void Pause();
void ShuttleLeft();
void ShuttleLeft();
void ShuttleStop();
void ShuttleStop();
void ShuttleRight();
void ShuttleRight();
void SetColorTransform(const ColorTransform& transform);
void SetColorTransform(const ColorTransform &transform);
/**
/**
* @brief Wrapper for ViewerGLWidget::SetSignalCursorColorEnabled()
*/
void SetSignalCursorColorEnabled(bool e);
void SetSignalCursorColorEnabled(bool e);
void CacheEntireSequence();
void CacheEntireSequence();
void CacheSequenceInOut();
void CacheSequenceInOut();
void SetViewerResolution(int width, int height);
void SetViewerResolution(int width, int height);
void SetViewerPixelAspect(const rational& ratio);
void SetViewerPixelAspect(const rational &ratio);
void UpdateTextureFromNode();
void UpdateTextureFromNode();
void RequestStartEditingText()
{
display_widget_->RequestStartEditingText();
}
void RequestStartEditingText()
{
display_widget_->RequestStartEditingText();
}
signals:
/**
/**
* @brief Wrapper for ViewerGLWidget::CursorColor()
*/
void CursorColor(const Color& reference, const Color& display);
void CursorColor(const Color &reference, const Color &display);
/**
/**
* @brief Signal emitted when a new frame is loaded
*/
void TextureChanged(TexturePtr t);
void TextureChanged(TexturePtr t);
/**
/**
* @brief Wrapper for ViewerGLWidget::ColorProcessorChanged()
*/
void ColorProcessorChanged(ColorProcessorPtr processor);
void ColorProcessorChanged(ColorProcessorPtr processor);
/**
/**
* @brief Wrapper for ViewerGLWidget::ColorManagerChanged()
*/
void ColorManagerChanged(ColorManager* color_manager);
void ColorManagerChanged(ColorManager *color_manager);
protected:
ViewerWidget(ViewerDisplayWidget *display, QWidget* parent = nullptr);
ViewerWidget(ViewerDisplayWidget *display, QWidget *parent = nullptr);
virtual void TimebaseChangedEvent(const rational &) override;
virtual void TimeChangedEvent(const rational &time) override;
virtual void TimebaseChangedEvent(const rational &) override;
virtual void TimeChangedEvent(const rational &time) override;
virtual void ConnectNodeEvent(ViewerOutput *) override;
virtual void DisconnectNodeEvent(ViewerOutput *) override;
virtual void ConnectedNodeChangeEvent(ViewerOutput *) override;
virtual void ConnectedWorkAreaChangeEvent(TimelineWorkArea *) override;
virtual void ConnectedMarkersChangeEvent(TimelineMarkerList *) override;
virtual void ConnectNodeEvent(ViewerOutput *) override;
virtual void DisconnectNodeEvent(ViewerOutput *) override;
virtual void ConnectedNodeChangeEvent(ViewerOutput *) override;
virtual void ConnectedWorkAreaChangeEvent(TimelineWorkArea *) override;
virtual void ConnectedMarkersChangeEvent(TimelineMarkerList *) override;
virtual void ScaleChangedEvent(const double& s) override;
virtual void ScaleChangedEvent(const double &s) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
PlaybackControls* controls_;
PlaybackControls *controls_;
ViewerDisplayWidget* display_widget() const
{
return display_widget_;
}
ViewerDisplayWidget *display_widget() const
{
return display_widget_;
}
void IgnoreNextScrubEvent()
{
ignore_scrub_++;
}
void IgnoreNextScrubEvent()
{
ignore_scrub_++;
}
RenderTicketPtr GetSingleFrame(const rational &t, bool dry = false);
RenderTicketPtr GetSingleFrame(const rational &t, bool dry = false);
void SetWaveformMode(WaveformMode wf);
void SetWaveformMode(WaveformMode wf);
private:
int64_t GetTimestamp() const
{
return Timecode::time_to_timestamp(GetConnectedNode()->GetPlayhead(), timebase(), Timecode::kFloor);
}
int64_t GetTimestamp() const
{
return Timecode::time_to_timestamp(GetConnectedNode()->GetPlayhead(),
timebase(), Timecode::kFloor);
}
void UpdateTimeInternal(int64_t i);
void UpdateTimeInternal(int64_t i);
void PlayInternal(int speed, bool in_to_out_only);
void PlayInternal(int speed, bool in_to_out_only);
void PauseInternal();
void PauseInternal();
void PushScrubbedAudio();
void PushScrubbedAudio();
void UpdateMinimumScale();
void UpdateMinimumScale();
void SetColorTransform(const ColorTransform& transform, ViewerDisplayWidget* sender);
void SetColorTransform(const ColorTransform &transform,
ViewerDisplayWidget *sender);
QString GetCachedFilenameFromTime(const rational& time);
QString GetCachedFilenameFromTime(const rational &time);
bool FrameExistsAtTime(const rational& time);
bool FrameExistsAtTime(const rational &time);
bool ViewerMightBeAStill();
bool ViewerMightBeAStill();
void SetDisplayImage(RenderTicketPtr ticket);
void SetDisplayImage(RenderTicketPtr ticket);
RenderTicketWatcher *RequestNextFrameForQueue(bool increment = true);
RenderTicketWatcher *RequestNextFrameForQueue(bool increment = true);
RenderTicketPtr GetFrame(const rational& t);
RenderTicketPtr GetFrame(const rational &t);
void FinishPlayPreprocess();
void FinishPlayPreprocess();
int DeterminePlaybackQueueSize();
int DeterminePlaybackQueueSize();
static FramePtr DecodeCachedImage(const QString &cache_path, const QUuid &cache_id, const int64_t& time);
static FramePtr DecodeCachedImage(const QString &cache_path,
const QUuid &cache_id,
const int64_t &time);
static void DecodeCachedImage(RenderTicketPtr ticket, const QString &cache_path, const QUuid &cache_id, const int64_t &time);
static void DecodeCachedImage(RenderTicketPtr ticket,
const QString &cache_path,
const QUuid &cache_id, const int64_t &time);
bool ShouldForceWaveform() const;
bool ShouldForceWaveform() const;
void SetEmptyImage();
void SetEmptyImage();
void UpdateAutoCacher();
void UpdateAutoCacher();
void DecrementPrequeuedAudio();
void DecrementPrequeuedAudio();
void ArmForRecording();
void ArmForRecording();
void DisarmRecording();
void DisarmRecording();
void CloseAudioProcessor();
void CloseAudioProcessor();
void DetectMulticamNode(const rational &time);
void DetectMulticamNode(const rational &time);
bool IsVideoVisible() const;
bool IsVideoVisible() const;
ViewerSizer* sizer_;
ViewerSizer *sizer_;
int playback_speed_;
int playback_speed_;
rational last_time_;
rational last_time_;
bool color_menu_enabled_;
bool color_menu_enabled_;
bool time_changed_from_timer_;
bool time_changed_from_timer_;
bool play_in_to_out_only_;
bool play_in_to_out_only_;
AudioWaveformView* waveform_view_;
AudioWaveformView *waveform_view_;
QHash<QScreen*, ViewerWindow*> windows_;
QHash<QScreen *, ViewerWindow *> windows_;
ViewerDisplayWidget* display_widget_;
ViewerDisplayWidget *display_widget_;
ViewerDisplayWidget* context_menu_widget_;
ViewerDisplayWidget *context_menu_widget_;
QTimer playback_backup_timer_;
QTimer playback_backup_timer_;
int64_t playback_queue_next_frame_;
int64_t dry_run_next_frame_;
QVector<ViewerDisplayWidget*> playback_devices_;
int64_t playback_queue_next_frame_;
int64_t dry_run_next_frame_;
QVector<ViewerDisplayWidget *> playback_devices_;
bool prequeuing_video_;
int prequeuing_audio_;
bool prequeuing_video_;
int prequeuing_audio_;
QList<RenderTicketWatcher*> nonqueue_watchers_;
QList<RenderTicketWatcher *> nonqueue_watchers_;
rational last_length_;
rational last_length_;
int prequeue_length_;
int prequeue_count_;
int prequeue_length_;
int prequeue_count_;
QVector<RenderTicketWatcher*> queue_watchers_;
QVector<RenderTicketWatcher *> queue_watchers_;
std::list<RenderTicketWatcher*> audio_playback_queue_;
rational audio_playback_queue_time_;
AudioProcessor audio_processor_;
QByteArray prequeued_audio_;
static const rational kAudioPlaybackInterval;
std::list<RenderTicketWatcher *> audio_playback_queue_;
rational audio_playback_queue_time_;
AudioProcessor audio_processor_;
QByteArray prequeued_audio_;
static const rational kAudioPlaybackInterval;
static QVector<ViewerWidget*> instances_;
static QVector<ViewerWidget *> instances_;
std::list<RenderTicketWatcher*> audio_scrub_watchers_;
std::list<RenderTicketWatcher *> audio_scrub_watchers_;
bool record_armed_;
bool recording_;
TimelineWidget *recording_callback_;
TimeRange recording_range_;
Track::Reference recording_track_;
QString recording_filename_;
bool record_armed_;
bool recording_;
TimelineWidget *recording_callback_;
TimeRange recording_range_;
Track::Reference recording_track_;
QString recording_filename_;
qint64 queue_starved_start_;
RenderTicketWatcher *first_requeue_watcher_;
qint64 queue_starved_start_;
RenderTicketWatcher *first_requeue_watcher_;
bool enable_audio_scrubbing_;
bool enable_audio_scrubbing_;
WaveformMode waveform_mode_;
WaveformMode waveform_mode_;
QVector<RenderTicketWatcher*> dry_run_watchers_;
QVector<RenderTicketWatcher *> dry_run_watchers_;
int ignore_scrub_;
int ignore_scrub_;
QVector<Block*> timeline_selected_blocks_;
QVector<Node*> node_view_selected_;
QVector<Block *> timeline_selected_blocks_;
QVector<Node *> node_view_selected_;
MulticamWidget *multicam_panel_;
MulticamWidget *multicam_panel_;
private slots:
void PlaybackTimerUpdate();
void PlaybackTimerUpdate();
void LengthChangedSlot(const rational& length);
void LengthChangedSlot(const rational &length);
void InterlacingChangedSlot(VideoParams::Interlacing interlacing);
void InterlacingChangedSlot(VideoParams::Interlacing interlacing);
void UpdateRendererVideoParameters();
void UpdateRendererVideoParameters();
void UpdateRendererAudioParameters();
void UpdateRendererAudioParameters();
void ShowContextMenu(const QPoint& pos);
void ShowContextMenu(const QPoint &pos);
void SetZoomFromMenu(QAction* action);
void SetZoomFromMenu(QAction *action);
void UpdateWaveformViewFromMode();
void UpdateWaveformViewFromMode();
void ContextMenuSetFullScreen(QAction* action);
void ContextMenuSetFullScreen(QAction *action);
void ContextMenuSetPlaybackRes(QAction* action);
void ContextMenuSetPlaybackRes(QAction *action);
void ContextMenuDisableSafeMargins();
void ContextMenuDisableSafeMargins();
void ContextMenuSetSafeMargins();
void ContextMenuSetSafeMargins();
void ContextMenuSetCustomSafeMargins();
void ContextMenuSetCustomSafeMargins();
void WindowAboutToClose();
void WindowAboutToClose();
void RendererGeneratedFrame();
void RendererGeneratedFrame();
void RendererGeneratedFrameForQueue();
void RendererGeneratedFrameForQueue();
void ViewerInvalidatedVideoRange(const olive::TimeRange &range);
void ViewerInvalidatedVideoRange(const olive::TimeRange &range);
void UpdateWaveformModeFromMenu(QAction *a);
void UpdateWaveformModeFromMenu(QAction *a);
void DragEntered(QDragEnterEvent* event);
void DragEntered(QDragEnterEvent *event);
void Dropped(QDropEvent* event);
void Dropped(QDropEvent *event);
void QueueNextAudioBuffer();
void QueueNextAudioBuffer();
void ReceivedAudioBufferForPlayback();
void ReceivedAudioBufferForPlayback();
void ReceivedAudioBufferForScrubbing();
void ReceivedAudioBufferForScrubbing();
void QueueStarved();
void QueueNoLongerStarved();
void QueueStarved();
void QueueNoLongerStarved();
void ForceRequeueFromCurrentTime();
void ForceRequeueFromCurrentTime();
void UpdateAudioProcessor();
void UpdateAudioProcessor();
void CreateAddableAt(const QRectF &f);
void CreateAddableAt(const QRectF &f);
void HandleFirstRequeueDestroy();
void HandleFirstRequeueDestroy();
void ShowSubtitleProperties();
void ShowSubtitleProperties();
void DryRunFinished();
void DryRunFinished();
void RequestNextDryRun();
void RequestNextDryRun();
void SaveFrameAsImage();
void DetectMulticamNodeNow();
void SaveFrameAsImage();
void DetectMulticamNodeNow();
};
}
File diff suppressed because it is too large Load Diff
+234 -217
View File
@@ -37,7 +37,8 @@
#include "widget/manageddisplay/manageddisplay.h"
#include "widget/timetarget/timetarget.h"
namespace olive {
namespace olive
{
/**
* @brief The inner display/rendering widget of a Viewer class.
@@ -54,393 +55,409 @@ namespace olive {
* the same texture object, use SetTexture() since it will nearly always be faster to just set it than to check *and*
* set it.
*/
class ViewerDisplayWidget : public ManagedDisplayWidget, public TimeTargetObject
{
Q_OBJECT
class ViewerDisplayWidget : public ManagedDisplayWidget,
public TimeTargetObject {
Q_OBJECT
public:
/**
/**
* @brief ViewerGLWidget Constructor
*
* @param parent
*
* QWidget parent.
*/
ViewerDisplayWidget(QWidget* parent = nullptr);
ViewerDisplayWidget(QWidget *parent = nullptr);
virtual ~ViewerDisplayWidget() override;
virtual ~ViewerDisplayWidget() override;
const ViewerSafeMarginInfo& GetSafeMargin() const;
void SetSafeMargins(const ViewerSafeMarginInfo& safe_margin);
const ViewerSafeMarginInfo &GetSafeMargin() const;
void SetSafeMargins(const ViewerSafeMarginInfo &safe_margin);
void SetGizmos(Node* node);
void SetGizmos(Node *node);
const VideoParams &GetVideoParams() const { return gizmo_params_; }
void SetVideoParams(const VideoParams &params);
const VideoParams &GetVideoParams() const
{
return gizmo_params_;
}
void SetVideoParams(const VideoParams &params);
const AudioParams &GetAudioParams() const { return gizmo_audio_params_; }
void SetAudioParams(const AudioParams &p);
const AudioParams &GetAudioParams() const
{
return gizmo_audio_params_;
}
void SetAudioParams(const AudioParams &p);
void SetTime(const rational& time);
void SetSubtitleTracks(Sequence *list);
void SetTime(const rational &time);
void SetSubtitleTracks(Sequence *list);
void SetShowWidgetBackground(bool e)
{
show_widget_background_ = e;
update();
}
void SetShowWidgetBackground(bool e)
{
show_widget_background_ = e;
update();
}
/**
/**
* @brief Transform a point from viewer space to the buffer space.
* Multiplies by the inverted transform matrix to undo the scaling and translation.
*/
QPointF TransformViewerSpaceToBufferSpace(const QPointF &pos);
QPointF TransformViewerSpaceToBufferSpace(const QPointF &pos);
bool IsDeinterlacing() const
{
return deinterlace_;
}
bool IsDeinterlacing() const
{
return deinterlace_;
}
void ResetFPSTimer();
void ResetFPSTimer();
bool GetShowFPS() const
{
return show_fps_;
}
bool GetShowFPS() const
{
return show_fps_;
}
bool GetShowSubtitles() const { return show_subtitles_; }
void SetShowSubtitles(bool e) { show_subtitles_ = e; update(); }
bool GetShowSubtitles() const
{
return show_subtitles_;
}
void SetShowSubtitles(bool e)
{
show_subtitles_ = e;
update();
}
void IncrementSkippedFrames();
void IncrementSkippedFrames();
void IncrementFrameCount()
{
fps_timer_update_count_++;
}
void IncrementFrameCount()
{
fps_timer_update_count_++;
}
TexturePtr GetCurrentTexture() const
{
return texture_;
}
TexturePtr GetCurrentTexture() const
{
return texture_;
}
void Play(const int64_t &start_timestamp, const int &playback_speed, const rational &timebase, bool start_updating);
void Play(const int64_t &start_timestamp, const int &playback_speed,
const rational &timebase, bool start_updating);
void Pause();
void Pause();
ViewerQueue* queue()
{
return &queue_;
}
ViewerQueue *queue()
{
return &queue_;
}
ViewerPlaybackTimer *timer()
{
return &timer_;
}
ViewerPlaybackTimer *timer()
{
return &timer_;
}
QPointF ScreenToScenePoint(const QPoint &p);
QPointF ScreenToScenePoint(const QPoint &p);
virtual bool eventFilter(QObject *o, QEvent *e) override;
virtual bool eventFilter(QObject *o, QEvent *e) override;
public slots:
/**
/**
* @brief Set the transformation matrix to draw with
*
* Set this if you want the drawing to pass through some sort of transform (most of the time you won't want this).
*/
void SetMatrixTranslate(const QMatrix4x4& mat);
void SetMatrixTranslate(const QMatrix4x4 &mat);
/**
/**
* @brief Set the scale matrix.
*/
void SetMatrixZoom(const QMatrix4x4& mat);
void SetMatrixZoom(const QMatrix4x4 &mat);
void SetMatrixCrop(const QMatrix4x4& mat);
void SetMatrixCrop(const QMatrix4x4 &mat);
/**
/**
* @brief Enables or disables whether this color at the cursor should be emitted
*
* Since tracking the mouse every movement, reading pixels, and doing color transforms are processor intensive, we
* have an option for it. Ideally, this should be connected to a PixelSamplerPanel::visibilityChanged signal so that
* it can automatically be enabled when the user is pixel sampling and disabled for optimization when they're not.
*/
void SetSignalCursorColorEnabled(bool e);
void SetSignalCursorColorEnabled(bool e);
void SetImage(const QVariant &buffer);
void SetImage(const QVariant &buffer);
void SetBlank();
void SetBlank();
/**
/**
* @brief Changes the pointer type if the tool is changed to the hand tool. Otherwise resets the pointer to it's
* normal type.
*/
void UpdateCursor();
void UpdateCursor();
void ToolChanged();
void ToolChanged();
/**
/**
* @brief Enables/disables a basic deinterlace on the viewer
*/
void SetDeinterlacing(bool e);
void SetDeinterlacing(bool e);
void SetShowFPS(bool e);
void SetShowFPS(bool e);
void RequestStartEditingText();
void RequestStartEditingText();
signals:
/**
/**
* @brief Signal emitted when the user starts dragging from the viewer
*/
void DragStarted(const QPoint &p);
void DragStarted(const QPoint &p);
/**
/**
* @brief Signal emitted when a hand drag starts
*/
void HandDragStarted();
void HandDragStarted();
/**
/**
* @brief Signal emitted when a hand drag moves
*/
void HandDragMoved(int x, int y);
void HandDragMoved(int x, int y);
/**
/**
* @brief Signal emitted when a hand drag ends
*/
void HandDragEnded();
void HandDragEnded();
/**
/**
* @brief Signal emitted when cursor color is enabled and the user's mouse position changes
*/
void CursorColor(const Color& reference, const Color& display);
void CursorColor(const Color &reference, const Color &display);
void DragEntered(QDragEnterEvent* event);
void DragEntered(QDragEnterEvent *event);
void DragLeft(QDragLeaveEvent* event);
void DragLeft(QDragLeaveEvent *event);
void Dropped(QDropEvent* event);
void Dropped(QDropEvent *event);
void TextureChanged(TexturePtr texture);
void TextureChanged(TexturePtr texture);
void QueueStarved();
void QueueStarved();
void QueueNoLongerStarved();
void QueueNoLongerStarved();
void CreateAddableAt(const QRectF &rect);
void CreateAddableAt(const QRectF &rect);
protected:
QTransform GenerateWorldTransform();
QTransform GenerateWorldTransform();
QTransform GenerateDisplayTransform();
QTransform GenerateDisplayTransform();
QTransform GenerateGizmoTransform(NodeTraverser &gt, const TimeRange &range);
QTransform GenerateGizmoTransform()
{
NodeTraverser t;
t.SetCacheVideoParams(gizmo_params_);
return GenerateGizmoTransform(t, GenerateGizmoTime());
}
QTransform GenerateGizmoTransform(NodeTraverser &gt,
const TimeRange &range);
QTransform GenerateGizmoTransform()
{
NodeTraverser t;
t.SetCacheVideoParams(gizmo_params_);
return GenerateGizmoTransform(t, GenerateGizmoTime());
}
TimeRange GenerateGizmoTime()
{
rational node_time = GetGizmoTime();
return TimeRange(node_time, node_time + gizmo_params_.frame_rate_as_time_base());
}
TimeRange GenerateGizmoTime()
{
rational node_time = GetGizmoTime();
return TimeRange(node_time,
node_time + gizmo_params_.frame_rate_as_time_base());
}
virtual TexturePtr LoadCustomTextureFromFrame(const QVariant &v)
{
return nullptr;
}
virtual TexturePtr LoadCustomTextureFromFrame(const QVariant &v)
{
return nullptr;
}
protected slots:
/**
/**
* @brief Paint function to display the texture (received in SetTexture()) on screen.
*
* Simple OpenGL drawing function for painting the texture on screen. Standardized around OpenGL ES 3.2 Core.
*/
virtual void OnPaint() override;
virtual void OnPaint() override;
virtual void OnDestroy() override;
virtual void OnDestroy() override;
private:
QPointF GetTexturePosition(const QPoint& screen_pos);
QPointF GetTexturePosition(const QSize& size);
QPointF GetTexturePosition(const double& x, const double& y);
QPointF GetTexturePosition(const QPoint &screen_pos);
QPointF GetTexturePosition(const QSize &size);
QPointF GetTexturePosition(const double &x, const double &y);
static void DrawTextWithCrudeShadow(QPainter* painter, const QRect& rect, const QString& text, const QTextOption &opt = QTextOption());
static void DrawTextWithCrudeShadow(QPainter *painter, const QRect &rect,
const QString &text,
const QTextOption &opt = QTextOption());
rational GetGizmoTime();
rational GetGizmoTime();
bool IsHandDrag(QMouseEvent* event) const;
bool IsHandDrag(QMouseEvent *event) const;
void UpdateMatrix();
void UpdateMatrix();
NodeGizmo *TryGizmoPress(const NodeValueRow &row, const QPointF &p);
NodeGizmo *TryGizmoPress(const NodeValueRow &row, const QPointF &p);
void OpenTextGizmo(TextGizmo *text, QMouseEvent *event = nullptr);
void OpenTextGizmo(TextGizmo *text, QMouseEvent *event = nullptr);
bool OnMousePress(QMouseEvent *e);
bool OnMouseMove(QMouseEvent *e);
bool OnMouseRelease(QMouseEvent *e);
bool OnMouseDoubleClick(QMouseEvent *e);
bool OnMousePress(QMouseEvent *e);
bool OnMouseMove(QMouseEvent *e);
bool OnMouseRelease(QMouseEvent *e);
bool OnMouseDoubleClick(QMouseEvent *e);
bool OnKeyPress(QKeyEvent *e);
bool OnKeyRelease(QKeyEvent *e);
bool OnKeyPress(QKeyEvent *e);
bool OnKeyRelease(QKeyEvent *e);
void EmitColorAtCursor(QMouseEvent* e);
void EmitColorAtCursor(QMouseEvent *e);
void DrawSubtitleTracks();
void DrawSubtitleTracks();
QPointF GetVirtualPosForTextEdit(const QPointF &p)
{
return text_transform_inverted_.map(p) - text_edit_pos_;
}
QPointF GetVirtualPosForTextEdit(const QPointF &p)
{
return text_transform_inverted_.map(p) - text_edit_pos_;
}
template <typename T>
void ForwardDragEventToTextEdit(T *event);
template <typename T> void ForwardDragEventToTextEdit(T *event);
bool ForwardMouseEventToTextEdit(QMouseEvent *event, bool check_if_outside = false);
bool ForwardEventToTextEdit(QEvent *event);
bool ForwardMouseEventToTextEdit(QMouseEvent *event,
bool check_if_outside = false);
bool ForwardEventToTextEdit(QEvent *event);
QPointF AdjustPosByVAlign(QPointF p);
QPointF AdjustPosByVAlign(QPointF p);
void CloseTextEditor();
void CloseTextEditor();
void GenerateGizmoTransforms();
void GenerateGizmoTransforms();
void DrawBlank(const VideoParams &device_params);
void DrawBlank(const VideoParams &device_params);
/**
/**
* @brief Internal reference to the OpenGL texture to draw. Set in SetTexture() and used in paintGL().
*/
TexturePtr texture_;
TexturePtr texture_;
/**
/**
* @brief Internal texture to deinterlace to
*/
TexturePtr deinterlace_texture_;
TexturePtr deinterlace_texture_;
/**
/**
* @brief Deinterlace shader
*/
QVariant deinterlace_shader_;
QVariant deinterlace_shader_;
/**
/**
* @brief Blank shader
*/
QVariant blank_shader_;
QVariant blank_shader_;
/**
/**
* @brief Translation only matrix (defaults to identity).
*/
QMatrix4x4 translate_matrix_;
QMatrix4x4 translate_matrix_;
/**
/**
* @brief Scale only matrix.
*/
QMatrix4x4 scale_matrix_;
QMatrix4x4 scale_matrix_;
/**
/**
* @brief Crop only matrix
*/
QMatrix4x4 crop_matrix_;
QMatrix4x4 crop_matrix_;
/**
/**
* @brief Cached result of translate_matrix_ and scale_matrix_ multiplied
*/
QMatrix4x4 combined_matrix_;
QMatrix4x4 combined_matrix_flipped_;
QMatrix4x4 combined_matrix_;
QMatrix4x4 combined_matrix_flipped_;
bool signal_cursor_color_;
bool signal_cursor_color_;
ViewerSafeMarginInfo safe_margin_;
ViewerSafeMarginInfo safe_margin_;
Node* gizmos_;
NodeValueRow gizmo_db_;
VideoParams gizmo_params_;
AudioParams gizmo_audio_params_;
QPoint gizmo_start_drag_;
QPoint gizmo_last_drag_;
TimeRange gizmo_draw_time_;
NodeGizmo *current_gizmo_;
bool gizmo_drag_started_;
QTransform gizmo_last_draw_transform_;
QTransform gizmo_last_draw_transform_inverted_;
Node *gizmos_;
NodeValueRow gizmo_db_;
VideoParams gizmo_params_;
AudioParams gizmo_audio_params_;
QPoint gizmo_start_drag_;
QPoint gizmo_last_drag_;
TimeRange gizmo_draw_time_;
NodeGizmo *current_gizmo_;
bool gizmo_drag_started_;
QTransform gizmo_last_draw_transform_;
QTransform gizmo_last_draw_transform_inverted_;
bool show_subtitles_;
Sequence *subtitle_tracks_;
bool show_subtitles_;
Sequence *subtitle_tracks_;
rational time_;
rational time_;
/**
/**
* @brief Position of mouse to calculate delta from.
*/
QPoint hand_last_drag_pos_;
bool hand_dragging_;
QPoint hand_last_drag_pos_;
bool hand_dragging_;
bool deinterlace_;
bool deinterlace_;
qint64 fps_timer_start_;
int fps_timer_update_count_;
qint64 fps_timer_start_;
int fps_timer_update_count_;
bool show_fps_;
int frames_skipped_;
bool show_fps_;
int frames_skipped_;
QVector<double> frame_rate_averages_;
int frame_rate_average_count_;
QVector<double> frame_rate_averages_;
int frame_rate_average_count_;
bool show_widget_background_;
bool show_widget_background_;
QVariant load_frame_;
QVariant load_frame_;
int playback_speed_;
int playback_speed_;
enum PushMode {
/// New frame to push to internal texture
kPushFrame,
enum PushMode {
/// New frame to push to internal texture
kPushFrame,
/// Internal texture reference is up to date, keep showing it
kPushUnnecessary,
/// Internal texture reference is up to date, keep showing it
kPushUnnecessary,
/// Draw blank/black screen
kPushBlank,
/// Draw blank/black screen
kPushBlank,
/// Draw nothing (not even a black frame)
kPushNull,
};
/// Draw nothing (not even a black frame)
kPushNull,
};
PushMode push_mode_;
PushMode push_mode_;
// Playback
ViewerQueue queue_;
// Playback
ViewerQueue queue_;
ViewerPlaybackTimer timer_;
ViewerPlaybackTimer timer_;
rational playback_timebase_;
rational playback_timebase_;
bool add_band_;
QPoint add_band_start_;
QPoint add_band_end_;
bool add_band_;
QPoint add_band_start_;
QPoint add_band_end_;
bool queue_starved_;
bool queue_starved_;
TextGizmo *active_text_gizmo_;
QPointF text_edit_pos_;
ViewerTextEditor *text_edit_;
ViewerTextEditorToolBar *text_toolbar_;
QTransform text_transform_;
QTransform text_transform_inverted_;
TextGizmo *active_text_gizmo_;
QPointF text_edit_pos_;
ViewerTextEditor *text_edit_;
ViewerTextEditorToolBar *text_toolbar_;
QTransform text_transform_;
QTransform text_transform_inverted_;
private slots:
void UpdateFromQueue();
void UpdateFromQueue();
void TextEditChanged();
void TextEditDestroyed();
void TextEditChanged();
void TextEditDestroyed();
void SubtitlesChanged(const TimeRange &r);
void FocusChanged(QWidget *old, QWidget *now);
QRectF UpdateActiveTextGizmoSize();
void SubtitlesChanged(const TimeRange &r);
void FocusChanged(QWidget *old, QWidget *now);
QRectF UpdateActiveTextGizmoSize();
};
}
+14 -10
View File
@@ -23,23 +23,27 @@
#include <QDateTime>
#include <QtMath>
namespace olive {
void ViewerPlaybackTimer::Start(const int64_t &start_timestamp, const int &playback_speed, const double &timebase)
namespace olive
{
start_msec_ = QDateTime::currentMSecsSinceEpoch();
start_timestamp_ = start_timestamp;
playback_speed_ = playback_speed;
timebase_ = timebase * 1000;
void ViewerPlaybackTimer::Start(const int64_t &start_timestamp,
const int &playback_speed,
const double &timebase)
{
start_msec_ = QDateTime::currentMSecsSinceEpoch();
start_timestamp_ = start_timestamp;
playback_speed_ = playback_speed;
timebase_ = timebase * 1000;
}
int64_t ViewerPlaybackTimer::GetTimestampNow() const
{
int64_t real_time = QDateTime::currentMSecsSinceEpoch() - start_msec_;
int64_t real_time = QDateTime::currentMSecsSinceEpoch() - start_msec_;
int64_t frames_since_start = qFloor(static_cast<double>(real_time) / (timebase_));
int64_t frames_since_start =
qFloor(static_cast<double>(real_time) / (timebase_));
return start_timestamp_ + frames_since_start * playback_speed_;
return start_timestamp_ + frames_since_start * playback_speed_;
}
}
+9 -8
View File
@@ -25,22 +25,23 @@
#include "common/define.h"
namespace olive {
namespace olive
{
class ViewerPlaybackTimer {
public:
void Start(const int64_t& start_timestamp, const int& playback_speed, const double& timebase);
void Start(const int64_t &start_timestamp, const int &playback_speed,
const double &timebase);
int64_t GetTimestampNow() const;
int64_t GetTimestampNow() const;
private:
qint64 start_msec_;
int64_t start_timestamp_;
qint64 start_msec_;
int64_t start_timestamp_;
int playback_speed_;
double timebase_;
int playback_speed_;
double timebase_;
};
}
+48 -41
View File
@@ -10,7 +10,8 @@
#include <QtDBus/QtDBus>
#endif
namespace olive {
namespace olive
{
#if defined(Q_OS_MAC)
IOPMAssertionID assertionID = 0;
@@ -21,53 +22,59 @@ IOPMAssertionID assertionID = 0;
void PreventSleep(bool on)
{
#if defined(Q_OS_WINDOWS)
SetThreadExecutionState(on ? ES_DISPLAY_REQUIRED | ES_CONTINUOUS : ES_CONTINUOUS);
SetThreadExecutionState(on ? ES_DISPLAY_REQUIRED | ES_CONTINUOUS :
ES_CONTINUOUS);
#elif defined(Q_OS_MAC)
if (on) {
static const CFStringRef reasonForActivity = CFSTR("Video Playback");
if (on) {
static const CFStringRef reasonForActivity = CFSTR("Video Playback");
IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
} else if (assertionID) {
IOPMAssertionRelease(assertionID);
assertionID = 0;
}
IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
kIOPMAssertionLevelOn, reasonForActivity,
&assertionID);
} else if (assertionID) {
IOPMAssertionRelease(assertionID);
assertionID = 0;
}
#elif defined(Q_OS_LINUX)
QDBusConnection bus = QDBusConnection::sessionBus();
if(bus.isConnected()) {
static const QStringList sleep_services = {
QStringLiteral("org.freedesktop.ScreenSaver"),
//QStringLiteral("org.gnome.SessionManager")
};
static const QStringList sleep_paths = {
QStringLiteral("/org/freedesktop/ScreenSaver"),
//QStringLiteral("/org/gnome/SessionManager")
};
static QVector<uint> sleep_cookies;
QDBusConnection bus = QDBusConnection::sessionBus();
if (bus.isConnected()) {
static const QStringList sleep_services = {
QStringLiteral("org.freedesktop.ScreenSaver"),
//QStringLiteral("org.gnome.SessionManager")
};
static const QStringList sleep_paths = {
QStringLiteral("/org/freedesktop/ScreenSaver"),
//QStringLiteral("/org/gnome/SessionManager")
};
static QVector<uint> sleep_cookies;
// Initialize vector to 0
if (sleep_cookies.isEmpty()) {
sleep_cookies.resize(sleep_services.size());
sleep_cookies.fill(0);
}
// Initialize vector to 0
if (sleep_cookies.isEmpty()) {
sleep_cookies.resize(sleep_services.size());
sleep_cookies.fill(0);
}
for (int i=0; i<sleep_cookies.size(); i++) {
QDBusInterface interface(sleep_services.at(i), sleep_paths.at(i), sleep_services.at(i), bus);
if (interface.isValid()) {
QDBusReply<uint> reply;
for (int i = 0; i < sleep_cookies.size(); i++) {
QDBusInterface interface(sleep_services.at(i), sleep_paths.at(i),
sleep_services.at(i), bus);
if (interface.isValid()) {
QDBusReply<uint> reply;
if (on) {
reply = interface.call(QStringLiteral("Inhibit"), QStringLiteral("Olive Video Editor"), QStringLiteral("Video Playback"));
} else {
reply = interface.call(QStringLiteral("UnInhibit"), sleep_cookies.at(i));
}
if (on) {
reply = interface.call(QStringLiteral("Inhibit"),
QStringLiteral("Olive Video Editor"),
QStringLiteral("Video Playback"));
} else {
reply = interface.call(QStringLiteral("UnInhibit"),
sleep_cookies.at(i));
}
if (reply.isValid()) {
sleep_cookies[i] = reply.value();
}
}
}
}
if (reply.isValid()) {
sleep_cookies[i] = reply.value();
}
}
}
}
#endif
}
+2 -1
View File
@@ -1,7 +1,8 @@
#ifndef VIEWERPREVENTSLEEP_H
#define VIEWERPREVENTSLEEP_H
namespace olive {
namespace olive
{
void PreventSleep(bool on);
+29 -29
View File
@@ -23,41 +23,41 @@
#include "codec/frame.h"
namespace olive {
struct ViewerPlaybackFrame
namespace olive
{
rational timestamp;
QVariant frame;
struct ViewerPlaybackFrame {
rational timestamp;
QVariant frame;
};
class ViewerQueue : public std::list<ViewerPlaybackFrame>
{
class ViewerQueue : public std::list<ViewerPlaybackFrame> {
public:
ViewerQueue() = default;
ViewerQueue() = default;
void AppendTimewise(const ViewerPlaybackFrame& f, int playback_speed)
{
if (this->empty() || (this->back().timestamp < f.timestamp) == (playback_speed > 0)) {
this->push_back(f);
} else {
for (auto i=this->begin(); i!=this->end(); i++) {
if ((i->timestamp > f.timestamp) == (playback_speed > 0)) {
this->insert(i, f);
break;
}
}
}
}
void PurgeBefore(const rational &time, int playback_speed)
{
while (!this->empty()
&& ((playback_speed > 0 && this->front().timestamp < time) || (playback_speed < 0 && this->front().timestamp > time))) {
this->pop_front();
}
}
void AppendTimewise(const ViewerPlaybackFrame &f, int playback_speed)
{
if (this->empty() ||
(this->back().timestamp < f.timestamp) == (playback_speed > 0)) {
this->push_back(f);
} else {
for (auto i = this->begin(); i != this->end(); i++) {
if ((i->timestamp > f.timestamp) == (playback_speed > 0)) {
this->insert(i, f);
break;
}
}
}
}
void PurgeBefore(const rational &time, int playback_speed)
{
while (!this->empty() &&
((playback_speed > 0 && this->front().timestamp < time) ||
(playback_speed < 0 && this->front().timestamp > time))) {
this->pop_front();
}
}
};
}
+33 -31
View File
@@ -25,49 +25,51 @@
#include "common/define.h"
namespace olive {
namespace olive
{
class ViewerSafeMarginInfo {
public:
ViewerSafeMarginInfo() :
enabled_(false)
{
}
ViewerSafeMarginInfo()
: enabled_(false)
{
}
ViewerSafeMarginInfo(bool enabled, double ratio = 0) :
enabled_(enabled),
ratio_(ratio)
{
}
ViewerSafeMarginInfo(bool enabled, double ratio = 0)
: enabled_(enabled)
, ratio_(ratio)
{
}
bool is_enabled() const
{
return enabled_;
}
bool is_enabled() const
{
return enabled_;
}
bool custom_ratio() const
{
return (ratio_ > 0);
}
bool custom_ratio() const
{
return (ratio_ > 0);
}
double ratio() const
{
return ratio_;
}
double ratio() const
{
return ratio_;
}
bool operator==(const ViewerSafeMarginInfo& rhs) const {
return (enabled_ == rhs.enabled_ && qFuzzyCompare(ratio_, rhs.ratio_));
}
bool operator==(const ViewerSafeMarginInfo &rhs) const
{
return (enabled_ == rhs.enabled_ && qFuzzyCompare(ratio_, rhs.ratio_));
}
bool operator!=(const ViewerSafeMarginInfo& rhs) const {
return (enabled_ != rhs.enabled_ || !qFuzzyCompare(ratio_, rhs.ratio_));
}
bool operator!=(const ViewerSafeMarginInfo &rhs) const
{
return (enabled_ != rhs.enabled_ || !qFuzzyCompare(ratio_, rhs.ratio_));
}
private:
bool enabled_;
double ratio_;
bool enabled_;
double ratio_;
};
}
+184 -166
View File
@@ -27,262 +27,280 @@
#include "widget/handmovableview/handmovableview.h"
namespace olive {
ViewerSizer::ViewerSizer(QWidget *parent) :
QWidget(parent),
widget_(nullptr),
width_(0),
height_(0),
pixel_aspect_(1),
zoom_(-1),
current_widget_scale_(0)
namespace olive
{
horiz_scrollbar_ = new QScrollBar(Qt::Horizontal, this);
horiz_scrollbar_->setVisible(false);
connect(horiz_scrollbar_, &QScrollBar::valueChanged, this, &ViewerSizer::ScrollBarMoved);
vert_scrollbar_ = new QScrollBar(Qt::Vertical, this);
vert_scrollbar_->setVisible(false);
connect(vert_scrollbar_, &QScrollBar::valueChanged, this, &ViewerSizer::ScrollBarMoved);
ViewerSizer::ViewerSizer(QWidget *parent)
: QWidget(parent)
, widget_(nullptr)
, width_(0)
, height_(0)
, pixel_aspect_(1)
, zoom_(-1)
, current_widget_scale_(0)
{
horiz_scrollbar_ = new QScrollBar(Qt::Horizontal, this);
horiz_scrollbar_->setVisible(false);
connect(horiz_scrollbar_, &QScrollBar::valueChanged, this,
&ViewerSizer::ScrollBarMoved);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
vert_scrollbar_ = new QScrollBar(Qt::Vertical, this);
vert_scrollbar_->setVisible(false);
connect(vert_scrollbar_, &QScrollBar::valueChanged, this,
&ViewerSizer::ScrollBarMoved);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
void ViewerSizer::SetWidget(QWidget *widget)
{
// Delete any previous widgets occupying this space
delete widget_;
// Delete any previous widgets occupying this space
delete widget_;
widget_ = widget;
widget_ = widget;
if (widget_ != nullptr) {
widget_->setParent(this);
widget_->installEventFilter(this);
if (widget_ != nullptr) {
widget_->setParent(this);
widget_->installEventFilter(this);
UpdateSize();
}
UpdateSize();
}
}
QSize ViewerSizer::GetContainerSize() const
{
double s = GetRealCurrentZoom();
return QSize(std::min(this->width(), int(width_ * s)) - vert_scrollbar_->width(), std::min(int(height_ * s), this->height()) - horiz_scrollbar_->height());
double s = GetRealCurrentZoom();
return QSize(std::min(this->width(), int(width_ * s)) -
vert_scrollbar_->width(),
std::min(int(height_ * s), this->height()) -
horiz_scrollbar_->height());
}
void ViewerSizer::SetChildSize(int width, int height)
{
width_ = width;
height_ = height;
width_ = width;
height_ = height;
UpdateSize();
UpdateSize();
}
void ViewerSizer::SetPixelAspectRatio(const rational &pixel_aspect)
{
pixel_aspect_ = pixel_aspect;
pixel_aspect_ = pixel_aspect;
UpdateSize();
UpdateSize();
}
void ViewerSizer::SetZoom(double percent)
{
zoom_ = percent;
zoom_ = percent;
UpdateSize();
UpdateSize();
}
void ViewerSizer::SetZoomAnchored(double next_scale, double cursor_x, double cursor_y)
void ViewerSizer::SetZoomAnchored(double next_scale, double cursor_x,
double cursor_y)
{
if (next_scale > 0) {
double cur_scale = GetRealCurrentZoom();
if (next_scale > 0) {
double cur_scale = GetRealCurrentZoom();
// Clamp scale within safe values
next_scale = std::clamp(next_scale, kZoomLevels[0], kZoomLevels[kZoomLevelCount-1]);
// Clamp scale within safe values
next_scale = std::clamp(next_scale, kZoomLevels[0],
kZoomLevels[kZoomLevelCount - 1]);
int anchor_x = qRound(double(cursor_x + horiz_scrollbar_->value()) / cur_scale * next_scale - cursor_x);
int anchor_y = qRound(double(cursor_y + vert_scrollbar_->value()) / cur_scale * next_scale - cursor_y);
int anchor_x = qRound(double(cursor_x + horiz_scrollbar_->value()) /
cur_scale * next_scale -
cursor_x);
int anchor_y = qRound(double(cursor_y + vert_scrollbar_->value()) /
cur_scale * next_scale -
cursor_y);
SetZoom(next_scale);
SetZoom(next_scale);
horiz_scrollbar_->setValue(anchor_x);
vert_scrollbar_->setValue(anchor_y);
} else {
SetZoom(-1);
horiz_scrollbar_->setValue(anchor_x);
vert_scrollbar_->setValue(anchor_y);
} else {
SetZoom(-1);
horiz_scrollbar_->setValue(0);
vert_scrollbar_->setValue(0);
}
horiz_scrollbar_->setValue(0);
vert_scrollbar_->setValue(0);
}
}
void ViewerSizer::HandDragMove(int x, int y)
{
if (horiz_scrollbar_->isVisible()) {
horiz_scrollbar_->setValue(horiz_scrollbar_->value() - x);
}
if (horiz_scrollbar_->isVisible()) {
horiz_scrollbar_->setValue(horiz_scrollbar_->value() - x);
}
if (vert_scrollbar_->isVisible()) {
vert_scrollbar_->setValue(vert_scrollbar_->value() - y);
}
if (vert_scrollbar_->isVisible()) {
vert_scrollbar_->setValue(vert_scrollbar_->value() - y);
}
}
bool ViewerSizer::eventFilter(QObject *watched, QEvent *event)
{
if (watched == widget_) {
if (event->type() == QEvent::Wheel) {
QWheelEvent *w = static_cast<QWheelEvent*>(event);
if (watched == widget_) {
if (event->type() == QEvent::Wheel) {
QWheelEvent *w = static_cast<QWheelEvent *>(event);
if (HandMovableView::WheelEventIsAZoomEvent(w)) {
double next_scale = GetRealCurrentZoom() * HandMovableView::GetScrollZoomMultiplier(w);
QPointF cursor_pos = w->position();
SetZoomAnchored(next_scale, cursor_pos.x(), cursor_pos.y());
} else {
// Pass scroll values to scrollbars
QPoint p = w->pixelDelta();
horiz_scrollbar_->setValue(horiz_scrollbar_->value() - p.x());
vert_scrollbar_->setValue(vert_scrollbar_->value() - p.y());
}
return true;
}
}
if (HandMovableView::WheelEventIsAZoomEvent(w)) {
double next_scale = GetRealCurrentZoom() *
HandMovableView::GetScrollZoomMultiplier(w);
QPointF cursor_pos = w->position();
SetZoomAnchored(next_scale, cursor_pos.x(), cursor_pos.y());
} else {
// Pass scroll values to scrollbars
QPoint p = w->pixelDelta();
horiz_scrollbar_->setValue(horiz_scrollbar_->value() - p.x());
vert_scrollbar_->setValue(vert_scrollbar_->value() - p.y());
}
return true;
}
}
return QWidget::eventFilter(watched, event);
return QWidget::eventFilter(watched, event);
}
void ViewerSizer::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
QWidget::resizeEvent(event);
UpdateSize();
UpdateSize();
}
void ViewerSizer::UpdateSize()
{
if (widget_ == nullptr) {
return;
}
if (widget_ == nullptr) {
return;
}
// If the aspect ratio is 0, default to taking all space
if (!width_ || !height_) {
widget_->move(0, 0);
widget_->resize(width(), height());
return;
}
// If the aspect ratio is 0, default to taking all space
if (!width_ || !height_) {
widget_->move(0, 0);
widget_->resize(width(), height());
return;
}
// Calculate how much UI space is available (it will be less if we have to show scrollbars)
int available_width = width();
int available_height = height();
// Calculate how much UI space is available (it will be less if we have to show scrollbars)
int available_width = width();
int available_height = height();
// Determine if we need scrollbars for the zoom we want
horiz_scrollbar_->setVisible(zoom_ > 0 && GetZoomedValue(width_) > available_width);
vert_scrollbar_->setVisible(zoom_ > 0 && GetZoomedValue(height_) > available_height);
// Determine if we need scrollbars for the zoom we want
horiz_scrollbar_->setVisible(zoom_ > 0 &&
GetZoomedValue(width_) > available_width);
vert_scrollbar_->setVisible(zoom_ > 0 &&
GetZoomedValue(height_) > available_height);
// Horizontal scrollbar will reduce the available height
if (horiz_scrollbar_->isVisible()) {
available_height -= horiz_scrollbar_->sizeHint().height();
}
// Horizontal scrollbar will reduce the available height
if (horiz_scrollbar_->isVisible()) {
available_height -= horiz_scrollbar_->sizeHint().height();
}
// Vertical scrollbar will reduce the available width
if (vert_scrollbar_->isVisible()) {
available_width -= vert_scrollbar_->sizeHint().width();
}
// Vertical scrollbar will reduce the available width
if (vert_scrollbar_->isVisible()) {
available_width -= vert_scrollbar_->sizeHint().width();
}
// Set correct values on horizontal scrollbar
if (horiz_scrollbar_->isVisible()) {
horiz_scrollbar_->resize(available_width, horiz_scrollbar_->sizeHint().height());
horiz_scrollbar_->move(0, this->height() - horiz_scrollbar_->height() - 1);
horiz_scrollbar_->setMaximum(GetZoomedValue(width_) - available_width);
horiz_scrollbar_->setPageStep(available_width);
}
// Set correct values on horizontal scrollbar
if (horiz_scrollbar_->isVisible()) {
horiz_scrollbar_->resize(available_width,
horiz_scrollbar_->sizeHint().height());
horiz_scrollbar_->move(0,
this->height() - horiz_scrollbar_->height() - 1);
horiz_scrollbar_->setMaximum(GetZoomedValue(width_) - available_width);
horiz_scrollbar_->setPageStep(available_width);
}
// Set correct values on vertical scrollbar
if (vert_scrollbar_->isVisible()) {
vert_scrollbar_->resize(vert_scrollbar_->sizeHint().width(), available_height);
vert_scrollbar_->move(this->width() - vert_scrollbar_->width() - 1, 0);
vert_scrollbar_->setMaximum(GetZoomedValue(height_) - available_height);
vert_scrollbar_->setPageStep(available_height);
}
// Set correct values on vertical scrollbar
if (vert_scrollbar_->isVisible()) {
vert_scrollbar_->resize(vert_scrollbar_->sizeHint().width(),
available_height);
vert_scrollbar_->move(this->width() - vert_scrollbar_->width() - 1, 0);
vert_scrollbar_->setMaximum(GetZoomedValue(height_) - available_height);
vert_scrollbar_->setPageStep(available_height);
}
// Size widget to the UI space we've calculated
widget_->resize(available_width, available_height);
// Size widget to the UI space we've calculated
widget_->resize(available_width, available_height);
// Adjust to aspect ratio
double sequence_aspect_ratio = double(width_) / double(height_)
* pixel_aspect_.toDouble();
double our_aspect_ratio = double(available_width) / double(available_height);
// Adjust to aspect ratio
double sequence_aspect_ratio =
double(width_) / double(height_) * pixel_aspect_.toDouble();
double our_aspect_ratio =
double(available_width) / double(available_height);
QMatrix4x4 child_matrix;
double current_scale;
QMatrix4x4 child_matrix;
double current_scale;
if (our_aspect_ratio > sequence_aspect_ratio) {
if (our_aspect_ratio > sequence_aspect_ratio) {
// This container is wider than the image, scale by height
child_matrix.scale(sequence_aspect_ratio / our_aspect_ratio, 1.0);
current_scale = double(available_height) / double(height_);
// This container is wider than the image, scale by height
child_matrix.scale(sequence_aspect_ratio / our_aspect_ratio, 1.0);
current_scale = double(available_height) / double(height_);
} else {
// This container is taller than the image, scale by width
child_matrix.scale(1.0, our_aspect_ratio / sequence_aspect_ratio);
current_scale = double(available_width) / double(width_);
}
} else {
current_widget_scale_ = current_scale;
// This container is taller than the image, scale by width
child_matrix.scale(1.0, our_aspect_ratio / sequence_aspect_ratio);
current_scale = double(available_width) / double(width_);
if (zoom_ > 0) {
// Scale to get to the requested zoom
double zoom_diff = zoom_ / current_scale;
child_matrix.scale(zoom_diff, zoom_diff, 1.0);
}
}
emit RequestScale(child_matrix);
current_widget_scale_ = current_scale;
if (zoom_ > 0) {
// Scale to get to the requested zoom
double zoom_diff = zoom_ / current_scale;
child_matrix.scale(zoom_diff, zoom_diff, 1.0);
}
emit RequestScale(child_matrix);
ScrollBarMoved();
ScrollBarMoved();
}
int ViewerSizer::GetZoomedValue(int value)
{
return qRound(value * zoom_);
return qRound(value * zoom_);
}
double ViewerSizer::GetRealCurrentZoom() const
{
if (zoom_ < 0) {
// Currently set to "fit"
return current_widget_scale_;
} else {
// Explicit zoom set
return zoom_;
}
if (zoom_ < 0) {
// Currently set to "fit"
return current_widget_scale_;
} else {
// Explicit zoom set
return zoom_;
}
}
void ViewerSizer::ScrollBarMoved()
{
QMatrix4x4 mat;
QMatrix4x4 mat;
float x_scroll, y_scroll;
float x_scroll, y_scroll;
if (horiz_scrollbar_->isVisible()) {
int zoomed_width = GetZoomedValue(width_);
x_scroll = (zoomed_width/2 - horiz_scrollbar_->value() - widget_->width() / 2) * (2.0 / zoomed_width);
} else {
x_scroll = 0;
}
if (horiz_scrollbar_->isVisible()) {
int zoomed_width = GetZoomedValue(width_);
x_scroll = (zoomed_width / 2 - horiz_scrollbar_->value() -
widget_->width() / 2) *
(2.0 / zoomed_width);
} else {
x_scroll = 0;
}
if (vert_scrollbar_->isVisible()) {
int zoomed_height = GetZoomedValue(height_);
y_scroll = (zoomed_height/2 - vert_scrollbar_->value() - widget_->height() / 2) * (2.0 / zoomed_height);
} else {
y_scroll = 0;
}
if (vert_scrollbar_->isVisible()) {
int zoomed_height = GetZoomedValue(height_);
y_scroll = (zoomed_height / 2 - vert_scrollbar_->value() -
widget_->height() / 2) *
(2.0 / zoomed_height);
} else {
y_scroll = 0;
}
// Zero translate is centered, so we need to determine how much "off center" we are
mat.translate(x_scroll, y_scroll);
// Zero translate is centered, so we need to determine how much "off center" we are
mat.translate(x_scroll, y_scroll);
emit RequestTranslate(mat);
emit RequestTranslate(mat);
}
}
+41 -40
View File
@@ -25,7 +25,8 @@
#include <QScrollBar>
#include <QWidget>
namespace olive {
namespace olive
{
using namespace core;
@@ -38,97 +39,97 @@ using namespace core;
* The aspect ratio is calculated width divided by height. If the aspect ratio is zero (either width or height == 0),
* the widget is hidden until a valid size is provided.
*/
class ViewerSizer : public QWidget
{
Q_OBJECT
class ViewerSizer : public QWidget {
Q_OBJECT
public:
ViewerSizer(QWidget* parent = nullptr);
ViewerSizer(QWidget *parent = nullptr);
/**
/**
* @brief Set the widget to be adjusted by this widget
*
* ViewerSizer takes ownership of this widget. If a widget was previously set, it is destroyed.
*/
void SetWidget(QWidget* widget);
void SetWidget(QWidget *widget);
QSize GetContainerSize() const;
QSize GetContainerSize() const;
static constexpr int kZoomLevelCount = 10;
static constexpr double kZoomLevels[kZoomLevelCount] = {0.05, 0.1, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 4.0, 8.0};
static constexpr int kZoomLevelCount = 10;
static constexpr double kZoomLevels[kZoomLevelCount] = {
0.05, 0.1, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 4.0, 8.0
};
public slots:
/**
/**
* @brief Set resolution to use
*
* This is not the actual resolution of the viewer, it's used to calculate the aspect ratio
*/
void SetChildSize(int width, int height);
void SetChildSize(int width, int height);
/**
/**
* @brief Set pixel aspect ratio
*/
void SetPixelAspectRatio(const rational& pixel_aspect);
void SetPixelAspectRatio(const rational &pixel_aspect);
/**
/**
* @brief Set the zoom value of the child widget
*
* The number is an integer percentage (100 = 100%). Set to 0 to auto-fit.
*/
void SetZoom(double percent);
void SetZoomAnchored(double percent, double cursor_x, double cursor_y);
void SetZoom(double percent);
void SetZoomAnchored(double percent, double cursor_x, double cursor_y);
void HandDragMove(int x, int y);
void HandDragMove(int x, int y);
virtual bool eventFilter(QObject *watched, QEvent *event) override;
virtual bool eventFilter(QObject *watched, QEvent *event) override;
signals:
void RequestScale(const QMatrix4x4& matrix);
void RequestScale(const QMatrix4x4 &matrix);
void RequestTranslate(const QMatrix4x4& matrix);
void RequestTranslate(const QMatrix4x4 &matrix);
protected:
/**
/**
* @brief Listen for resize events to ensure the child widget remains correctly sized
*/
virtual void resizeEvent(QResizeEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
private:
/**
/**
* @brief Main sizing function, resizes widget_ to fit aspect_ratio_ (or hides if aspect ratio is 0)
*/
void UpdateSize();
void UpdateSize();
int GetZoomedValue(int value);
int GetZoomedValue(int value);
double GetRealCurrentZoom() const;
double GetRealCurrentZoom() const;
/**
/**
* @brief Reference to widget
*
* If this is nullptr, all sizing operations are no-ops
*/
QWidget* widget_;
QWidget *widget_;
/**
/**
* @brief Internal resolution values
*/
int width_;
int height_;
int width_;
int height_;
rational pixel_aspect_;
rational pixel_aspect_;
/**
/**
* @brief Internal zoom value
*/
double zoom_;
double current_widget_scale_;
double zoom_;
double current_widget_scale_;
QScrollBar* horiz_scrollbar_;
QScrollBar* vert_scrollbar_;
QScrollBar *horiz_scrollbar_;
QScrollBar *vert_scrollbar_;
private slots:
void ScrollBarMoved();
void ScrollBarMoved();
};
}
+420 -366
View File
@@ -32,550 +32,604 @@
#include "common/qtutils.h"
#include "ui/icons/icons.h"
namespace olive {
namespace olive
{
#define super QTextEdit
ViewerTextEditor::ViewerTextEditor(double scale, QWidget *parent) :
super(parent),
transparent_clone_(nullptr),
block_update_toolbar_signal_(false),
forced_default_(false)
ViewerTextEditor::ViewerTextEditor(double scale, QWidget *parent)
: super(parent)
, transparent_clone_(nullptr)
, block_update_toolbar_signal_(false)
, forced_default_(false)
{
// Ensure default text color is white
QPalette p = palette();
p.setColor(QPalette::Text, Qt::white);
setPalette(p);
// Ensure default text color is white
QPalette p = palette();
p.setColor(QPalette::Text, Qt::white);
setPalette(p);
document()->setDefaultStyleSheet(QStringLiteral("body { color: white; }"));
document()->setDefaultStyleSheet(QStringLiteral("body { color: white; }"));
// Ensure cursor is visible at this scale
setCursorWidth(std::ceil(1.0 / scale));
// Ensure cursor is visible at this scale
setCursorWidth(std::ceil(1.0 / scale));
viewport()->setAutoFillBackground(false);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
connect(horizontalScrollBar(), &QScrollBar::rangeChanged, this, &ViewerTextEditor::LockScrollBarMaximumToZero);
connect(verticalScrollBar(), &QScrollBar::rangeChanged, this, &ViewerTextEditor::LockScrollBarMaximumToZero);
viewport()->setAutoFillBackground(false);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
connect(horizontalScrollBar(), &QScrollBar::rangeChanged, this,
&ViewerTextEditor::LockScrollBarMaximumToZero);
connect(verticalScrollBar(), &QScrollBar::rangeChanged, this,
&ViewerTextEditor::LockScrollBarMaximumToZero);
// Force DPI to the same one that we're using in the actual render
dpi_force_ = QImage(1, 1, QImage::Format_RGBA8888_Premultiplied);
// Force DPI to the same one that we're using in the actual render
dpi_force_ = QImage(1, 1, QImage::Format_RGBA8888_Premultiplied);
const int dpm = 3780;
dpi_force_.setDotsPerMeterX(dpm);
dpi_force_.setDotsPerMeterY(dpm);
document()->documentLayout()->setPaintDevice(&dpi_force_);
const int dpm = 3780;
dpi_force_.setDotsPerMeterX(dpm);
dpi_force_.setDotsPerMeterY(dpm);
document()->documentLayout()->setPaintDevice(&dpi_force_);
connect(this, &QTextEdit::currentCharFormatChanged, this, &ViewerTextEditor::FormatChanged);
connect(document(), &QTextDocument::contentsChanged, this, &ViewerTextEditor::DocumentChanged, Qt::QueuedConnection);
connect(this, &QTextEdit::currentCharFormatChanged, this,
&ViewerTextEditor::FormatChanged);
connect(document(), &QTextDocument::contentsChanged, this,
&ViewerTextEditor::DocumentChanged, Qt::QueuedConnection);
setAcceptRichText(false);
setAcceptRichText(false);
}
void ViewerTextEditor::ConnectToolBar(ViewerTextEditorToolBar *toolbar)
{
connect(toolbar, &ViewerTextEditorToolBar::FamilyChanged, this, &ViewerTextEditor::SetFamily);
connect(toolbar, &ViewerTextEditorToolBar::SizeChanged, this, &ViewerTextEditor::setFontPointSize);
connect(toolbar, &ViewerTextEditorToolBar::StyleChanged, this, &ViewerTextEditor::SetStyle);
connect(toolbar, &ViewerTextEditorToolBar::UnderlineChanged, this, &ViewerTextEditor::setFontUnderline);
connect(toolbar, &ViewerTextEditorToolBar::StrikethroughChanged, this, &ViewerTextEditor::SetFontStrikethrough);
connect(toolbar, &ViewerTextEditorToolBar::ColorChanged, this, &ViewerTextEditor::setTextColor);
connect(toolbar, &ViewerTextEditorToolBar::SmallCapsChanged, this, &ViewerTextEditor::SetSmallCaps);
connect(toolbar, &ViewerTextEditorToolBar::StretchChanged, this, &ViewerTextEditor::SetFontStretch);
connect(toolbar, &ViewerTextEditorToolBar::KerningChanged, this, &ViewerTextEditor::SetFontKerning);
connect(toolbar, &ViewerTextEditorToolBar::LineHeightChanged, this, &ViewerTextEditor::SetLineHeight);
connect(toolbar, &ViewerTextEditorToolBar::AlignmentChanged, this, [this](Qt::Alignment a){
this->setAlignment(a);
connect(toolbar, &ViewerTextEditorToolBar::FamilyChanged, this,
&ViewerTextEditor::SetFamily);
connect(toolbar, &ViewerTextEditorToolBar::SizeChanged, this,
&ViewerTextEditor::setFontPointSize);
connect(toolbar, &ViewerTextEditorToolBar::StyleChanged, this,
&ViewerTextEditor::SetStyle);
connect(toolbar, &ViewerTextEditorToolBar::UnderlineChanged, this,
&ViewerTextEditor::setFontUnderline);
connect(toolbar, &ViewerTextEditorToolBar::StrikethroughChanged, this,
&ViewerTextEditor::SetFontStrikethrough);
connect(toolbar, &ViewerTextEditorToolBar::ColorChanged, this,
&ViewerTextEditor::setTextColor);
connect(toolbar, &ViewerTextEditorToolBar::SmallCapsChanged, this,
&ViewerTextEditor::SetSmallCaps);
connect(toolbar, &ViewerTextEditorToolBar::StretchChanged, this,
&ViewerTextEditor::SetFontStretch);
connect(toolbar, &ViewerTextEditorToolBar::KerningChanged, this,
&ViewerTextEditor::SetFontKerning);
connect(toolbar, &ViewerTextEditorToolBar::LineHeightChanged, this,
&ViewerTextEditor::SetLineHeight);
connect(toolbar, &ViewerTextEditorToolBar::AlignmentChanged, this,
[this](Qt::Alignment a) {
this->setAlignment(a);
// Ensure no buttons are checked that shouldn't be
static_cast<ViewerTextEditorToolBar*>(sender())->SetAlignment(a);
});
// Ensure no buttons are checked that shouldn't be
static_cast<ViewerTextEditorToolBar *>(sender())->SetAlignment(
a);
});
UpdateToolBar(toolbar, this->currentCharFormat(), this->textCursor().blockFormat(), this->alignment());
UpdateToolBar(toolbar, this->currentCharFormat(),
this->textCursor().blockFormat(), this->alignment());
toolbars_.append(toolbar);
toolbars_.append(toolbar);
}
void ViewerTextEditor::Paint(QPainter *p, Qt::Alignment valign)
{
QAbstractTextDocumentLayout::PaintContext ctx;
QAbstractTextDocumentLayout::PaintContext ctx;
QRect clip = this->rect();
p->setClipRect(clip, Qt::IntersectClip);
ctx.clip = clip;
QRect clip = this->rect();
p->setClipRect(clip, Qt::IntersectClip);
ctx.clip = clip;
ctx.cursorPosition = this->textCursor().position();
ctx.cursorPosition = this->textCursor().position();
if (this->textCursor().hasSelection()) {
QAbstractTextDocumentLayout::Selection selection;
selection.cursor = this->textCursor();
if (this->textCursor().hasSelection()) {
QAbstractTextDocumentLayout::Selection selection;
selection.cursor = this->textCursor();
QPalette::ColorGroup cg = this->hasFocus() ? QPalette::Active : QPalette::Inactive;
QBrush b = ctx.palette.brush(cg, QPalette::Highlight);
QColor bc = b.color();
bc.setAlpha(128);
b.setColor(bc);
selection.format.setBackground(b);
QStyleOption opt;
opt.initFrom(this);
if (this->style()->styleHint(QStyle::SH_RichText_FullWidthSelection, &opt, this)) {
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
}
ctx.selections.append(selection);
}
QPalette::ColorGroup cg = this->hasFocus() ? QPalette::Active :
QPalette::Inactive;
QBrush b = ctx.palette.brush(cg, QPalette::Highlight);
QColor bc = b.color();
bc.setAlpha(128);
b.setColor(bc);
selection.format.setBackground(b);
QStyleOption opt;
opt.initFrom(this);
if (this->style()->styleHint(QStyle::SH_RichText_FullWidthSelection,
&opt, this)) {
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
}
ctx.selections.append(selection);
}
switch (valign) {
case Qt::AlignTop:
// Do nothing
break;
case Qt::AlignVCenter:
p->translate(0, clip.height()/2-document()->size().height()/2);
break;
case Qt::AlignBottom:
p->translate(0, clip.height()-document()->size().height());
break;
}
switch (valign) {
case Qt::AlignTop:
// Do nothing
break;
case Qt::AlignVCenter:
p->translate(0, clip.height() / 2 - document()->size().height() / 2);
break;
case Qt::AlignBottom:
p->translate(0, clip.height() - document()->size().height());
break;
}
const bool use_transparent_clone = true;
if (transparent_clone_ && use_transparent_clone) {
transparent_clone_->setPageSize(this->document()->pageSize());
transparent_clone_->documentLayout()->draw(p, ctx);
} else {
document()->documentLayout()->draw(p, ctx);
}
const bool use_transparent_clone = true;
if (transparent_clone_ && use_transparent_clone) {
transparent_clone_->setPageSize(this->document()->pageSize());
transparent_clone_->documentLayout()->draw(p, ctx);
} else {
document()->documentLayout()->draw(p, ctx);
}
}
void ViewerTextEditor::paintEvent(QPaintEvent *e)
{
// Disable painting
// Disable painting
}
void ViewerTextEditor::UpdateToolBar(ViewerTextEditorToolBar *toolbar, const QTextCharFormat &f, const QTextBlockFormat &b, Qt::Alignment alignment)
void ViewerTextEditor::UpdateToolBar(ViewerTextEditorToolBar *toolbar,
const QTextCharFormat &f,
const QTextBlockFormat &b,
Qt::Alignment alignment)
{
QStringList families = f.fontFamilies().toStringList();
QString family;
if (families.isEmpty()) {
family = qApp->font().family();
} else {
family = families.first();
}
QStringList families = f.fontFamilies().toStringList();
QString family;
if (families.isEmpty()) {
family = qApp->font().family();
} else {
family = families.first();
}
QString style = f.fontStyleName().toString();
QStringList styles = QFontDatabase().styles(family);
if (!styles.isEmpty() && (style.isEmpty() || !styles.contains(style))) {
// There seems to be no better way to find the "regular" style outside of this heuristic.
// Feel free to add more if a font isn't working right.
style = QStringLiteral("Regular");
if (!styles.contains(style)) {
style = QStringLiteral("Normal");
}
if (!styles.contains(style)) {
style = QStringLiteral("R");
}
if (!styles.contains(style)) {
style = styles.first();
}
}
QString style = f.fontStyleName().toString();
QStringList styles = QFontDatabase().styles(family);
if (!styles.isEmpty() && (style.isEmpty() || !styles.contains(style))) {
// There seems to be no better way to find the "regular" style outside of this heuristic.
// Feel free to add more if a font isn't working right.
style = QStringLiteral("Regular");
if (!styles.contains(style)) {
style = QStringLiteral("Normal");
}
if (!styles.contains(style)) {
style = QStringLiteral("R");
}
if (!styles.contains(style)) {
style = styles.first();
}
}
toolbar->SetFontFamily(family);
toolbar->SetFontSize(f.fontPointSize());
toolbar->SetStyle(style);
toolbar->SetUnderline(f.fontUnderline());
toolbar->SetStrikethrough(f.fontStrikeOut());
toolbar->SetAlignment(alignment);
toolbar->SetColor(f.foreground().color());
toolbar->SetSmallCaps(f.fontCapitalization() == QFont::SmallCaps);
toolbar->SetStretch(f.fontStretch() == 0 ? 100 : f.fontStretch());
toolbar->SetKerning(f.fontLetterSpacing() == 0.0 ? 100 : f.fontLetterSpacing());
toolbar->SetLineHeight(b.lineHeight() == 0.0 ? 100 : b.lineHeight());
toolbar->SetFontFamily(family);
toolbar->SetFontSize(f.fontPointSize());
toolbar->SetStyle(style);
toolbar->SetUnderline(f.fontUnderline());
toolbar->SetStrikethrough(f.fontStrikeOut());
toolbar->SetAlignment(alignment);
toolbar->SetColor(f.foreground().color());
toolbar->SetSmallCaps(f.fontCapitalization() == QFont::SmallCaps);
toolbar->SetStretch(f.fontStretch() == 0 ? 100 : f.fontStretch());
toolbar->SetKerning(f.fontLetterSpacing() == 0.0 ? 100 :
f.fontLetterSpacing());
toolbar->SetLineHeight(b.lineHeight() == 0.0 ? 100 : b.lineHeight());
}
void ViewerTextEditor::FormatChanged(const QTextCharFormat &f)
{
if (!block_update_toolbar_signal_) {
foreach (ViewerTextEditorToolBar *toolbar, toolbars_) {
UpdateToolBar(toolbar, f, textCursor().blockFormat(), this->alignment());
}
}
if (!block_update_toolbar_signal_) {
foreach (ViewerTextEditorToolBar *toolbar, toolbars_) {
UpdateToolBar(toolbar, f, textCursor().blockFormat(),
this->alignment());
}
}
if (!(document()->blockCount() == 1 && document()->firstBlock().text().isEmpty())) {
default_fmt_ = f;
}
if (!(document()->blockCount() == 1 &&
document()->firstBlock().text().isEmpty())) {
default_fmt_ = f;
}
}
void ViewerTextEditor::SetFamily(const QString &s)
{
ViewerTextEditorToolBar *toolbar = static_cast<ViewerTextEditorToolBar *>(sender());
ViewerTextEditorToolBar *toolbar =
static_cast<ViewerTextEditorToolBar *>(sender());
QTextCharFormat f;
f.setFontFamilies({s});
QTextCharFormat f;
f.setFontFamilies({ s });
ApplyStyle(&f, s, toolbar->GetFontStyleName());
ApplyStyle(&f, s, toolbar->GetFontStyleName());
MergeCharFormat(f);
MergeCharFormat(f);
}
void ViewerTextEditor::SetStyle(const QString &s)
{
ViewerTextEditorToolBar *toolbar = static_cast<ViewerTextEditorToolBar *>(sender());
ViewerTextEditorToolBar *toolbar =
static_cast<ViewerTextEditorToolBar *>(sender());
QTextCharFormat f;
QTextCharFormat f;
ApplyStyle(&f, toolbar->GetFontFamily(), s);
ApplyStyle(&f, toolbar->GetFontFamily(), s);
MergeCharFormat(f);
MergeCharFormat(f);
}
void ViewerTextEditor::SetFontStrikethrough(bool e)
{
QTextCharFormat f;
f.setFontStrikeOut(e);
MergeCharFormat(f);
QTextCharFormat f;
f.setFontStrikeOut(e);
MergeCharFormat(f);
}
void ViewerTextEditor::SetSmallCaps(bool e)
{
QTextCharFormat f;
f.setFontCapitalization(e ? QFont::SmallCaps : QFont::MixedCase);
MergeCharFormat(f);
QTextCharFormat f;
f.setFontCapitalization(e ? QFont::SmallCaps : QFont::MixedCase);
MergeCharFormat(f);
}
void ViewerTextEditor::SetFontStretch(int i)
{
QTextCharFormat f;
f.setFontStretch(i);
MergeCharFormat(f);
QTextCharFormat f;
f.setFontStretch(i);
MergeCharFormat(f);
}
void ViewerTextEditor::SetFontKerning(qreal i)
{
QTextCharFormat f;
f.setFontLetterSpacing(i);
MergeCharFormat(f);
QTextCharFormat f;
f.setFontLetterSpacing(i);
MergeCharFormat(f);
}
void ViewerTextEditor::MergeCharFormat(const QTextCharFormat &fmt)
{
// mergeCurrentCharFormat throws a currentCharFormatChanged signal that updates the toolbar,
// this can be undesirable if the user is currently typing a font
block_update_toolbar_signal_ = true;
mergeCurrentCharFormat(fmt);
//default_fmt_ = this->currentCharFormat();
block_update_toolbar_signal_ = false;
// mergeCurrentCharFormat throws a currentCharFormatChanged signal that updates the toolbar,
// this can be undesirable if the user is currently typing a font
block_update_toolbar_signal_ = true;
mergeCurrentCharFormat(fmt);
//default_fmt_ = this->currentCharFormat();
block_update_toolbar_signal_ = false;
}
void ViewerTextEditor::ApplyStyle(QTextCharFormat *format, const QString &family, const QString &style)
void ViewerTextEditor::ApplyStyle(QTextCharFormat *format,
const QString &family, const QString &style)
{
// NOTE: Windows appears to require setting weight and italic manually, while macOS and Linux are
// perfectly fine with just the style name
format->setFontWeight(QFontDatabase().weight(family, style));
format->setFontItalic(QFontDatabase().italic(family, style));
// NOTE: Windows appears to require setting weight and italic manually, while macOS and Linux are
// perfectly fine with just the style name
format->setFontWeight(QFontDatabase().weight(family, style));
format->setFontItalic(QFontDatabase().italic(family, style));
format->setFontStyleName(style);
format->setFontStyleName(style);
}
void ViewerTextEditor::SetLineHeight(qreal i)
{
QTextBlockFormat f = this->textCursor().blockFormat();
f.setLineHeight(i, QTextBlockFormat::ProportionalHeight);
this->textCursor().setBlockFormat(f);
QTextBlockFormat f = this->textCursor().blockFormat();
f.setLineHeight(i, QTextBlockFormat::ProportionalHeight);
this->textCursor().setBlockFormat(f);
}
void ViewerTextEditor::LockScrollBarMaximumToZero()
{
static_cast<QScrollBar*>(sender())->setMaximum(0);
static_cast<QScrollBar *>(sender())->setMaximum(0);
}
void ViewerTextEditor::DocumentChanged()
{
if (document()->blockCount() == 1 && document()->firstBlock().text().isEmpty()) {
if (!forced_default_) {
QTextCursor c(document()->firstBlock());
c.setBlockCharFormat(default_fmt_);
forced_default_ = true;
}
} else {
if (default_fmt_.isEmpty()) {
default_fmt_ = document()->firstBlock().charFormat();
}
forced_default_ = false;
}
if (document()->blockCount() == 1 &&
document()->firstBlock().text().isEmpty()) {
if (!forced_default_) {
QTextCursor c(document()->firstBlock());
c.setBlockCharFormat(default_fmt_);
forced_default_ = true;
}
} else {
if (default_fmt_.isEmpty()) {
default_fmt_ = document()->firstBlock().charFormat();
}
forced_default_ = false;
}
// HACK: We want to show the text cursor and selections without necessarily rendering the text,
// because the text is already being rendered underneath the gizmo (and rendering twice will
// alter the overall look of the text while editing). This is something that Qt does not
// support by default, and while it could be solved by subclassing QAbstractTextDocumentLayout,
// this seems like overkill since 99% of QTextDocumentLayout's (the subclass used by default)
// functionality and would need to be fully implemented ourselves. So instead, we clone the
// document, set all of its colors to rgba(0,0,0,0) to make them transparent, and draw that
// document instead. The result is cursor and selections being rendered without the text.
// While this isn't the fastest code, nor is it the cleanest solution, it definitely works.
delete transparent_clone_;
transparent_clone_ = document()->clone(this);
transparent_clone_->documentLayout()->setPaintDevice(&dpi_force_);
transparent_clone_->documentLayout()->setProperty("cursorWidth", document()->documentLayout()->property("cursorWidth"));
// HACK: We want to show the text cursor and selections without necessarily rendering the text,
// because the text is already being rendered underneath the gizmo (and rendering twice will
// alter the overall look of the text while editing). This is something that Qt does not
// support by default, and while it could be solved by subclassing QAbstractTextDocumentLayout,
// this seems like overkill since 99% of QTextDocumentLayout's (the subclass used by default)
// functionality and would need to be fully implemented ourselves. So instead, we clone the
// document, set all of its colors to rgba(0,0,0,0) to make them transparent, and draw that
// document instead. The result is cursor and selections being rendered without the text.
// While this isn't the fastest code, nor is it the cleanest solution, it definitely works.
delete transparent_clone_;
transparent_clone_ = document()->clone(this);
transparent_clone_->documentLayout()->setPaintDevice(&dpi_force_);
transparent_clone_->documentLayout()->setProperty(
"cursorWidth", document()->documentLayout()->property("cursorWidth"));
QTextCursor cursor(transparent_clone_);
cursor.select(QTextCursor::Document);
QTextCursor cursor(transparent_clone_);
cursor.select(QTextCursor::Document);
QTextCharFormat fmt;
fmt.setForeground(QColor(0, 0, 0, 0));
cursor.mergeCharFormat(fmt);
QTextCharFormat fmt;
fmt.setForeground(QColor(0, 0, 0, 0));
cursor.mergeCharFormat(fmt);
}
ViewerTextEditorToolBar::ViewerTextEditorToolBar(QWidget *parent) :
QWidget(parent),
painted_(false),
drag_enabled_(true)
ViewerTextEditorToolBar::ViewerTextEditorToolBar(QWidget *parent)
: QWidget(parent)
, painted_(false)
, drag_enabled_(true)
{
QVBoxLayout *outer_layout = new QVBoxLayout(this);
QVBoxLayout *outer_layout = new QVBoxLayout(this);
const int advanced_slider_width = QtUtils::QFontMetricsWidth(fontMetrics(), QStringLiteral("9999.9%"));
const int advanced_slider_width =
QtUtils::QFontMetricsWidth(fontMetrics(), QStringLiteral("9999.9%"));
{
QHBoxLayout *row_layout = new QHBoxLayout();
row_layout->setSpacing(0);
outer_layout->addLayout(row_layout);
{
QHBoxLayout *row_layout = new QHBoxLayout();
row_layout->setSpacing(0);
outer_layout->addLayout(row_layout);
font_combo_ = new QFontComboBox();
connect(font_combo_, &QFontComboBox::currentTextChanged, this, &ViewerTextEditorToolBar::UpdateFontStyleListAndEmitFamilyChanged);
row_layout->addWidget(font_combo_);
font_combo_ = new QFontComboBox();
connect(
font_combo_, &QFontComboBox::currentTextChanged, this,
&ViewerTextEditorToolBar::UpdateFontStyleListAndEmitFamilyChanged);
row_layout->addWidget(font_combo_);
font_sz_slider_ = new FloatSlider();
font_sz_slider_->SetMinimum(0.1);
font_sz_slider_->SetMaximum(9999.9);
font_sz_slider_->SetDecimalPlaces(1);
font_sz_slider_->SetAlignment(Qt::AlignCenter);
font_sz_slider_->setFixedWidth(advanced_slider_width);
connect(font_sz_slider_, &FloatSlider::ValueChanged, this, &ViewerTextEditorToolBar::SizeChanged);
font_sz_slider_->SetLadderElementCount(2);
row_layout->addWidget(font_sz_slider_);
font_sz_slider_ = new FloatSlider();
font_sz_slider_->SetMinimum(0.1);
font_sz_slider_->SetMaximum(9999.9);
font_sz_slider_->SetDecimalPlaces(1);
font_sz_slider_->SetAlignment(Qt::AlignCenter);
font_sz_slider_->setFixedWidth(advanced_slider_width);
connect(font_sz_slider_, &FloatSlider::ValueChanged, this,
&ViewerTextEditorToolBar::SizeChanged);
font_sz_slider_->SetLadderElementCount(2);
row_layout->addWidget(font_sz_slider_);
style_combo_ = new QComboBox();
connect(style_combo_, &QComboBox::currentTextChanged, this, &ViewerTextEditorToolBar::StyleChanged);
row_layout->addWidget(style_combo_);
style_combo_ = new QComboBox();
connect(style_combo_, &QComboBox::currentTextChanged, this,
&ViewerTextEditorToolBar::StyleChanged);
row_layout->addWidget(style_combo_);
underline_btn_ = new QPushButton();
connect(underline_btn_, &QPushButton::clicked, this, &ViewerTextEditorToolBar::UnderlineChanged);
underline_btn_->setCheckable(true);
underline_btn_->setIcon(icon::TextUnderline);
row_layout->addWidget(underline_btn_);
underline_btn_ = new QPushButton();
connect(underline_btn_, &QPushButton::clicked, this,
&ViewerTextEditorToolBar::UnderlineChanged);
underline_btn_->setCheckable(true);
underline_btn_->setIcon(icon::TextUnderline);
row_layout->addWidget(underline_btn_);
strikethrough_btn_ = new QPushButton();
connect(strikethrough_btn_, &QPushButton::clicked, this, &ViewerTextEditorToolBar::StrikethroughChanged);
strikethrough_btn_->setCheckable(true);
strikethrough_btn_->setIcon(icon::TextStrikethrough);
row_layout->addWidget(strikethrough_btn_);
strikethrough_btn_ = new QPushButton();
connect(strikethrough_btn_, &QPushButton::clicked, this,
&ViewerTextEditorToolBar::StrikethroughChanged);
strikethrough_btn_->setCheckable(true);
strikethrough_btn_->setIcon(icon::TextStrikethrough);
row_layout->addWidget(strikethrough_btn_);
AddSpacer(row_layout);
AddSpacer(row_layout);
color_btn_ = new QPushButton();
color_btn_->setAutoFillBackground(true);
connect(color_btn_, &QPushButton::clicked, this, [this]{
QColor c = color_btn_->property("color").value<QColor>();
color_btn_ = new QPushButton();
color_btn_->setAutoFillBackground(true);
connect(color_btn_, &QPushButton::clicked, this, [this] {
QColor c = color_btn_->property("color").value<QColor>();
QColorDialog cd(c, this);
if (cd.exec() == QDialog::Accepted) {
c = cd.selectedColor();
SetColor(c);
emit ColorChanged(c);
}
});
row_layout->addWidget(color_btn_);
QColorDialog cd(c, this);
if (cd.exec() == QDialog::Accepted) {
c = cd.selectedColor();
SetColor(c);
emit ColorChanged(c);
}
});
row_layout->addWidget(color_btn_);
row_layout->addStretch();
}
row_layout->addStretch();
}
{
QHBoxLayout *row_layout = new QHBoxLayout();
row_layout->setSpacing(0);
outer_layout->addLayout(row_layout);
{
QHBoxLayout *row_layout = new QHBoxLayout();
row_layout->setSpacing(0);
outer_layout->addLayout(row_layout);
align_left_btn_ = new QPushButton();
align_left_btn_->setCheckable(true);
align_left_btn_->setIcon(icon::TextAlignLeft);
connect(align_left_btn_, &QPushButton::clicked, this, [this]{emit AlignmentChanged(Qt::AlignLeft);});
row_layout->addWidget(align_left_btn_);
align_left_btn_ = new QPushButton();
align_left_btn_->setCheckable(true);
align_left_btn_->setIcon(icon::TextAlignLeft);
connect(align_left_btn_, &QPushButton::clicked, this,
[this] { emit AlignmentChanged(Qt::AlignLeft); });
row_layout->addWidget(align_left_btn_);
align_center_btn_ = new QPushButton();
align_center_btn_->setCheckable(true);
align_center_btn_->setIcon(icon::TextAlignCenter);
connect(align_center_btn_, &QPushButton::clicked, this, [this]{emit AlignmentChanged(Qt::AlignHCenter);});
row_layout->addWidget(align_center_btn_);
align_center_btn_ = new QPushButton();
align_center_btn_->setCheckable(true);
align_center_btn_->setIcon(icon::TextAlignCenter);
connect(align_center_btn_, &QPushButton::clicked, this,
[this] { emit AlignmentChanged(Qt::AlignHCenter); });
row_layout->addWidget(align_center_btn_);
align_right_btn_ = new QPushButton();
align_right_btn_->setCheckable(true);
align_right_btn_->setIcon(icon::TextAlignRight);
connect(align_right_btn_, &QPushButton::clicked, this, [this]{emit AlignmentChanged(Qt::AlignRight);});
row_layout->addWidget(align_right_btn_);
align_right_btn_ = new QPushButton();
align_right_btn_->setCheckable(true);
align_right_btn_->setIcon(icon::TextAlignRight);
connect(align_right_btn_, &QPushButton::clicked, this,
[this] { emit AlignmentChanged(Qt::AlignRight); });
row_layout->addWidget(align_right_btn_);
align_justify_btn_ = new QPushButton();
align_justify_btn_->setCheckable(true);
align_justify_btn_->setIcon(icon::TextAlignJustify);
connect(align_justify_btn_, &QPushButton::clicked, this, [this]{emit AlignmentChanged(Qt::AlignJustify);});
row_layout->addWidget(align_justify_btn_);
align_justify_btn_ = new QPushButton();
align_justify_btn_->setCheckable(true);
align_justify_btn_->setIcon(icon::TextAlignJustify);
connect(align_justify_btn_, &QPushButton::clicked, this,
[this] { emit AlignmentChanged(Qt::AlignJustify); });
row_layout->addWidget(align_justify_btn_);
AddSpacer(row_layout);
AddSpacer(row_layout);
align_top_btn_ = new QPushButton();
align_top_btn_->setCheckable(true);
align_top_btn_->setIcon(icon::TextAlignTop);
connect(align_top_btn_, &QPushButton::clicked, this, [this]{emit VerticalAlignmentChanged(Qt::AlignTop);});
row_layout->addWidget(align_top_btn_);
align_top_btn_ = new QPushButton();
align_top_btn_->setCheckable(true);
align_top_btn_->setIcon(icon::TextAlignTop);
connect(align_top_btn_, &QPushButton::clicked, this,
[this] { emit VerticalAlignmentChanged(Qt::AlignTop); });
row_layout->addWidget(align_top_btn_);
align_middle_btn_ = new QPushButton();
align_middle_btn_->setCheckable(true);
align_middle_btn_->setIcon(icon::TextAlignMiddle);
connect(align_middle_btn_, &QPushButton::clicked, this, [this]{emit VerticalAlignmentChanged(Qt::AlignVCenter);});
row_layout->addWidget(align_middle_btn_);
align_middle_btn_ = new QPushButton();
align_middle_btn_->setCheckable(true);
align_middle_btn_->setIcon(icon::TextAlignMiddle);
connect(align_middle_btn_, &QPushButton::clicked, this,
[this] { emit VerticalAlignmentChanged(Qt::AlignVCenter); });
row_layout->addWidget(align_middle_btn_);
align_bottom_btn_ = new QPushButton();
align_bottom_btn_->setCheckable(true);
align_bottom_btn_->setIcon(icon::TextAlignBottom);
connect(align_bottom_btn_, &QPushButton::clicked, this, [this]{emit VerticalAlignmentChanged(Qt::AlignBottom);});
row_layout->addWidget(align_bottom_btn_);
align_bottom_btn_ = new QPushButton();
align_bottom_btn_->setCheckable(true);
align_bottom_btn_->setIcon(icon::TextAlignBottom);
connect(align_bottom_btn_, &QPushButton::clicked, this,
[this] { emit VerticalAlignmentChanged(Qt::AlignBottom); });
row_layout->addWidget(align_bottom_btn_);
AddSpacer(row_layout);
AddSpacer(row_layout);
small_caps_btn_ = new QPushButton();
small_caps_btn_->setIcon(icon::TextSmallCaps);
small_caps_btn_->setCheckable(true);
connect(small_caps_btn_, &QPushButton::clicked, this, &ViewerTextEditorToolBar::SmallCapsChanged);
row_layout->addWidget(small_caps_btn_);
small_caps_btn_ = new QPushButton();
small_caps_btn_->setIcon(icon::TextSmallCaps);
small_caps_btn_->setCheckable(true);
connect(small_caps_btn_, &QPushButton::clicked, this,
&ViewerTextEditorToolBar::SmallCapsChanged);
row_layout->addWidget(small_caps_btn_);
AddSpacer(row_layout);
AddSpacer(row_layout);
row_layout->addWidget(new QLabel(tr("Stretch: "))); // FIXME: Procure icon
row_layout->addWidget(
new QLabel(tr("Stretch: "))); // FIXME: Procure icon
stretch_slider_ = new IntegerSlider();
stretch_slider_->SetMinimum(0);
stretch_slider_->SetDefaultValue(100);
stretch_slider_->setFixedWidth(advanced_slider_width);
stretch_slider_->SetFormat(tr("%1%"));
connect(stretch_slider_, &IntegerSlider::ValueChanged, this, &ViewerTextEditorToolBar::StretchChanged);
row_layout->addWidget(stretch_slider_);
stretch_slider_ = new IntegerSlider();
stretch_slider_->SetMinimum(0);
stretch_slider_->SetDefaultValue(100);
stretch_slider_->setFixedWidth(advanced_slider_width);
stretch_slider_->SetFormat(tr("%1%"));
connect(stretch_slider_, &IntegerSlider::ValueChanged, this,
&ViewerTextEditorToolBar::StretchChanged);
row_layout->addWidget(stretch_slider_);
row_layout->addWidget(new QLabel(tr("Kerning: "))); // FIXME: Procure icon
row_layout->addWidget(
new QLabel(tr("Kerning: "))); // FIXME: Procure icon
kerning_slider_ = new FloatSlider();
kerning_slider_->SetMinimum(0);
kerning_slider_->SetDefaultValue(100);
kerning_slider_->SetDecimalPlaces(1);
kerning_slider_->setFixedWidth(advanced_slider_width);
kerning_slider_->SetFormat(tr("%1%"));
connect(kerning_slider_, &FloatSlider::ValueChanged, this, &ViewerTextEditorToolBar::KerningChanged);
row_layout->addWidget(kerning_slider_);
kerning_slider_ = new FloatSlider();
kerning_slider_->SetMinimum(0);
kerning_slider_->SetDefaultValue(100);
kerning_slider_->SetDecimalPlaces(1);
kerning_slider_->setFixedWidth(advanced_slider_width);
kerning_slider_->SetFormat(tr("%1%"));
connect(kerning_slider_, &FloatSlider::ValueChanged, this,
&ViewerTextEditorToolBar::KerningChanged);
row_layout->addWidget(kerning_slider_);
row_layout->addWidget(new QLabel(tr("Line Height: "))); // FIXME: Procure icon
row_layout->addWidget(
new QLabel(tr("Line Height: "))); // FIXME: Procure icon
line_height_slider_ = new FloatSlider();
line_height_slider_->SetMinimum(0);
line_height_slider_->SetDefaultValue(100);
line_height_slider_->SetDecimalPlaces(1);
line_height_slider_->setFixedWidth(advanced_slider_width);
line_height_slider_->SetFormat(tr("%1%"));
connect(line_height_slider_, &FloatSlider::ValueChanged, this, &ViewerTextEditorToolBar::LineHeightChanged);
row_layout->addWidget(line_height_slider_);
line_height_slider_ = new FloatSlider();
line_height_slider_->SetMinimum(0);
line_height_slider_->SetDefaultValue(100);
line_height_slider_->SetDecimalPlaces(1);
line_height_slider_->setFixedWidth(advanced_slider_width);
line_height_slider_->SetFormat(tr("%1%"));
connect(line_height_slider_, &FloatSlider::ValueChanged, this,
&ViewerTextEditorToolBar::LineHeightChanged);
row_layout->addWidget(line_height_slider_);
row_layout->addStretch();
}
row_layout->addStretch();
}
setAutoFillBackground(true);
setAutoFillBackground(true);
resize(sizeHint());
resize(sizeHint());
}
void ViewerTextEditorToolBar::SetAlignment(Qt::Alignment a)
{
align_left_btn_->setChecked(a == Qt::AlignLeft);
align_center_btn_->setChecked(a == Qt::AlignHCenter);
align_right_btn_->setChecked(a == Qt::AlignRight);
align_justify_btn_->setChecked(a == Qt::AlignJustify);
align_left_btn_->setChecked(a == Qt::AlignLeft);
align_center_btn_->setChecked(a == Qt::AlignHCenter);
align_right_btn_->setChecked(a == Qt::AlignRight);
align_justify_btn_->setChecked(a == Qt::AlignJustify);
}
void ViewerTextEditorToolBar::SetVerticalAlignment(Qt::Alignment a)
{
align_top_btn_->setChecked(a == Qt::AlignTop);
align_middle_btn_->setChecked(a == Qt::AlignVCenter);
align_bottom_btn_->setChecked(a == Qt::AlignBottom);
align_top_btn_->setChecked(a == Qt::AlignTop);
align_middle_btn_->setChecked(a == Qt::AlignVCenter);
align_bottom_btn_->setChecked(a == Qt::AlignBottom);
}
void ViewerTextEditorToolBar::SetColor(const QColor &c)
{
color_btn_->setProperty("color", c);
color_btn_->setStyleSheet(QStringLiteral("QPushButton { background: %1; }").arg(c.name()));
color_btn_->setProperty("color", c);
color_btn_->setStyleSheet(
QStringLiteral("QPushButton { background: %1; }").arg(c.name()));
}
void ViewerTextEditorToolBar::closeEvent(QCloseEvent *event)
{
event->ignore();
event->ignore();
}
void ViewerTextEditorToolBar::paintEvent(QPaintEvent *event)
{
if (!painted_) {
emit FirstPaint();
painted_ = true;
}
QWidget::paintEvent(event);
if (!painted_) {
emit FirstPaint();
painted_ = true;
}
QWidget::paintEvent(event);
}
void ViewerTextEditorToolBar::AddSpacer(QLayout *l)
{
const int spacing = this->fontMetrics().height()/4;
QWidget *a = new QWidget();
a->setFixedSize(spacing, 1);
l->addWidget(a);
const int spacing = this->fontMetrics().height() / 4;
QWidget *a = new QWidget();
a->setFixedSize(spacing, 1);
l->addWidget(a);
l->addWidget(QtUtils::CreateVerticalLine());
l->addWidget(QtUtils::CreateVerticalLine());
QWidget *b = new QWidget();
b->setFixedSize(spacing, 1);
l->addWidget(b);
QWidget *b = new QWidget();
b->setFixedSize(spacing, 1);
l->addWidget(b);
}
void ViewerTextEditorToolBar::UpdateFontStyleList(const QString &family)
{
QString temp = style_combo_->currentText();
QString temp = style_combo_->currentText();
style_combo_->blockSignals(true);
style_combo_->clear();
QStringList l = QFontDatabase().styles(family);
foreach (const QString &style, l) {
style_combo_->addItem(style);
}
style_combo_->setCurrentText(temp);
style_combo_->blockSignals(false);
style_combo_->blockSignals(true);
style_combo_->clear();
QStringList l = QFontDatabase().styles(family);
foreach (const QString &style, l) {
style_combo_->addItem(style);
}
style_combo_->setCurrentText(temp);
style_combo_->blockSignals(false);
}
void ViewerTextEditorToolBar::UpdateFontStyleListAndEmitFamilyChanged(const QString &family)
void ViewerTextEditorToolBar::UpdateFontStyleListAndEmitFamilyChanged(
const QString &family)
{
// Ensures correct ordering of commands
UpdateFontStyleList(family);
emit FamilyChanged(family);
// Ensures correct ordering of commands
UpdateFontStyleList(family);
emit FamilyChanged(family);
}
void ViewerTextEditorToolBar::mousePressEvent(QMouseEvent *event)
{
QWidget::mousePressEvent(event);
QWidget::mousePressEvent(event);
if (event->button() == Qt::LeftButton && drag_enabled_) {
drag_anchor_ = event->pos();
}
if (event->button() == Qt::LeftButton && drag_enabled_) {
drag_anchor_ = event->pos();
}
}
void ViewerTextEditorToolBar::mouseMoveEvent(QMouseEvent *event)
{
QWidget::mouseMoveEvent(event);
QWidget::mouseMoveEvent(event);
if ((event->buttons() & Qt::LeftButton) && drag_enabled_) {
this->move(mapToParent(QPoint(event->pos() - drag_anchor_)));
}
if ((event->buttons() & Qt::LeftButton) && drag_enabled_) {
this->move(mapToParent(QPoint(event->pos() - drag_anchor_)));
}
}
void ViewerTextEditorToolBar::mouseReleaseEvent(QMouseEvent *event)
{
QWidget::mouseReleaseEvent(event);
QWidget::mouseReleaseEvent(event);
}
}
+143 -109
View File
@@ -30,176 +30,210 @@
#include "widget/slider/floatslider.h"
#include "widget/slider/integerslider.h"
namespace olive {
class ViewerTextEditorToolBar : public QWidget
namespace olive
{
Q_OBJECT
class ViewerTextEditorToolBar : public QWidget {
Q_OBJECT
public:
ViewerTextEditorToolBar(QWidget *parent = nullptr);
ViewerTextEditorToolBar(QWidget *parent = nullptr);
QString GetFontFamily() const
{
return font_combo_->currentText();
}
QString GetFontFamily() const
{
return font_combo_->currentText();
}
QString GetFontStyleName() const
{
return style_combo_->currentText();
}
QString GetFontStyleName() const
{
return style_combo_->currentText();
}
public slots:
void SetFontFamily(QString s)
{
font_combo_->blockSignals(true);
font_combo_->setCurrentFont(s);
UpdateFontStyleList(s);
font_combo_->blockSignals(false);
}
void SetFontFamily(QString s)
{
font_combo_->blockSignals(true);
font_combo_->setCurrentFont(s);
UpdateFontStyleList(s);
font_combo_->blockSignals(false);
}
void SetStyle(QString style)
{
style_combo_->blockSignals(true);
style_combo_->setCurrentText(style);
style_combo_->blockSignals(false);
}
void SetStyle(QString style)
{
style_combo_->blockSignals(true);
style_combo_->setCurrentText(style);
style_combo_->blockSignals(false);
}
void SetFontSize(double d) { font_sz_slider_->SetValue(d); }
void SetUnderline(bool e) { underline_btn_->setChecked(e); }
void SetStrikethrough(bool e) { strikethrough_btn_->setChecked(e); }
void SetAlignment(Qt::Alignment a);
void SetVerticalAlignment(Qt::Alignment a);
void SetColor(const QColor &c);
void SetSmallCaps(bool e) { small_caps_btn_->setChecked(e); }
void SetStretch(int i) { stretch_slider_->SetValue(i); }
void SetKerning(qreal i) { kerning_slider_->SetValue(i); }
void SetLineHeight(qreal i) { line_height_slider_->SetValue(i); }
void SetFontSize(double d)
{
font_sz_slider_->SetValue(d);
}
void SetUnderline(bool e)
{
underline_btn_->setChecked(e);
}
void SetStrikethrough(bool e)
{
strikethrough_btn_->setChecked(e);
}
void SetAlignment(Qt::Alignment a);
void SetVerticalAlignment(Qt::Alignment a);
void SetColor(const QColor &c);
void SetSmallCaps(bool e)
{
small_caps_btn_->setChecked(e);
}
void SetStretch(int i)
{
stretch_slider_->SetValue(i);
}
void SetKerning(qreal i)
{
kerning_slider_->SetValue(i);
}
void SetLineHeight(qreal i)
{
line_height_slider_->SetValue(i);
}
signals:
void FamilyChanged(const QString &s);
void SizeChanged(double d);
void StyleChanged(const QString &s);
void UnderlineChanged(bool e);
void StrikethroughChanged(bool e);
void AlignmentChanged(Qt::Alignment alignment);
void VerticalAlignmentChanged(Qt::Alignment alignment);
void ColorChanged(const QColor &c);
void SmallCapsChanged(bool e);
void StretchChanged(int i);
void KerningChanged(qreal i);
void LineHeightChanged(qreal i);
void FamilyChanged(const QString &s);
void SizeChanged(double d);
void StyleChanged(const QString &s);
void UnderlineChanged(bool e);
void StrikethroughChanged(bool e);
void AlignmentChanged(Qt::Alignment alignment);
void VerticalAlignmentChanged(Qt::Alignment alignment);
void ColorChanged(const QColor &c);
void SmallCapsChanged(bool e);
void StretchChanged(int i);
void KerningChanged(qreal i);
void LineHeightChanged(qreal i);
void FirstPaint();
void FirstPaint();
protected:
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void closeEvent(QCloseEvent *event) override;
virtual void closeEvent(QCloseEvent *event) override;
virtual void paintEvent(QPaintEvent *event) override;
virtual void paintEvent(QPaintEvent *event) override;
private:
void AddSpacer(QLayout *l);
void AddSpacer(QLayout *l);
QPoint drag_anchor_;
QPoint drag_anchor_;
QFontComboBox *font_combo_;
QFontComboBox *font_combo_;
FloatSlider *font_sz_slider_;
FloatSlider *font_sz_slider_;
QComboBox *style_combo_;
QComboBox *style_combo_;
QPushButton *underline_btn_;
QPushButton *strikethrough_btn_;
QPushButton *underline_btn_;
QPushButton *strikethrough_btn_;
QPushButton *align_left_btn_;
QPushButton *align_center_btn_;
QPushButton *align_right_btn_;
QPushButton *align_justify_btn_;
QPushButton *align_left_btn_;
QPushButton *align_center_btn_;
QPushButton *align_right_btn_;
QPushButton *align_justify_btn_;
QPushButton *align_top_btn_;
QPushButton *align_middle_btn_;
QPushButton *align_bottom_btn_;
QPushButton *align_top_btn_;
QPushButton *align_middle_btn_;
QPushButton *align_bottom_btn_;
IntegerSlider *stretch_slider_;
FloatSlider *kerning_slider_;
FloatSlider *line_height_slider_;
QPushButton *small_caps_btn_;
IntegerSlider *stretch_slider_;
FloatSlider *kerning_slider_;
FloatSlider *line_height_slider_;
QPushButton *small_caps_btn_;
QPushButton *color_btn_;
QPushButton *color_btn_;
bool painted_;
bool painted_;
bool drag_enabled_;
bool drag_enabled_;
private slots:
void UpdateFontStyleList(const QString &family);
void UpdateFontStyleListAndEmitFamilyChanged(const QString &family);
void UpdateFontStyleList(const QString &family);
void UpdateFontStyleListAndEmitFamilyChanged(const QString &family);
};
class ViewerTextEditor : public QTextEdit
{
Q_OBJECT
class ViewerTextEditor : public QTextEdit {
Q_OBJECT
public:
ViewerTextEditor(double scale, QWidget *parent = nullptr);
ViewerTextEditor(double scale, QWidget *parent = nullptr);
void ConnectToolBar(ViewerTextEditorToolBar *toolbar);
void ConnectToolBar(ViewerTextEditorToolBar *toolbar);
void Paint(QPainter *p, Qt::Alignment valign);
void Paint(QPainter *p, Qt::Alignment valign);
virtual void dragEnterEvent(QDragEnterEvent *e) override { return QTextEdit::dragEnterEvent(e); }
virtual void dragMoveEvent(QDragMoveEvent *e) override { return QTextEdit::dragMoveEvent(e); }
virtual void dragLeaveEvent(QDragLeaveEvent *e) override { return QTextEdit::dragLeaveEvent(e); }
virtual void dropEvent(QDropEvent *e) override { return QTextEdit::dropEvent(e); }
virtual void dragEnterEvent(QDragEnterEvent *e) override
{
return QTextEdit::dragEnterEvent(e);
}
virtual void dragMoveEvent(QDragMoveEvent *e) override
{
return QTextEdit::dragMoveEvent(e);
}
virtual void dragLeaveEvent(QDragLeaveEvent *e) override
{
return QTextEdit::dragLeaveEvent(e);
}
virtual void dropEvent(QDropEvent *e) override
{
return QTextEdit::dropEvent(e);
}
protected:
virtual void paintEvent(QPaintEvent *event) override;
virtual void paintEvent(QPaintEvent *event) override;
private:
static void UpdateToolBar(ViewerTextEditorToolBar *toolbar, const QTextCharFormat &f, const QTextBlockFormat &b, Qt::Alignment alignment);
static void UpdateToolBar(ViewerTextEditorToolBar *toolbar,
const QTextCharFormat &f,
const QTextBlockFormat &b,
Qt::Alignment alignment);
void MergeCharFormat(const QTextCharFormat &fmt);
void MergeCharFormat(const QTextCharFormat &fmt);
void ApplyStyle(QTextCharFormat *format, const QString &family, const QString &style);
void ApplyStyle(QTextCharFormat *format, const QString &family,
const QString &style);
QVector<ViewerTextEditorToolBar *> toolbars_;
QVector<ViewerTextEditorToolBar *> toolbars_;
QImage dpi_force_;
QImage dpi_force_;
QTextDocument *transparent_clone_;
QTextDocument *transparent_clone_;
bool block_update_toolbar_signal_;
bool block_update_toolbar_signal_;
bool forced_default_;
QTextCharFormat default_fmt_;
bool forced_default_;
QTextCharFormat default_fmt_;
private slots:
void FormatChanged(const QTextCharFormat &f);
void FormatChanged(const QTextCharFormat &f);
void SetFamily(const QString &s);
void SetFamily(const QString &s);
void SetStyle(const QString &s);
void SetStyle(const QString &s);
void SetFontStrikethrough(bool e);
void SetFontStrikethrough(bool e);
void SetSmallCaps(bool e);
void SetSmallCaps(bool e);
void SetFontStretch(int i);
void SetFontStretch(int i);
void SetFontKerning(qreal i);
void SetFontKerning(qreal i);
void SetLineHeight(qreal i);
void SetLineHeight(qreal i);
void LockScrollBarMaximumToZero();
void DocumentChanged();
void LockScrollBarMaximumToZero();
void DocumentChanged();
};
}
+41 -38
View File
@@ -23,82 +23,85 @@
#include <QKeyEvent>
#include <QVBoxLayout>
namespace olive {
ViewerWindow::ViewerWindow(QWidget *parent) :
QWidget(parent, Qt::Window | Qt::WindowStaysOnTopHint),
pixel_aspect_(1)
namespace olive
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
display_widget_ = new ViewerDisplayWidget();
layout->addWidget(display_widget_);
ViewerWindow::ViewerWindow(QWidget *parent)
: QWidget(parent, Qt::Window | Qt::WindowStaysOnTopHint)
, pixel_aspect_(1)
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
display_widget_ = new ViewerDisplayWidget();
layout->addWidget(display_widget_);
}
ViewerDisplayWidget *ViewerWindow::display_widget() const
{
return display_widget_;
return display_widget_;
}
void ViewerWindow::SetVideoParams(const VideoParams &params)
{
width_ = params.width();
height_ = params.height();
pixel_aspect_ = params.pixel_aspect_ratio();
width_ = params.width();
height_ = params.height();
pixel_aspect_ = params.pixel_aspect_ratio();
UpdateMatrix();
UpdateMatrix();
}
void ViewerWindow::SetResolution(int width, int height)
{
width_ = width;
height_ = height;
width_ = width;
height_ = height;
UpdateMatrix();
UpdateMatrix();
}
void ViewerWindow::SetPixelAspectRatio(const rational &pixel_aspect)
{
pixel_aspect_ = pixel_aspect;
pixel_aspect_ = pixel_aspect;
UpdateMatrix();
UpdateMatrix();
}
void ViewerWindow::keyPressEvent(QKeyEvent *e)
{
QWidget::keyPressEvent(e);
QWidget::keyPressEvent(e);
if (e->key() == Qt::Key_Escape) {
close();
}
if (e->key() == Qt::Key_Escape) {
close();
}
}
void ViewerWindow::closeEvent(QCloseEvent *e)
{
QWidget::closeEvent(e);
QWidget::closeEvent(e);
deleteLater();
deleteLater();
}
void ViewerWindow::UpdateMatrix()
{
// Set GL widget matrix to maintain this texture's aspect ratio
double window_ar = static_cast<double>(this->width()) / static_cast<double>(this->height());
double image_ar = static_cast<double>(width_) / static_cast<double>(height_) * pixel_aspect_.toDouble();
// Set GL widget matrix to maintain this texture's aspect ratio
double window_ar = static_cast<double>(this->width()) /
static_cast<double>(this->height());
double image_ar = static_cast<double>(width_) /
static_cast<double>(height_) * pixel_aspect_.toDouble();
QMatrix4x4 mat;
QMatrix4x4 mat;
if (window_ar > image_ar) {
// Window is wider than image, adjust X scale
mat.scale(image_ar / window_ar, 1.0f, 1.0f);
} else if (window_ar < image_ar) {
// Window is taller than image, adjust Y scale
mat.scale(1.0f, window_ar / image_ar, 1.0f);
}
if (window_ar > image_ar) {
// Window is wider than image, adjust X scale
mat.scale(image_ar / window_ar, 1.0f, 1.0f);
} else if (window_ar < image_ar) {
// Window is taller than image, adjust Y scale
mat.scale(1.0f, window_ar / image_ar, 1.0f);
}
display_widget_->SetMatrixZoom(mat);
display_widget_->SetMatrixZoom(mat);
}
}
+18 -19
View File
@@ -25,49 +25,48 @@
#include "viewerdisplay.h"
namespace olive {
class ViewerWindow : public QWidget
namespace olive
{
class ViewerWindow : public QWidget {
public:
ViewerWindow(QWidget* parent = nullptr);
ViewerWindow(QWidget *parent = nullptr);
ViewerDisplayWidget* display_widget() const;
ViewerDisplayWidget *display_widget() const;
/**
/**
* @brief Used to adjust resulting picture to be the right aspect ratio
*
* Equivalent to calling SetResolution and SetPixelAspectRatio, just slightly faster since we
* only calculate the matrix once rather than twice.
*/
void SetVideoParams(const VideoParams &params);
void SetVideoParams(const VideoParams &params);
/**
/**
* @brief Used to adjust resulting picture to be the right aspect ratio
*/
void SetResolution(int width, int height);
void SetResolution(int width, int height);
/**
/**
* @brief Used to adjust resulting picture to be the right aspect ratio
*/
void SetPixelAspectRatio(const rational& pixel_aspect);
void SetPixelAspectRatio(const rational &pixel_aspect);
protected:
virtual void keyPressEvent(QKeyEvent* e) override;
virtual void keyPressEvent(QKeyEvent *e) override;
virtual void closeEvent(QCloseEvent* e) override;
virtual void closeEvent(QCloseEvent *e) override;
private:
void UpdateMatrix();
void UpdateMatrix();
int width_;
int width_;
int height_;
int height_;
ViewerDisplayWidget* display_widget_;
rational pixel_aspect_;
ViewerDisplayWidget *display_widget_;
rational pixel_aspect_;
};
}