2015-02-12 23:16:25 +08:00
|
|
|
// Aseprite
|
2017-02-11 05:38:08 +08:00
|
|
|
// Copyright (C) 2001-2017 David Capello
|
2015-02-12 23:16:25 +08:00
|
|
|
//
|
2016-08-27 04:02:58 +08:00
|
|
|
// This program is distributed under the terms of
|
|
|
|
|
// the End-User License Agreement for Aseprite.
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2013-01-21 05:40:37 +08:00
|
|
|
#include "config.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#endif
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
#include "app/ui/preview_editor.h"
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2015-02-15 20:48:38 +08:00
|
|
|
#include "app/app.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/document.h"
|
|
|
|
|
#include "app/ini_file.h"
|
2015-03-10 00:57:16 +08:00
|
|
|
#include "app/loop_tag.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/modules/editors.h"
|
|
|
|
|
#include "app/modules/gui.h"
|
2015-02-15 20:48:38 +08:00
|
|
|
#include "app/pref/preferences.h"
|
2014-04-27 03:05:29 +08:00
|
|
|
#include "app/ui/editor/editor.h"
|
2017-03-30 08:18:29 +08:00
|
|
|
#include "app/ui/editor/editor_customization_delegate.h"
|
2014-04-27 03:05:29 +08:00
|
|
|
#include "app/ui/editor/editor_view.h"
|
2015-02-10 23:59:43 +08:00
|
|
|
#include "app/ui/editor/navigate_state.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui/skin/skin_theme.h"
|
2014-04-27 03:05:29 +08:00
|
|
|
#include "app/ui/status_bar.h"
|
|
|
|
|
#include "app/ui/toolbar.h"
|
2014-05-18 08:27:44 +08:00
|
|
|
#include "app/ui_context.h"
|
2014-04-27 03:05:29 +08:00
|
|
|
#include "base/bind.h"
|
2014-10-21 09:21:31 +08:00
|
|
|
#include "doc/sprite.h"
|
2015-02-10 23:59:43 +08:00
|
|
|
#include "gfx/rect.h"
|
2013-01-21 05:40:37 +08:00
|
|
|
#include "ui/base.h"
|
|
|
|
|
#include "ui/button.h"
|
|
|
|
|
#include "ui/close_event.h"
|
2013-01-21 08:58:16 +08:00
|
|
|
#include "ui/message.h"
|
2013-01-21 05:40:37 +08:00
|
|
|
#include "ui/system.h"
|
|
|
|
|
|
2015-03-10 00:57:16 +08:00
|
|
|
#include "doc/frame_tag.h"
|
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
namespace app {
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
using namespace app::skin;
|
|
|
|
|
using namespace ui;
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2017-03-30 08:59:04 +08:00
|
|
|
class MiniCenterButton : public CheckBox {
|
2015-02-10 23:59:43 +08:00
|
|
|
public:
|
2017-03-30 08:59:04 +08:00
|
|
|
MiniCenterButton() : CheckBox("") {
|
2015-02-10 23:59:43 +08:00
|
|
|
setDecorative(true);
|
|
|
|
|
setSelected(true);
|
2017-08-15 21:39:06 +08:00
|
|
|
initTheme();
|
2015-02-10 23:59:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
2017-08-15 21:39:06 +08:00
|
|
|
void onInitTheme(ui::InitThemeEvent& ev) override {
|
|
|
|
|
CheckBox::onInitTheme(ev);
|
|
|
|
|
setStyle(SkinTheme::instance()->styles.windowCenterButton());
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-05 06:38:52 +08:00
|
|
|
void onSetDecorativeWidgetBounds() override {
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
|
|
|
|
Widget* window = parent();
|
2015-02-10 23:59:43 +08:00
|
|
|
gfx::Rect rect(0, 0, 0, 0);
|
2017-03-30 08:59:04 +08:00
|
|
|
gfx::Size centerSize = this->sizeHint();
|
|
|
|
|
gfx::Size playSize = theme->calcSizeHint(this, theme->styles.windowPlayButton());
|
|
|
|
|
gfx::Size closeSize = theme->calcSizeHint(this, theme->styles.windowCloseButton());
|
|
|
|
|
|
|
|
|
|
rect.w = centerSize.w;
|
|
|
|
|
rect.h = centerSize.h;
|
|
|
|
|
rect.offset(window->bounds().x2()
|
|
|
|
|
- theme->styles.windowCloseButton()->margin().width() - closeSize.w
|
|
|
|
|
- theme->styles.windowPlayButton()->margin().width() - playSize.w
|
|
|
|
|
- style()->margin().right() - centerSize.w,
|
|
|
|
|
window->bounds().y + style()->margin().top());
|
2015-02-10 23:59:43 +08:00
|
|
|
|
|
|
|
|
setBounds(rect);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-30 08:59:04 +08:00
|
|
|
bool onProcessMessage(Message* msg) override {
|
2015-02-10 23:59:43 +08:00
|
|
|
switch (msg->type()) {
|
|
|
|
|
|
|
|
|
|
case kSetCursorMessage:
|
|
|
|
|
ui::set_mouse_cursor(kArrowCursor);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-30 08:59:04 +08:00
|
|
|
return CheckBox::onProcessMessage(msg);
|
2015-02-10 23:59:43 +08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2017-03-30 08:59:04 +08:00
|
|
|
class MiniPlayButton : public Button {
|
2013-01-21 08:58:16 +08:00
|
|
|
public:
|
2017-03-30 08:59:04 +08:00
|
|
|
MiniPlayButton() : Button(""), m_isPlaying(false) {
|
2016-08-14 00:35:35 +08:00
|
|
|
enableFlags(CTRL_RIGHT_CLICK);
|
2013-01-21 08:58:16 +08:00
|
|
|
setDecorative(true);
|
2017-08-15 21:39:06 +08:00
|
|
|
initTheme();
|
2013-01-21 08:58:16 +08:00
|
|
|
}
|
|
|
|
|
|
2015-04-07 03:12:28 +08:00
|
|
|
bool isPlaying() const { return m_isPlaying; }
|
2013-01-21 08:58:16 +08:00
|
|
|
|
2016-02-12 08:39:22 +08:00
|
|
|
void setPlaying(bool state) {
|
|
|
|
|
m_isPlaying = state;
|
2015-12-19 05:51:30 +08:00
|
|
|
setupIcons();
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-14 02:02:00 +08:00
|
|
|
obs::signal<void()> Popup;
|
2015-05-08 06:08:24 +08:00
|
|
|
|
2015-08-05 06:38:52 +08:00
|
|
|
private:
|
2017-08-15 21:39:06 +08:00
|
|
|
void onInitTheme(ui::InitThemeEvent& ev) override {
|
|
|
|
|
Button::onInitTheme(ev);
|
|
|
|
|
setupIcons();
|
|
|
|
|
}
|
2015-08-05 06:38:52 +08:00
|
|
|
|
|
|
|
|
void onClick(Event& ev) override {
|
2013-01-21 08:58:16 +08:00
|
|
|
m_isPlaying = !m_isPlaying;
|
2015-08-05 06:38:52 +08:00
|
|
|
setupIcons();
|
2013-03-12 09:27:13 +08:00
|
|
|
|
2017-03-30 08:59:04 +08:00
|
|
|
Button::onClick(ev);
|
2013-01-21 08:58:16 +08:00
|
|
|
}
|
|
|
|
|
|
2015-08-05 06:38:52 +08:00
|
|
|
void onSetDecorativeWidgetBounds() override {
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
|
|
|
|
Widget* window = parent();
|
2013-05-12 04:56:27 +08:00
|
|
|
gfx::Rect rect(0, 0, 0, 0);
|
2017-03-30 08:59:04 +08:00
|
|
|
gfx::Size playSize = this->sizeHint();
|
|
|
|
|
gfx::Size closeSize = theme->calcSizeHint(this, theme->styles.windowCloseButton());
|
|
|
|
|
gfx::Border margin(0, 0, 0, 0);
|
2013-01-21 08:58:16 +08:00
|
|
|
|
2013-05-12 04:56:27 +08:00
|
|
|
rect.w = playSize.w;
|
|
|
|
|
rect.h = playSize.h;
|
2017-03-30 08:59:04 +08:00
|
|
|
rect.offset(window->bounds().x2()
|
|
|
|
|
- theme->styles.windowCloseButton()->margin().width() - closeSize.w
|
|
|
|
|
- style()->margin().right() - playSize.w,
|
|
|
|
|
window->bounds().y + style()->margin().top());
|
2013-01-21 08:58:16 +08:00
|
|
|
|
2013-05-12 04:56:27 +08:00
|
|
|
setBounds(rect);
|
2013-01-21 08:58:16 +08:00
|
|
|
}
|
|
|
|
|
|
2015-08-05 06:38:52 +08:00
|
|
|
bool onProcessMessage(Message* msg) override {
|
2013-07-29 08:17:07 +08:00
|
|
|
switch (msg->type()) {
|
2013-01-21 08:58:16 +08:00
|
|
|
|
2013-04-05 08:53:29 +08:00
|
|
|
case kSetCursorMessage:
|
2014-11-26 08:30:56 +08:00
|
|
|
ui::set_mouse_cursor(kArrowCursor);
|
2013-01-21 08:58:16 +08:00
|
|
|
return true;
|
2015-05-08 06:08:24 +08:00
|
|
|
|
|
|
|
|
case kMouseUpMessage: {
|
|
|
|
|
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
|
|
|
|
if (mouseMsg->right()) {
|
|
|
|
|
if (hasCapture()) {
|
|
|
|
|
releaseMouse();
|
|
|
|
|
Popup();
|
|
|
|
|
|
|
|
|
|
setSelected(false);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-01-21 08:58:16 +08:00
|
|
|
}
|
|
|
|
|
|
2017-03-30 08:59:04 +08:00
|
|
|
return Button::onProcessMessage(msg);
|
2013-01-21 08:58:16 +08:00
|
|
|
}
|
|
|
|
|
|
2015-08-05 06:38:52 +08:00
|
|
|
void setupIcons() {
|
|
|
|
|
SkinTheme* theme = SkinTheme::instance();
|
|
|
|
|
if (m_isPlaying)
|
2017-03-30 08:59:04 +08:00
|
|
|
setStyle(theme->styles.windowStopButton());
|
2015-08-05 06:38:52 +08:00
|
|
|
else
|
2017-03-30 08:59:04 +08:00
|
|
|
setStyle(theme->styles.windowPlayButton());
|
2015-08-05 06:38:52 +08:00
|
|
|
}
|
|
|
|
|
|
2013-01-21 08:58:16 +08:00
|
|
|
bool m_isPlaying;
|
|
|
|
|
};
|
|
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
PreviewEditorWindow::PreviewEditorWindow()
|
2015-02-10 20:07:04 +08:00
|
|
|
: Window(WithTitleBar, "Preview")
|
2013-01-21 05:40:37 +08:00
|
|
|
, m_docView(NULL)
|
2015-02-10 23:59:43 +08:00
|
|
|
, m_centerButton(new MiniCenterButton())
|
2013-01-21 08:58:16 +08:00
|
|
|
, m_playButton(new MiniPlayButton())
|
2015-03-10 00:57:16 +08:00
|
|
|
, m_refFrame(0)
|
2015-05-08 06:08:24 +08:00
|
|
|
, m_aniSpeed(1.0)
|
2015-05-19 08:28:30 +08:00
|
|
|
, m_relatedEditor(nullptr)
|
2013-01-21 05:40:37 +08:00
|
|
|
{
|
|
|
|
|
setAutoRemap(false);
|
|
|
|
|
setWantFocus(false);
|
|
|
|
|
|
|
|
|
|
m_isEnabled = get_config_bool("MiniEditor", "Enabled", true);
|
2013-01-21 08:58:16 +08:00
|
|
|
|
2015-12-05 02:17:42 +08:00
|
|
|
m_centerButton->Click.connect(base::Bind<void>(&PreviewEditorWindow::onCenterClicked, this));
|
|
|
|
|
m_playButton->Click.connect(base::Bind<void>(&PreviewEditorWindow::onPlayClicked, this));
|
|
|
|
|
m_playButton->Popup.connect(base::Bind<void>(&PreviewEditorWindow::onPopupSpeed, this));
|
2015-02-10 23:59:43 +08:00
|
|
|
|
|
|
|
|
addChild(m_centerButton);
|
2013-01-21 08:58:16 +08:00
|
|
|
addChild(m_playButton);
|
2017-08-15 21:39:06 +08:00
|
|
|
|
|
|
|
|
initTheme();
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
|
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
PreviewEditorWindow::~PreviewEditorWindow()
|
2013-01-21 05:40:37 +08:00
|
|
|
{
|
|
|
|
|
set_config_bool("MiniEditor", "Enabled", m_isEnabled);
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
void PreviewEditorWindow::setPreviewEnabled(bool state)
|
2013-01-21 05:40:37 +08:00
|
|
|
{
|
|
|
|
|
m_isEnabled = state;
|
|
|
|
|
|
|
|
|
|
updateUsingEditor(current_editor);
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
bool PreviewEditorWindow::onProcessMessage(ui::Message* msg)
|
2014-04-27 03:05:29 +08:00
|
|
|
{
|
|
|
|
|
switch (msg->type()) {
|
|
|
|
|
|
|
|
|
|
case kOpenMessage:
|
|
|
|
|
{
|
2015-09-16 22:10:30 +08:00
|
|
|
SkinTheme* theme = SkinTheme::instance();
|
|
|
|
|
|
2014-04-27 03:05:29 +08:00
|
|
|
// Default bounds
|
2014-09-01 01:17:49 +08:00
|
|
|
int width = ui::display_w()/4;
|
|
|
|
|
int height = ui::display_h()/4;
|
2015-09-16 22:10:30 +08:00
|
|
|
int extra = 2*theme->dimensions.miniScrollbarSize();
|
2014-04-27 03:05:29 +08:00
|
|
|
setBounds(
|
|
|
|
|
gfx::Rect(
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
ui::display_w() - width - ToolBar::instance()->bounds().w - extra,
|
|
|
|
|
ui::display_h() - height - StatusBar::instance()->bounds().h - extra,
|
2014-04-27 03:05:29 +08:00
|
|
|
width, height));
|
|
|
|
|
|
|
|
|
|
load_window_pos(this, "MiniEditor");
|
2014-08-20 20:02:44 +08:00
|
|
|
invalidate();
|
2014-04-27 03:05:29 +08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kCloseMessage:
|
|
|
|
|
save_window_pos(this, "MiniEditor");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Window::onProcessMessage(msg);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-15 21:39:06 +08:00
|
|
|
void PreviewEditorWindow::onInitTheme(ui::InitThemeEvent& ev)
|
|
|
|
|
{
|
|
|
|
|
Window::onInitTheme(ev);
|
|
|
|
|
setChildSpacing(0);
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
void PreviewEditorWindow::onClose(ui::CloseEvent& ev)
|
2013-01-21 05:40:37 +08:00
|
|
|
{
|
2017-03-31 03:27:18 +08:00
|
|
|
ButtonBase* closeButton = dynamic_cast<ButtonBase*>(ev.getSource());
|
2017-02-18 01:18:47 +08:00
|
|
|
if (closeButton &&
|
|
|
|
|
closeButton->type() == kWindowCloseButtonWidget) {
|
2017-03-31 03:27:18 +08:00
|
|
|
// Here we don't use "setPreviewEnabled" to change the state of
|
2013-01-21 05:40:37 +08:00
|
|
|
// "m_isEnabled" because we're coming from a close event of the
|
|
|
|
|
// window.
|
|
|
|
|
m_isEnabled = false;
|
|
|
|
|
|
|
|
|
|
// Redraw the tool bar because it shows the mini editor enabled
|
|
|
|
|
// state. TODO abstract this event
|
|
|
|
|
ToolBar::instance()->invalidate();
|
|
|
|
|
|
2015-12-19 05:51:30 +08:00
|
|
|
destroyDocView();
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
void PreviewEditorWindow::onWindowResize()
|
2014-09-11 11:00:28 +08:00
|
|
|
{
|
|
|
|
|
Window::onWindowResize();
|
|
|
|
|
|
|
|
|
|
DocumentView* view = UIContext::instance()->activeView();
|
|
|
|
|
if (view)
|
2016-02-13 12:33:43 +08:00
|
|
|
updateUsingEditor(view->editor());
|
2014-09-11 11:00:28 +08:00
|
|
|
}
|
|
|
|
|
|
2016-02-12 08:09:31 +08:00
|
|
|
bool PreviewEditorWindow::hasDocument() const
|
|
|
|
|
{
|
2016-02-13 12:33:43 +08:00
|
|
|
return (m_docView && m_docView->document() != nullptr);
|
2016-02-12 08:09:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DocumentPreferences& PreviewEditorWindow::docPref()
|
|
|
|
|
{
|
2016-02-13 12:33:43 +08:00
|
|
|
Document* doc = (m_docView ? m_docView->document(): nullptr);
|
2016-02-12 08:09:31 +08:00
|
|
|
return Preferences::instance().document(doc);
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-10 23:59:43 +08:00
|
|
|
void PreviewEditorWindow::onCenterClicked()
|
|
|
|
|
{
|
2016-02-12 08:09:31 +08:00
|
|
|
if (!m_relatedEditor || !hasDocument())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bool autoScroll = m_centerButton->isSelected();
|
|
|
|
|
docPref().preview.autoScroll(autoScroll);
|
|
|
|
|
if (autoScroll)
|
|
|
|
|
updateUsingEditor(m_relatedEditor);
|
2015-02-10 23:59:43 +08:00
|
|
|
}
|
|
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
void PreviewEditorWindow::onPlayClicked()
|
2013-01-21 08:58:16 +08:00
|
|
|
{
|
2016-02-13 12:33:43 +08:00
|
|
|
Editor* miniEditor = (m_docView ? m_docView->editor(): nullptr);
|
2015-04-07 03:12:28 +08:00
|
|
|
if (!miniEditor || !miniEditor->document())
|
|
|
|
|
return;
|
2015-03-12 03:20:19 +08:00
|
|
|
|
2014-04-26 23:06:11 +08:00
|
|
|
if (m_playButton->isPlaying()) {
|
2015-04-07 03:12:28 +08:00
|
|
|
m_refFrame = miniEditor->frame();
|
2016-11-30 21:23:29 +08:00
|
|
|
miniEditor->play(Preferences::instance().preview.playOnce(),
|
|
|
|
|
Preferences::instance().preview.playAll());
|
2014-04-26 23:06:11 +08:00
|
|
|
}
|
2015-04-07 03:12:28 +08:00
|
|
|
else
|
|
|
|
|
miniEditor->stop();
|
2013-01-21 08:58:16 +08:00
|
|
|
}
|
|
|
|
|
|
2015-05-08 06:08:24 +08:00
|
|
|
void PreviewEditorWindow::onPopupSpeed()
|
|
|
|
|
{
|
2016-02-13 12:33:43 +08:00
|
|
|
Editor* miniEditor = (m_docView ? m_docView->editor(): nullptr);
|
2015-05-08 06:08:24 +08:00
|
|
|
if (!miniEditor || !miniEditor->document())
|
|
|
|
|
return;
|
|
|
|
|
|
2016-11-30 21:23:29 +08:00
|
|
|
auto& pref = Preferences::instance();
|
|
|
|
|
|
2015-12-19 05:51:30 +08:00
|
|
|
miniEditor->showAnimationSpeedMultiplierPopup(
|
2016-11-30 21:23:29 +08:00
|
|
|
pref.preview.playOnce,
|
|
|
|
|
pref.preview.playAll,
|
|
|
|
|
false);
|
2015-05-08 06:08:24 +08:00
|
|
|
m_aniSpeed = miniEditor->getAnimationSpeedMultiplier();
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-10 20:38:07 +08:00
|
|
|
void PreviewEditorWindow::updateUsingEditor(Editor* editor)
|
2013-01-21 05:40:37 +08:00
|
|
|
{
|
|
|
|
|
if (!m_isEnabled || !editor) {
|
|
|
|
|
hideWindow();
|
2015-05-19 08:28:30 +08:00
|
|
|
m_relatedEditor = nullptr;
|
2013-01-21 05:40:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-19 08:28:30 +08:00
|
|
|
if (!editor->isActive())
|
2015-04-07 03:12:28 +08:00
|
|
|
return;
|
|
|
|
|
|
2015-05-19 08:28:30 +08:00
|
|
|
m_relatedEditor = editor;
|
|
|
|
|
|
2014-07-30 12:28:15 +08:00
|
|
|
Document* document = editor->document();
|
2016-02-13 12:33:43 +08:00
|
|
|
Editor* miniEditor = (m_docView ? m_docView->editor(): nullptr);
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2014-04-14 01:29:54 +08:00
|
|
|
if (!isVisible())
|
|
|
|
|
openWindow();
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2016-02-12 08:09:31 +08:00
|
|
|
// Document preferences used to store the preferred zoom/scroll point
|
|
|
|
|
auto& docPref = Preferences::instance().document(document);
|
|
|
|
|
bool autoScroll = docPref.preview.autoScroll();
|
2014-04-14 01:29:54 +08:00
|
|
|
|
|
|
|
|
// Set the same location as in the given editor.
|
2014-07-30 12:28:15 +08:00
|
|
|
if (!miniEditor || miniEditor->document() != document) {
|
2015-12-19 05:51:30 +08:00
|
|
|
destroyDocView();
|
|
|
|
|
|
2016-02-12 08:09:31 +08:00
|
|
|
m_docView = new DocumentView(document, DocumentView::Preview, this);
|
2014-04-14 01:29:54 +08:00
|
|
|
addChild(m_docView);
|
|
|
|
|
|
2016-02-13 12:33:43 +08:00
|
|
|
miniEditor = m_docView->editor();
|
2016-02-12 08:09:31 +08:00
|
|
|
miniEditor->setZoom(render::Zoom::fromScale(docPref.preview.zoom()));
|
2015-04-07 03:12:28 +08:00
|
|
|
miniEditor->setLayer(editor->layer());
|
|
|
|
|
miniEditor->setFrame(editor->frame());
|
2015-02-10 23:59:43 +08:00
|
|
|
miniEditor->setState(EditorStatePtr(new NavigateState));
|
2015-05-08 06:08:24 +08:00
|
|
|
miniEditor->setAnimationSpeedMultiplier(m_aniSpeed);
|
2016-09-14 02:02:00 +08:00
|
|
|
miniEditor->add_observer(this);
|
2014-04-14 01:29:54 +08:00
|
|
|
layout();
|
2016-02-12 08:09:31 +08:00
|
|
|
|
|
|
|
|
if (!autoScroll)
|
|
|
|
|
miniEditor->setEditorScroll(docPref.preview.scroll());
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
2014-04-14 01:29:54 +08:00
|
|
|
|
2016-02-12 08:09:31 +08:00
|
|
|
m_centerButton->setSelected(autoScroll);
|
|
|
|
|
if (autoScroll) {
|
|
|
|
|
gfx::Point centerPoint = editor->getVisibleSpriteBounds().center();
|
2015-02-10 23:59:43 +08:00
|
|
|
miniEditor->centerInSpritePoint(centerPoint);
|
|
|
|
|
|
2016-02-12 08:09:31 +08:00
|
|
|
saveScrollPref();
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-07 03:12:28 +08:00
|
|
|
if (!m_playButton->isPlaying()) {
|
|
|
|
|
miniEditor->stop();
|
|
|
|
|
miniEditor->setLayer(editor->layer());
|
|
|
|
|
miniEditor->setFrame(editor->frame());
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (miniEditor->isPlaying()) {
|
2017-03-30 08:18:29 +08:00
|
|
|
doc::FrameTag* tag = editor
|
|
|
|
|
->getCustomizationDelegate()
|
|
|
|
|
->getFrameTagProvider()
|
|
|
|
|
->getFrameTagByFrame(editor->frame());
|
|
|
|
|
|
|
|
|
|
doc::FrameTag* playingTag = editor
|
|
|
|
|
->getCustomizationDelegate()
|
|
|
|
|
->getFrameTagProvider()
|
|
|
|
|
->getFrameTagByFrame(m_refFrame);
|
|
|
|
|
|
2017-01-31 21:49:59 +08:00
|
|
|
if (tag == playingTag)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
miniEditor->stop();
|
2015-04-07 03:12:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!miniEditor->isPlaying())
|
|
|
|
|
miniEditor->setFrame(m_refFrame = editor->frame());
|
|
|
|
|
|
2016-11-30 21:23:29 +08:00
|
|
|
miniEditor->play(Preferences::instance().preview.playOnce(),
|
|
|
|
|
Preferences::instance().preview.playAll());
|
2015-04-07 03:12:28 +08:00
|
|
|
}
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
|
|
|
|
|
2015-02-10 23:59:43 +08:00
|
|
|
void PreviewEditorWindow::uncheckCenterButton()
|
|
|
|
|
{
|
2016-02-12 08:09:31 +08:00
|
|
|
if (m_centerButton->isSelected()) {
|
2015-02-10 23:59:43 +08:00
|
|
|
m_centerButton->setSelected(false);
|
2016-02-12 08:09:31 +08:00
|
|
|
onCenterClicked();
|
|
|
|
|
}
|
2015-02-10 23:59:43 +08:00
|
|
|
}
|
|
|
|
|
|
2015-12-19 05:51:30 +08:00
|
|
|
void PreviewEditorWindow::onStateChanged(Editor* editor)
|
2013-01-21 05:40:37 +08:00
|
|
|
{
|
2016-02-12 08:39:22 +08:00
|
|
|
// Sync editor playing state with MiniPlayButton state
|
|
|
|
|
if (m_playButton->isPlaying() != editor->isPlaying())
|
|
|
|
|
m_playButton->setPlaying(editor->isPlaying());
|
2015-12-19 05:51:30 +08:00
|
|
|
}
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2016-02-12 08:09:31 +08:00
|
|
|
void PreviewEditorWindow::onScrollChanged(Editor* miniEditor)
|
|
|
|
|
{
|
|
|
|
|
if (miniEditor->hasCapture()) {
|
|
|
|
|
saveScrollPref();
|
|
|
|
|
uncheckCenterButton();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PreviewEditorWindow::onZoomChanged(Editor* miniEditor)
|
|
|
|
|
{
|
|
|
|
|
saveScrollPref();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PreviewEditorWindow::saveScrollPref()
|
|
|
|
|
{
|
|
|
|
|
ASSERT(m_docView);
|
|
|
|
|
if (!m_docView)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-02-13 12:33:43 +08:00
|
|
|
Editor* miniEditor = m_docView->editor();
|
2016-02-12 08:09:31 +08:00
|
|
|
ASSERT(miniEditor);
|
|
|
|
|
|
|
|
|
|
docPref().preview.scroll(View::getView(miniEditor)->viewScroll());
|
|
|
|
|
docPref().preview.zoom(miniEditor->zoom().scale());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PreviewEditorWindow::onScrollOtherEditor(Editor* editor)
|
|
|
|
|
{
|
|
|
|
|
updateUsingEditor(editor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PreviewEditorWindow::onDisposeOtherEditor(Editor* editor)
|
|
|
|
|
{
|
|
|
|
|
if (m_relatedEditor == editor)
|
|
|
|
|
updateUsingEditor(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PreviewEditorWindow::onPreviewOtherEditor(Editor* editor)
|
|
|
|
|
{
|
|
|
|
|
updateUsingEditor(editor);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-19 05:51:30 +08:00
|
|
|
void PreviewEditorWindow::hideWindow()
|
|
|
|
|
{
|
|
|
|
|
destroyDocView();
|
2013-01-21 05:40:37 +08:00
|
|
|
if (isVisible())
|
|
|
|
|
closeWindow(NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-19 05:51:30 +08:00
|
|
|
void PreviewEditorWindow::destroyDocView()
|
|
|
|
|
{
|
|
|
|
|
if (m_docView) {
|
2016-09-14 02:02:00 +08:00
|
|
|
m_docView->editor()->remove_observer(this);
|
2015-12-19 05:51:30 +08:00
|
|
|
|
|
|
|
|
delete m_docView;
|
|
|
|
|
m_docView = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
} // namespace app
|