New Feature : Adding Clapperboard (#2314)
* clapperboard * fixed image item and added aspect ratio prop * board -> clapperboard
This commit is contained in:
parent
fb35734678
commit
cd46940982
BIN
stuff/library/clapperboards/images/board1.png
Normal file
BIN
stuff/library/clapperboards/images/board1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
190
stuff/library/clapperboards/preset_sample.clapperboard
Normal file
190
stuff/library/clapperboards/preset_sample.clapperboard
Normal file
|
@ -0,0 +1,190 @@
|
|||
<clapperboardSettingsPreset>
|
||||
<duration>
|
||||
24
|
||||
</duration>
|
||||
<boardItems>
|
||||
<item>
|
||||
<type>
|
||||
ScenePath_Full
|
||||
</type>
|
||||
<name>
|
||||
"Scene file path"
|
||||
</name>
|
||||
<rect>
|
||||
0.15 0.566708 0.7 0.0433166
|
||||
</rect>
|
||||
<maximumFontSize>
|
||||
300
|
||||
</maximumFontSize>
|
||||
<color>
|
||||
0 0 0 255
|
||||
</color>
|
||||
<font>
|
||||
Verdana 0 0
|
||||
</font>
|
||||
</item>
|
||||
<item>
|
||||
<type>
|
||||
UserName
|
||||
</type>
|
||||
<name>
|
||||
"User name"
|
||||
</name>
|
||||
<rect>
|
||||
0.7 0.9 0.2 0.05
|
||||
</rect>
|
||||
<maximumFontSize>
|
||||
300
|
||||
</maximumFontSize>
|
||||
<color>
|
||||
0 128 0 255
|
||||
</color>
|
||||
<font>
|
||||
Verdana 0 1
|
||||
</font>
|
||||
</item>
|
||||
<item>
|
||||
<type>
|
||||
CurrentDate
|
||||
</type>
|
||||
<name>
|
||||
"Rendering date"
|
||||
</name>
|
||||
<rect>
|
||||
0.1 0.9 0.2 0.05
|
||||
</rect>
|
||||
<maximumFontSize>
|
||||
300
|
||||
</maximumFontSize>
|
||||
<color>
|
||||
0 0 0 255
|
||||
</color>
|
||||
<font>
|
||||
Verdana 0 0
|
||||
</font>
|
||||
</item>
|
||||
<item>
|
||||
<type>
|
||||
FreeText
|
||||
</type>
|
||||
<name>
|
||||
"Type some description here"
|
||||
</name>
|
||||
<rect>
|
||||
0.15 0.629176 0.55 0.248329
|
||||
</rect>
|
||||
<text>
|
||||
""
|
||||
</text>
|
||||
<maximumFontSize>
|
||||
40
|
||||
</maximumFontSize>
|
||||
<color>
|
||||
0 0 64 255
|
||||
</color>
|
||||
<font>
|
||||
Verdana 0 0
|
||||
</font>
|
||||
</item>
|
||||
<item>
|
||||
<type>
|
||||
Duration_SecFrame
|
||||
</type>
|
||||
<name>
|
||||
"Scene duration"
|
||||
</name>
|
||||
<rect>
|
||||
0.351376 0.424454 0.3 0.125546
|
||||
</rect>
|
||||
<maximumFontSize>
|
||||
300
|
||||
</maximumFontSize>
|
||||
<color>
|
||||
0 0 0 255
|
||||
</color>
|
||||
<font>
|
||||
Verdana 0 0
|
||||
</font>
|
||||
</item>
|
||||
<item>
|
||||
<type>
|
||||
SceneName
|
||||
</type>
|
||||
<name>
|
||||
Scene
|
||||
</name>
|
||||
<rect>
|
||||
0.35 0.25 0.3 0.2
|
||||
</rect>
|
||||
<maximumFontSize>
|
||||
300
|
||||
</maximumFontSize>
|
||||
<color>
|
||||
0 0 0 255
|
||||
</color>
|
||||
<font>
|
||||
Verdana 1 0
|
||||
</font>
|
||||
</item>
|
||||
<item>
|
||||
<type>
|
||||
FreeText
|
||||
</type>
|
||||
<name>
|
||||
"Episode #"
|
||||
</name>
|
||||
<rect>
|
||||
0.15 0.3 0.2 0.2
|
||||
</rect>
|
||||
<text>
|
||||
"#"
|
||||
</text>
|
||||
<maximumFontSize>
|
||||
120
|
||||
</maximumFontSize>
|
||||
<color>
|
||||
0 0 0 255
|
||||
</color>
|
||||
<font>
|
||||
Verdana 0 0
|
||||
</font>
|
||||
</item>
|
||||
<item>
|
||||
<type>
|
||||
ProjectName
|
||||
</type>
|
||||
<name>
|
||||
Title
|
||||
</name>
|
||||
<rect>
|
||||
0.15 0.1 0.7 0.15
|
||||
</rect>
|
||||
<maximumFontSize>
|
||||
300
|
||||
</maximumFontSize>
|
||||
<color>
|
||||
0 0 0 255
|
||||
</color>
|
||||
<font>
|
||||
Verdana 1 0
|
||||
</font>
|
||||
</item>
|
||||
<item>
|
||||
<type>
|
||||
Image
|
||||
</type>
|
||||
<name>
|
||||
Background
|
||||
</name>
|
||||
<rect>
|
||||
0 0 1 1
|
||||
</rect>
|
||||
<imgPath>
|
||||
1 "clapperboards\\images\\board1.png"
|
||||
</imgPath>
|
||||
<imgARMode>
|
||||
0
|
||||
</imgARMode>
|
||||
</item>
|
||||
</boardItems>
|
||||
</clapperboardSettingsPreset>
|
141
toonz/sources/include/toonz/boardsettings.h
Normal file
141
toonz/sources/include/toonz/boardsettings.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef BOARDSETTINGS_H
|
||||
#define BOARDSETTINGS_H
|
||||
|
||||
#include "traster.h"
|
||||
#include "tfilepath.h"
|
||||
|
||||
// TnzCore includes
|
||||
#include "tstream.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QRectF>
|
||||
#include <QColor>
|
||||
#include <QPainter>
|
||||
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
#ifdef TOONZLIB_EXPORTS
|
||||
#define DVAPI DV_EXPORT_API
|
||||
#define DVVAR DV_EXPORT_VAR
|
||||
#else
|
||||
#define DVAPI DV_IMPORT_API
|
||||
#define DVVAR DV_IMPORT_VAR
|
||||
#endif
|
||||
|
||||
class ToonzScene;
|
||||
|
||||
class DVAPI BoardItem {
|
||||
public:
|
||||
enum Type {
|
||||
FreeText = 0,
|
||||
ProjectName,
|
||||
SceneName,
|
||||
Duration_Frame,
|
||||
Duration_SecFrame,
|
||||
Duration_HHMMSSFF,
|
||||
CurrentDate,
|
||||
CurrentDateTime,
|
||||
UserName,
|
||||
ScenePath_Aliased,
|
||||
ScenePath_Full,
|
||||
MoviePath_Aliased,
|
||||
MoviePath_Full,
|
||||
Image,
|
||||
TypeCount
|
||||
};
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
Type m_type;
|
||||
|
||||
// item region, represented by ratio to the whole
|
||||
QRectF m_rect;
|
||||
|
||||
// Basically the font size will be automatically
|
||||
// adjusted to fit the item region.
|
||||
// The maximum font size can be used to make the font
|
||||
// size smaller.
|
||||
int m_maximumFontSize;
|
||||
|
||||
// font color
|
||||
QColor m_color;
|
||||
|
||||
// font (familiy, bold, italic)
|
||||
QFont m_font;
|
||||
|
||||
QString m_text;
|
||||
TFilePath m_imgPath;
|
||||
Qt::AspectRatioMode m_imgARMode = Qt::KeepAspectRatio;
|
||||
|
||||
QString getContentText(ToonzScene*);
|
||||
|
||||
public:
|
||||
BoardItem();
|
||||
|
||||
QRectF getRatioRect() { return m_rect; }
|
||||
void setRatioRect(QRectF rect) { m_rect = rect; }
|
||||
|
||||
// returns the item rect in pixels
|
||||
QRectF getItemRect(QSize imgSize);
|
||||
void drawItem(QPainter& p, QSize imgSize, int shrink, ToonzScene* scene);
|
||||
|
||||
QString getName() { return m_name; }
|
||||
void setName(QString name) { m_name = name; }
|
||||
|
||||
Type getType() { return m_type; }
|
||||
void setType(Type type) { m_type = type; }
|
||||
|
||||
int getMaximumFontSize() { return m_maximumFontSize; }
|
||||
void setMaximumFontSize(int size) { m_maximumFontSize = size; }
|
||||
|
||||
QColor getColor() { return m_color; }
|
||||
void setColor(QColor color) { m_color = color; }
|
||||
|
||||
QFont& font() { return m_font; }
|
||||
|
||||
QString getFreeText() { return m_text; }
|
||||
void setFreeText(QString text) { m_text = text; }
|
||||
|
||||
TFilePath getImgPath() { return m_imgPath; }
|
||||
void setImgPath(TFilePath path) { m_imgPath = path; }
|
||||
|
||||
Qt::AspectRatioMode getImgARMode() { return m_imgARMode; }
|
||||
void setImgARMode(Qt::AspectRatioMode mode) { m_imgARMode = mode; }
|
||||
|
||||
void saveData(TOStream& os);
|
||||
void loadData(TIStream& is);
|
||||
};
|
||||
|
||||
class DVAPI BoardSettings {
|
||||
bool m_active = false;
|
||||
int m_duration = 0;
|
||||
QList<BoardItem> m_items;
|
||||
|
||||
public:
|
||||
BoardSettings();
|
||||
|
||||
QImage getBoardImage(TDimension& dim, int shrink, ToonzScene* scene);
|
||||
|
||||
TRaster32P getBoardRaster(TDimension& dim, int shrink, ToonzScene* scene);
|
||||
|
||||
int getDuration() { return m_duration; }
|
||||
|
||||
bool isActive() { return m_active; }
|
||||
void setActive(bool on) { m_active = on; }
|
||||
|
||||
int getItemCount() { return m_items.count(); }
|
||||
BoardItem& getItem(int index) { return m_items[index]; }
|
||||
|
||||
void setDuration(int f) { m_duration = f; }
|
||||
|
||||
void addNewItem(int insertAt = 0);
|
||||
void removeItem(int index);
|
||||
void swapItems(int, int);
|
||||
|
||||
void saveData(TOStream& os, bool forPreset = false);
|
||||
void loadData(TIStream& is);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -96,7 +96,7 @@ class DVAPI ChannelField final : public QWidget {
|
|||
public:
|
||||
ChannelField(QWidget *parent = 0, const QString &string = "", int value = 0,
|
||||
int maxValue = 255, bool horizontal = false, int labelWidth = 13,
|
||||
int sliderWidth = 40);
|
||||
int sliderWidth = -1);
|
||||
|
||||
~ChannelField() {}
|
||||
|
||||
|
@ -145,7 +145,7 @@ public:
|
|||
|
||||
ColorField(QWidget *parent = 0, bool isAlphaActive = true,
|
||||
TPixel32 color = TPixel32(0, 0, 0, 255), int squareSize = 40,
|
||||
bool useStyleEditor = true);
|
||||
bool useStyleEditor = true, int sliderWidth = -1);
|
||||
|
||||
~ColorField() {}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
class TPropertyGroup;
|
||||
class TWidget;
|
||||
class TRenderSettings;
|
||||
class BoardSettings;
|
||||
|
||||
//=============================================================================
|
||||
//! The TOutputProperties class provides a container for output properties and
|
||||
|
@ -91,6 +92,8 @@ private:
|
|||
|
||||
bool m_subcameraPreview;
|
||||
|
||||
BoardSettings *m_boardSettings;
|
||||
|
||||
public:
|
||||
/*!
|
||||
Constructs TOutputProperties with default value.
|
||||
|
@ -216,6 +219,8 @@ machine's CPU).
|
|||
|
||||
bool isSubcameraPreview() const { return m_subcameraPreview; }
|
||||
void setSubcameraPreview(bool enabled) { m_subcameraPreview = enabled; }
|
||||
|
||||
BoardSettings *getBoardSettings() const { return m_boardSettings; }
|
||||
};
|
||||
|
||||
//--------------------------------------------
|
||||
|
|
|
@ -158,6 +158,7 @@ set(MOC_HEADERS
|
|||
reframepopup.h
|
||||
autoinputcellnumberpopup.h
|
||||
colormodelbehaviorpopup.h
|
||||
boardsettingspopup.h
|
||||
# Tracker file
|
||||
dummyprocessor.h
|
||||
metnum.h
|
||||
|
@ -331,6 +332,7 @@ set(SOURCES
|
|||
reframepopup.cpp
|
||||
autoinputcellnumberpopup.cpp
|
||||
colormodelbehaviorpopup.cpp
|
||||
boardsettingspopup.cpp
|
||||
# Tracker file
|
||||
dummyprocessor.cpp
|
||||
metnum.cpp
|
||||
|
|
49
toonz/sources/toonz/Resources/down.svg
Normal file
49
toonz/sources/toonz/Resources/down.svg
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 18 18"
|
||||
version="1.1"
|
||||
xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="down.svg"><metadata
|
||||
id="metadata12"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs10" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1375"
|
||||
inkscape:window-height="637"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="13.111111"
|
||||
inkscape:cx="-6.4830508"
|
||||
inkscape:cy="9"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" /><path
|
||||
d="M 11,9 11,2 7,2 7,9 3,9 9,16 15,9 11,9 Z"
|
||||
style="fill:#e0e0e0"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="M 6,8 6,1 12,1 12,8 17,8 8.929,17 1,8 6,8 Z M 9,15.568 14.545,9 11,9 11,2 7,2 7,9 3.41,9 9,15.568 Z"
|
||||
style="fill:#111111"
|
||||
id="path6"
|
||||
inkscape:connector-curvature="0" /></svg>
|
After Width: | Height: | Size: 1.8 KiB |
49
toonz/sources/toonz/Resources/up.svg
Normal file
49
toonz/sources/toonz/Resources/up.svg
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 18 18"
|
||||
version="1.1"
|
||||
xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="up.svg"><metadata
|
||||
id="metadata12"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs10" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1375"
|
||||
inkscape:window-height="637"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="13.111111"
|
||||
inkscape:cx="-6.4830508"
|
||||
inkscape:cy="9"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" /><path
|
||||
d="m 7,9 0,7 4,0 0,-7 4,0 L 9,2 3,9 7,9 Z"
|
||||
style="fill:#e0e0e0"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="M 12,10 12,17 6,17 6,10 1,10 9.071,1 17,10 12,10 Z M 9,2.432 3.455,9 7,9 7,16 11,16 11,9 14.59,9 9,2.432 Z"
|
||||
style="fill:#111111"
|
||||
id="path6"
|
||||
inkscape:connector-curvature="0" /></svg>
|
After Width: | Height: | Size: 1.8 KiB |
1089
toonz/sources/toonz/boardsettingspopup.cpp
Normal file
1089
toonz/sources/toonz/boardsettingspopup.cpp
Normal file
File diff suppressed because it is too large
Load diff
175
toonz/sources/toonz/boardsettingspopup.h
Normal file
175
toonz/sources/toonz/boardsettingspopup.h
Normal file
|
@ -0,0 +1,175 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef BOARDSETTINGSPOPUP_H
|
||||
#define BOARDSETTINGSPOPUP_H
|
||||
|
||||
#include "toonzqt/dvdialog.h"
|
||||
#include "tpixel.h"
|
||||
#include "filebrowserpopup.h"
|
||||
#include <QWidget>
|
||||
#include <QStackedWidget>
|
||||
|
||||
class TOutputProperties;
|
||||
class QLineEdit;
|
||||
class QTextEdit;
|
||||
class QComboBox;
|
||||
class QFontComboBox;
|
||||
class QListWidget;
|
||||
class BoardItem;
|
||||
|
||||
namespace DVGui {
|
||||
class FileField;
|
||||
class ColorField;
|
||||
class IntLineEdit;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class BoardView : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
enum DragItem {
|
||||
None = 0,
|
||||
Translate,
|
||||
TopLeftCorner,
|
||||
TopRightCorner,
|
||||
BottomRightCorner,
|
||||
BottomLeftCorner,
|
||||
TopEdge,
|
||||
RightEdge,
|
||||
BottomEdge,
|
||||
LeftEdge
|
||||
} m_dragItem = None;
|
||||
|
||||
QImage m_boardImg;
|
||||
bool m_valid = false;
|
||||
|
||||
QRectF m_boardImgRect;
|
||||
|
||||
QRectF m_dragStartItemRect;
|
||||
QPointF m_dragStartPos;
|
||||
|
||||
public:
|
||||
BoardView(QWidget* parent = nullptr);
|
||||
void invalidate() { m_valid = false; }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class ItemInfoView : public QStackedWidget {
|
||||
Q_OBJECT
|
||||
|
||||
QLineEdit* m_nameEdit;
|
||||
DVGui::IntLineEdit* m_maxFontSizeEdit;
|
||||
QComboBox* m_typeCombo;
|
||||
QTextEdit* m_textEdit;
|
||||
DVGui::FileField* m_imgPathField;
|
||||
QFontComboBox* m_fontCombo;
|
||||
QPushButton *m_boldButton, *m_italicButton;
|
||||
DVGui::ColorField* m_fontColorField;
|
||||
QComboBox* m_imgARModeCombo;
|
||||
|
||||
QWidget *m_fontPropBox, *m_imgPropBox;
|
||||
|
||||
public:
|
||||
ItemInfoView(QWidget* parent = nullptr);
|
||||
void setCurrentItem(int index);
|
||||
|
||||
protected slots:
|
||||
void onNameEdited();
|
||||
void onMaxFontSizeEdited();
|
||||
void onTypeComboActivated(int);
|
||||
void onFreeTextChanged();
|
||||
void onImgPathChanged();
|
||||
void onFontComboChanged(const QFont&);
|
||||
void onBoldButtonClicked(bool);
|
||||
void onItalicButtonClicked(bool);
|
||||
void onFontColorChanged(const TPixel32&, bool);
|
||||
void onImgARModeComboActivated();
|
||||
|
||||
signals:
|
||||
// if updateListView is true then update the list view as well
|
||||
void itemPropertyChanged(bool updateListView);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class ItemListView : public QWidget {
|
||||
Q_OBJECT
|
||||
QListWidget* m_list;
|
||||
QPushButton *m_deleteItemBtn, *m_moveUpBtn, *m_moveDownBtn;
|
||||
|
||||
public:
|
||||
ItemListView(QWidget* parent = nullptr);
|
||||
void initialize();
|
||||
void updateCurrentItem();
|
||||
protected slots:
|
||||
void onCurrentItemSwitched(int);
|
||||
void onNewItemButtonClicked();
|
||||
void onDeleteItemButtonClicked();
|
||||
void onMoveUpButtonClicked();
|
||||
void onMoveDownButtonClicked();
|
||||
signals:
|
||||
void currentItemSwitched(int);
|
||||
void itemAddedOrDeleted();
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class BoardSettingsPopup : public DVGui::Dialog {
|
||||
Q_OBJECT
|
||||
|
||||
BoardView* m_boardView;
|
||||
ItemInfoView* m_itemInfoView;
|
||||
ItemListView* m_itemListView;
|
||||
|
||||
DVGui::IntLineEdit* m_durationEdit;
|
||||
|
||||
void initialize();
|
||||
void initializeItemTypeString(); // call once on the first launch
|
||||
public:
|
||||
static BoardItem* currentBoardItem;
|
||||
|
||||
BoardSettingsPopup(QWidget* parent = nullptr);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent*) override { initialize(); }
|
||||
void hideEvent(QHideEvent*) override;
|
||||
protected slots:
|
||||
void onCurrentItemSwitched(int);
|
||||
void onItemAddedOrDeleted();
|
||||
void onItemPropertyChanged(bool updateListView);
|
||||
void onDurationEdited();
|
||||
void onLoadPreset();
|
||||
void onSavePreset();
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class SaveBoardPresetFilePopup final : public GenericSaveFilePopup {
|
||||
public:
|
||||
SaveBoardPresetFilePopup();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent*) override;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class LoadBoardPresetFilePopup final : public GenericLoadFilePopup {
|
||||
public:
|
||||
LoadBoardPresetFilePopup();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent*) override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -156,7 +156,7 @@ public:
|
|||
|
||||
//! The GenericLoadFilePopup is a simple, standard Toonz popup that
|
||||
//! asks the user for \a single file to be loaded from disk.
|
||||
class GenericLoadFilePopup final : public FileBrowserPopup {
|
||||
class GenericLoadFilePopup : public FileBrowserPopup {
|
||||
public:
|
||||
GenericLoadFilePopup(const QString &title);
|
||||
|
||||
|
@ -175,7 +175,7 @@ protected:
|
|||
|
||||
//! The GenericSaveFilePopup is a simple, standard Toonz popup that
|
||||
//! asks the user for a \a single file path to save something to.
|
||||
class GenericSaveFilePopup final : public FileBrowserPopup {
|
||||
class GenericSaveFilePopup : public FileBrowserPopup {
|
||||
public:
|
||||
GenericSaveFilePopup(const QString &title);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "tapp.h"
|
||||
#include "camerasettingspopup.h"
|
||||
#include "pane.h"
|
||||
#include "boardsettingspopup.h"
|
||||
|
||||
// TnzQt includes
|
||||
#include "toonzqt/menubarcommand.h"
|
||||
|
@ -25,6 +26,7 @@
|
|||
#include "toonz/preferences.h"
|
||||
#include "toutputproperties.h"
|
||||
#include "toonz/tcamera.h"
|
||||
#include "toonz/boardsettings.h"
|
||||
|
||||
// TnzBase includes
|
||||
#include "trasterfx.h"
|
||||
|
@ -166,6 +168,11 @@ OutputSettingsPopup::OutputSettingsPopup(bool isPreview)
|
|||
otherSettingsLabel = new QLabel(tr("Other Settings"), this);
|
||||
otherSettingsFrame = new QFrame(this);
|
||||
m_renderButton = new QPushButton(tr("Render"), this);
|
||||
|
||||
// Board
|
||||
m_addBoard = new DVGui::CheckBox(tr("Add Clapperboard"), this);
|
||||
m_boardSettingsBtn = new QPushButton(tr("Edit Clapperboard..."), this);
|
||||
|
||||
// Gamma
|
||||
m_gammaFld = new DVGui::DoubleLineEdit();
|
||||
// Dominant Field
|
||||
|
@ -457,39 +464,43 @@ OutputSettingsPopup::OutputSettingsPopup(bool isPreview)
|
|||
otherSettingsLay->setHorizontalSpacing(5);
|
||||
otherSettingsLay->setVerticalSpacing(10);
|
||||
{
|
||||
// clapperboard
|
||||
otherSettingsLay->addWidget(m_addBoard, 0, 0);
|
||||
otherSettingsLay->addWidget(m_boardSettingsBtn, 0, 2, 1, 2);
|
||||
|
||||
// Gamma
|
||||
otherSettingsLay->addWidget(new QLabel(tr("Gamma:"), this), 0, 0,
|
||||
otherSettingsLay->addWidget(new QLabel(tr("Gamma:"), this), 1, 0,
|
||||
Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_gammaFld, 0, 1, 1, 3);
|
||||
otherSettingsLay->addWidget(m_gammaFld, 1, 1, 1, 3);
|
||||
// Dominant Field
|
||||
otherSettingsLay->addWidget(new QLabel(tr("Dominant Field:"), this),
|
||||
1, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_dominantFieldOm, 1, 1, 1, 4);
|
||||
2, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_dominantFieldOm, 2, 1, 1, 4);
|
||||
// Scene Settings' FPS
|
||||
otherSettingsLay->addWidget(
|
||||
new QLabel(tr("Frame Rate (linked to Scene Settings):"), this), 2,
|
||||
new QLabel(tr("Frame Rate (linked to Scene Settings):"), this), 3,
|
||||
0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_frameRateFld, 2, 1, 1, 3);
|
||||
otherSettingsLay->addWidget(m_frameRateFld, 3, 1, 1, 3);
|
||||
// Strech
|
||||
otherSettingsLay->addWidget(new QLabel(tr("Stretch from FPS:"), this),
|
||||
3, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_stretchFromFld, 3, 1);
|
||||
otherSettingsLay->addWidget(new QLabel(tr(" To:"), this), 3, 2,
|
||||
4, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_stretchFromFld, 4, 1);
|
||||
otherSettingsLay->addWidget(new QLabel(tr(" To:"), this), 4, 2,
|
||||
Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_stretchToFld, 3, 3);
|
||||
otherSettingsLay->addWidget(m_stretchToFld, 4, 3);
|
||||
// new in V6.1
|
||||
// Multimedia rendering enum
|
||||
otherSettingsLay->addWidget(
|
||||
new QLabel(tr("Multiple Rendering:"), this), 4, 0,
|
||||
new QLabel(tr("Multiple Rendering:"), this), 5, 0,
|
||||
Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_multimediaOm, 4, 1, 1, 4);
|
||||
otherSettingsLay->addWidget(m_multimediaOm, 5, 1, 1, 4);
|
||||
|
||||
otherSettingsLay->addWidget(m_doStereoscopy, 5, 0);
|
||||
otherSettingsLay->addWidget(new QLabel(tr("Camera Shift:")), 5, 1,
|
||||
otherSettingsLay->addWidget(m_doStereoscopy, 6, 0);
|
||||
otherSettingsLay->addWidget(new QLabel(tr("Camera Shift:")), 6, 1,
|
||||
Qt::AlignRight | Qt::AlignVCenter);
|
||||
otherSettingsLay->addWidget(m_stereoShift, 5, 2);
|
||||
otherSettingsLay->addWidget(m_stereoShift, 6, 2);
|
||||
|
||||
otherSettingsLay->addLayout(bottomGridLay, 6, 0, 4, 5);
|
||||
otherSettingsLay->addLayout(bottomGridLay, 7, 0, 4, 5);
|
||||
}
|
||||
otherSettingsLay->setColumnStretch(0, 0);
|
||||
otherSettingsLay->setColumnStretch(1, 0);
|
||||
|
@ -548,6 +559,12 @@ OutputSettingsPopup::OutputSettingsPopup(bool isPreview)
|
|||
SLOT(onChannelWidthChanged(int)));
|
||||
|
||||
if (!isPreview) {
|
||||
// clapperboard
|
||||
ret = ret && connect(m_addBoard, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(onAddBoardChecked(int)));
|
||||
ret = ret && connect(m_boardSettingsBtn, SIGNAL(clicked()), this,
|
||||
SLOT(onBoardSettingsBtnClicked()));
|
||||
|
||||
ret = ret && connect(m_gammaFld, SIGNAL(editingFinished()),
|
||||
SLOT(onGammaFldEditFinished()));
|
||||
ret = ret && connect(m_dominantFieldOm, SIGNAL(currentIndexChanged(int)),
|
||||
|
@ -862,6 +879,18 @@ void OutputSettingsPopup::updateField() {
|
|||
m_stretchToFld->setValue(renderSettings.m_timeStretchTo);
|
||||
|
||||
m_frameRateFld->setValue(prop->getFrameRate());
|
||||
|
||||
// clapperboard
|
||||
BoardSettings *boardSettings = prop->getBoardSettings();
|
||||
m_addBoard->setChecked(boardSettings->isActive());
|
||||
// clapperboard is only available with movie formats
|
||||
if (isMovieType(m_fileFormat->currentText().toStdString())) {
|
||||
m_addBoard->setEnabled(true);
|
||||
m_boardSettingsBtn->setEnabled(m_addBoard->isChecked());
|
||||
} else {
|
||||
m_addBoard->setEnabled(false);
|
||||
m_boardSettingsBtn->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -960,6 +989,15 @@ void OutputSettingsPopup::onFormatChanged(const QString &str) {
|
|||
m_threadsComboOm->setDisabled(false);
|
||||
m_threadsComboOm->setCurrentIndex(2);
|
||||
}
|
||||
|
||||
// clapperboard is only available with movie formats
|
||||
if (isMovieType(str.toStdString())) {
|
||||
m_addBoard->setEnabled(true);
|
||||
m_boardSettingsBtn->setEnabled(m_addBoard->isChecked());
|
||||
} else {
|
||||
m_addBoard->setEnabled(false);
|
||||
m_boardSettingsBtn->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1574,6 +1612,21 @@ void OutputSettingsPopup::onFrameRateEditingFinished() {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void OutputSettingsPopup::onAddBoardChecked(int state) {
|
||||
BoardSettings *boardSettings = getProperties()->getBoardSettings();
|
||||
boardSettings->setActive(state == Qt::Checked);
|
||||
|
||||
m_boardSettingsBtn->setEnabled(state == Qt::Checked);
|
||||
}
|
||||
|
||||
void OutputSettingsPopup::onBoardSettingsBtnClicked() {
|
||||
std::cout << "board settings button clicked" << std::endl;
|
||||
BoardSettingsPopup popup(this);
|
||||
popup.exec();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
OpenPopupCommandHandler<OutputSettingsPopup> openOutputSettingsPopup(
|
||||
MI_OutputSettings);
|
||||
OpenPopupCommandHandler<PreviewSettingsPopup> openPreviewSettingsPopup(
|
||||
|
|
|
@ -53,6 +53,10 @@ class OutputSettingsPopup : public DVGui::Dialog {
|
|||
CameraSettingsPopup *m_cameraSettings;
|
||||
QComboBox *m_presetCombo;
|
||||
|
||||
// clapperboard
|
||||
DVGui::CheckBox *m_addBoard;
|
||||
QPushButton *m_boardSettingsBtn;
|
||||
|
||||
bool m_isPreviewSettings;
|
||||
|
||||
void updatePresetComboItems();
|
||||
|
@ -97,6 +101,9 @@ protected slots:
|
|||
void onCameraSettingsChanged();
|
||||
/*-- Scene Settings のFPSを編集できるようにする --*/
|
||||
void onFrameRateEditingFinished();
|
||||
// clapperboard
|
||||
void onAddBoardChecked(int state);
|
||||
void onBoardSettingsBtnClicked();
|
||||
};
|
||||
|
||||
class PreviewSettingsPopup final : public OutputSettingsPopup {
|
||||
|
|
|
@ -468,5 +468,7 @@
|
|||
<file>Resources/shift_and_trace.svg</file>
|
||||
<file>Resources/shift_and_trace_edit.svg</file>
|
||||
<file>Resources/shift_and_trace_reset.svg</file>
|
||||
<file>Resources/up.svg</file>
|
||||
<file>Resources/down.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -156,6 +156,7 @@ set(MOC_HEADERS
|
|||
texturemanager.h
|
||||
imagebuilders.h
|
||||
../include/orientation.h
|
||||
../include/toonz/boardsettings.h
|
||||
)
|
||||
|
||||
set(HEADERS ${MOC_HEADERS})
|
||||
|
@ -317,6 +318,7 @@ set(SOURCES
|
|||
plasticdeformerfx.cpp
|
||||
txshmeshcolumn.cpp
|
||||
textureutils.cpp
|
||||
boardsettings.cpp
|
||||
)
|
||||
|
||||
if(BUILD_TARGET_WIN)
|
||||
|
|
364
toonz/sources/toonzlib/boardsettings.cpp
Normal file
364
toonz/sources/toonzlib/boardsettings.cpp
Normal file
|
@ -0,0 +1,364 @@
|
|||
#include "toonz/boardsettings.h"
|
||||
|
||||
// TnzLib includes
|
||||
#include "toonz/toonzscene.h"
|
||||
#include "toonz/tproject.h"
|
||||
#include "toonz/sceneproperties.h"
|
||||
#include "toonz/toonzfolders.h"
|
||||
#include "toutputproperties.h"
|
||||
#include "tsystem.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QDate>
|
||||
#include <QDateTime>
|
||||
#include <QFontMetricsF>
|
||||
#include <QMap>
|
||||
|
||||
namespace {
|
||||
QMap<BoardItem::Type, std::wstring> strs = {
|
||||
{BoardItem::FreeText, L"FreeText"},
|
||||
{BoardItem::ProjectName, L"ProjectName"},
|
||||
{BoardItem::SceneName, L"SceneName"},
|
||||
{BoardItem::Duration_Frame, L"Duration_Frame"},
|
||||
{BoardItem::Duration_SecFrame, L"Duration_SecFrame"},
|
||||
{BoardItem::Duration_HHMMSSFF, L"Duration_HHMMSSFF"},
|
||||
{BoardItem::CurrentDate, L"CurrentDate"},
|
||||
{BoardItem::CurrentDateTime, L"CurrentDateTime"},
|
||||
{BoardItem::UserName, L"UserName"},
|
||||
{BoardItem::ScenePath_Aliased, L"ScenePath_Aliased"},
|
||||
{BoardItem::ScenePath_Full, L"ScenePath_Full"},
|
||||
{BoardItem::MoviePath_Aliased, L"MoviePath_Aliased"},
|
||||
{BoardItem::MoviePath_Full, L"MoviePath_Full"},
|
||||
{BoardItem::Image, L"Image"}};
|
||||
|
||||
std::wstring type2String(BoardItem::Type type) { return strs.value(type, L""); }
|
||||
BoardItem::Type string2Type(std::wstring str) {
|
||||
return strs.key(str, BoardItem::TypeCount);
|
||||
}
|
||||
};
|
||||
|
||||
BoardItem::BoardItem() {
|
||||
m_name = "Item";
|
||||
m_type = ProjectName;
|
||||
m_rect = QRectF(0.1, 0.1, 0.8, 0.8);
|
||||
m_maximumFontSize = 300;
|
||||
m_color = Qt::black;
|
||||
}
|
||||
|
||||
QString BoardItem::getContentText(ToonzScene *scene) {
|
||||
switch (m_type) {
|
||||
case FreeText:
|
||||
return m_text;
|
||||
break;
|
||||
case ProjectName:
|
||||
return scene->getProject()->getName().getQString();
|
||||
break;
|
||||
case SceneName:
|
||||
return QString::fromStdWString(scene->getSceneName());
|
||||
break;
|
||||
case Duration_Frame:
|
||||
return QString::number(scene->getFrameCount());
|
||||
break;
|
||||
case Duration_SecFrame: {
|
||||
TOutputProperties *oprop = scene->getProperties()->getOutputProperties();
|
||||
int fps = (int)oprop->getFrameRate();
|
||||
int frame = scene->getFrameCount();
|
||||
return QString("%1 + %2").arg(QString::number(frame / fps),
|
||||
QString::number(frame % fps));
|
||||
} break;
|
||||
case Duration_HHMMSSFF: {
|
||||
TOutputProperties *oprop = scene->getProperties()->getOutputProperties();
|
||||
int fps = (int)oprop->getFrameRate();
|
||||
int frame = scene->getFrameCount();
|
||||
int hh = frame / (fps * 60 * 60);
|
||||
frame -= hh * fps * 60 * 60;
|
||||
int mm = frame / (fps * 60);
|
||||
frame -= mm * fps * 60;
|
||||
int ss = frame / fps;
|
||||
int ff = frame % fps;
|
||||
return QString::number(hh).rightJustified(2, '0') + ":" +
|
||||
QString::number(mm).rightJustified(2, '0') + ":" +
|
||||
QString::number(ss).rightJustified(2, '0') + ":" +
|
||||
QString::number(ff).rightJustified(2, '0');
|
||||
} break;
|
||||
case CurrentDate:
|
||||
return QDate::currentDate().toString(Qt::DefaultLocaleLongDate);
|
||||
break;
|
||||
case CurrentDateTime:
|
||||
return QDateTime::currentDateTime().toString(Qt::DefaultLocaleLongDate);
|
||||
break;
|
||||
case UserName:
|
||||
return TSystem::getUserName();
|
||||
break;
|
||||
case ScenePath_Aliased:
|
||||
return scene->codeFilePath(scene->getScenePath()).getQString();
|
||||
break;
|
||||
case ScenePath_Full:
|
||||
return scene->decodeFilePath(scene->getScenePath()).getQString();
|
||||
break;
|
||||
case MoviePath_Aliased: {
|
||||
TOutputProperties *oprop = scene->getProperties()->getOutputProperties();
|
||||
return scene->codeFilePath(oprop->getPath()).getQString();
|
||||
} break;
|
||||
case MoviePath_Full: {
|
||||
TOutputProperties *oprop = scene->getProperties()->getOutputProperties();
|
||||
return scene->decodeFilePath(oprop->getPath()).getQString();
|
||||
} break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QRectF BoardItem::getItemRect(QSize imgSize) {
|
||||
QSizeF imgSizeF(imgSize);
|
||||
return QRectF(
|
||||
imgSizeF.width() * m_rect.left(), imgSizeF.height() * m_rect.top(),
|
||||
imgSizeF.width() * m_rect.width(), imgSizeF.height() * m_rect.height());
|
||||
}
|
||||
|
||||
void BoardItem::drawItem(QPainter &p, QSize imgSize, int shrink,
|
||||
ToonzScene *scene) {
|
||||
QRectF itemRect = getItemRect(imgSize);
|
||||
|
||||
if (m_type == Image) {
|
||||
if (m_imgPath.isEmpty()) return;
|
||||
TFilePath decodedPath = scene->decodeFilePath(m_imgPath);
|
||||
QImage img(decodedPath.getQString());
|
||||
if (m_imgARMode == Qt::KeepAspectRatio) {
|
||||
float ratio = std::min((float)itemRect.width() / (float)img.width(),
|
||||
(float)itemRect.height() / (float)img.height());
|
||||
QSizeF imgSize((float)img.width() * ratio, (float)img.height() * ratio);
|
||||
QPointF imgTopLeft =
|
||||
itemRect.topLeft() +
|
||||
QPointF((itemRect.width() - imgSize.width()) * 0.5f,
|
||||
(itemRect.height() - imgSize.height()) * 0.5f);
|
||||
|
||||
p.drawImage(QRectF(imgTopLeft, imgSize), img);
|
||||
} else if (m_imgARMode == Qt::IgnoreAspectRatio)
|
||||
p.drawImage(itemRect, img);
|
||||
return;
|
||||
}
|
||||
|
||||
QString contentText = getContentText(scene);
|
||||
|
||||
QFont tmpFont(m_font);
|
||||
tmpFont.setPixelSize(100);
|
||||
QFontMetricsF tmpFm(tmpFont);
|
||||
QRectF tmpBounding =
|
||||
tmpFm.boundingRect(itemRect, Qt::AlignLeft | Qt::AlignTop, contentText);
|
||||
|
||||
float ratio = std::min(itemRect.width() / tmpBounding.width(),
|
||||
itemRect.height() / tmpBounding.height());
|
||||
|
||||
// compute the font size which will just fit the item region
|
||||
int fontSize = (int)(100.0f * ratio);
|
||||
tmpFont.setPixelSize(fontSize);
|
||||
tmpFm = QFontMetricsF(tmpFont);
|
||||
tmpBounding =
|
||||
tmpFm.boundingRect(itemRect, Qt::AlignLeft | Qt::AlignTop, contentText);
|
||||
bool isInRect;
|
||||
if (itemRect.width() >= tmpBounding.width() &&
|
||||
itemRect.height() >= tmpBounding.height())
|
||||
isInRect = true;
|
||||
else
|
||||
isInRect = false;
|
||||
while (1) {
|
||||
fontSize += (isInRect) ? 1 : -1;
|
||||
if (fontSize <= 0) // cannot draw
|
||||
return;
|
||||
tmpFont.setPixelSize(fontSize);
|
||||
tmpFm = QFontMetricsF(tmpFont);
|
||||
tmpBounding =
|
||||
tmpFm.boundingRect(itemRect, Qt::AlignLeft | Qt::AlignTop, contentText);
|
||||
|
||||
bool newIsInRect = (itemRect.width() >= tmpBounding.width() &&
|
||||
itemRect.height() >= tmpBounding.height());
|
||||
if (isInRect != newIsInRect) {
|
||||
if (isInRect) fontSize--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----
|
||||
fontSize = std::min(fontSize, m_maximumFontSize / shrink);
|
||||
|
||||
QFont font(m_font);
|
||||
font.setPixelSize(fontSize);
|
||||
|
||||
p.setFont(font);
|
||||
p.setPen(m_color);
|
||||
|
||||
if (m_type == FreeText)
|
||||
p.drawText(itemRect, Qt::AlignLeft | Qt::AlignTop, contentText);
|
||||
else
|
||||
p.drawText(itemRect, Qt::AlignCenter, contentText);
|
||||
}
|
||||
|
||||
void BoardItem::saveData(TOStream &os) {
|
||||
os.child("type") << type2String(m_type);
|
||||
os.child("name") << m_name;
|
||||
os.child("rect") << m_rect.x() << m_rect.y() << m_rect.width()
|
||||
<< m_rect.height();
|
||||
|
||||
if (m_type == Image) {
|
||||
// if the path is in library folder, then save the realtive path
|
||||
TFilePath libFp = ToonzFolder::getLibraryFolder();
|
||||
if (libFp.isAncestorOf(m_imgPath))
|
||||
os.child("imgPath") << 1 << m_imgPath - libFp;
|
||||
else
|
||||
os.child("imgPath") << 0 << m_imgPath;
|
||||
os.child("imgARMode") << (int)m_imgARMode;
|
||||
} else {
|
||||
if (m_type == FreeText) os.child("text") << m_text;
|
||||
|
||||
os.child("maximumFontSize") << m_maximumFontSize;
|
||||
os.child("color") << m_color.red() << m_color.green() << m_color.blue()
|
||||
<< m_color.alpha();
|
||||
os.child("font") << m_font.family() << (int)(m_font.bold() ? 1 : 0)
|
||||
<< (int)(m_font.italic() ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void BoardItem::loadData(TIStream &is) {
|
||||
std::string tagName;
|
||||
while (is.matchTag(tagName)) {
|
||||
if (tagName == "type") {
|
||||
std::wstring typeStr;
|
||||
is >> typeStr;
|
||||
m_type = string2Type(typeStr);
|
||||
} else if (tagName == "name") {
|
||||
std::wstring str;
|
||||
is >> str;
|
||||
m_name = QString::fromStdWString(str);
|
||||
} else if (tagName == "rect") {
|
||||
double x, y, width, height;
|
||||
is >> x >> y >> width >> height;
|
||||
m_rect = QRectF(x, y, width, height);
|
||||
} else if (tagName == "imgPath") {
|
||||
int isInLibrary;
|
||||
TFilePath fp;
|
||||
is >> isInLibrary >> fp;
|
||||
if (isInLibrary == 1)
|
||||
m_imgPath = ToonzFolder::getLibraryFolder() + fp;
|
||||
else
|
||||
m_imgPath = fp;
|
||||
} else if (tagName == "imgARMode") {
|
||||
int mode;
|
||||
is >> mode;
|
||||
m_imgARMode = (Qt::AspectRatioMode)mode;
|
||||
} else if (tagName == "text") {
|
||||
std::wstring str;
|
||||
is >> str;
|
||||
m_text = QString::fromStdWString(str);
|
||||
} else if (tagName == "maximumFontSize") {
|
||||
is >> m_maximumFontSize;
|
||||
} else if (tagName == "color") {
|
||||
int r, g, b, a;
|
||||
is >> r >> g >> b >> a;
|
||||
m_color = QColor(r, g, b, a);
|
||||
} else if (tagName == "font") {
|
||||
QString family;
|
||||
int isBold, isItalic;
|
||||
is >> family >> isBold >> isItalic;
|
||||
m_font.setFamily(family);
|
||||
m_font.setBold(isBold == 1);
|
||||
m_font.setItalic(isItalic == 1);
|
||||
} else
|
||||
throw TException("unexpected tag: " + tagName);
|
||||
is.closeChild();
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================================
|
||||
|
||||
BoardSettings::BoardSettings() {
|
||||
// add one item as an example
|
||||
m_items.push_back(BoardItem());
|
||||
}
|
||||
|
||||
QImage BoardSettings::getBoardImage(TDimension &dim, int shrink,
|
||||
ToonzScene *scene) {
|
||||
QImage img(dim.lx, dim.ly, QImage::Format_ARGB32);
|
||||
|
||||
QPainter painter(&img);
|
||||
|
||||
painter.fillRect(img.rect(), Qt::white);
|
||||
|
||||
// draw each item
|
||||
for (int i = m_items.size() - 1; i >= 0; i--)
|
||||
m_items[i].drawItem(painter, img.rect().size(), shrink, scene);
|
||||
|
||||
painter.end();
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
TRaster32P BoardSettings::getBoardRaster(TDimension &dim, int shrink,
|
||||
ToonzScene *scene) {
|
||||
QImage img = getBoardImage(dim, shrink, scene);
|
||||
|
||||
// convert QImage to TRaster
|
||||
TRaster32P boardRas(dim);
|
||||
int img_y = img.height() - 1;
|
||||
for (int j = 0; j < dim.ly; j++, img_y--) {
|
||||
TPixel32 *pix = boardRas->pixels(j);
|
||||
QRgb *img_p = (QRgb *)img.scanLine(img_y);
|
||||
for (int i = 0; i < dim.lx; i++, pix++, img_p++) {
|
||||
(*pix).r = (typename TPixel32::Channel)(qRed(*img_p));
|
||||
(*pix).g = (typename TPixel32::Channel)(qGreen(*img_p));
|
||||
(*pix).b = (typename TPixel32::Channel)(qBlue(*img_p));
|
||||
(*pix).m = (typename TPixel32::Channel)(qAlpha(*img_p));
|
||||
}
|
||||
}
|
||||
return boardRas;
|
||||
}
|
||||
|
||||
void BoardSettings::addNewItem(int insertAt) {
|
||||
m_items.insert(insertAt, BoardItem());
|
||||
}
|
||||
|
||||
void BoardSettings::removeItem(int index) {
|
||||
if (index < 0 || index >= m_items.size()) return;
|
||||
m_items.removeAt(index);
|
||||
}
|
||||
|
||||
void BoardSettings::swapItems(int i, int j) { m_items.swap(i, j); }
|
||||
|
||||
void BoardSettings::saveData(TOStream &os, bool forPreset) {
|
||||
if (!forPreset) os.child("active") << (int)((m_active) ? 1 : 0);
|
||||
os.child("duration") << m_duration;
|
||||
if (!m_items.isEmpty()) {
|
||||
os.openChild("boardItems");
|
||||
for (int i = 0; i < getItemCount(); i++) {
|
||||
os.openChild("item");
|
||||
m_items[i].saveData(os);
|
||||
os.closeChild();
|
||||
}
|
||||
os.closeChild();
|
||||
}
|
||||
}
|
||||
|
||||
void BoardSettings::loadData(TIStream &is) {
|
||||
std::string tagName;
|
||||
while (is.matchTag(tagName)) {
|
||||
if (tagName == "active") {
|
||||
int val;
|
||||
is >> val;
|
||||
setActive(val == 1);
|
||||
} else if (tagName == "duration") {
|
||||
is >> m_duration;
|
||||
} else if (tagName == "boardItems") {
|
||||
m_items.clear();
|
||||
while (is.matchTag(tagName)) {
|
||||
if (tagName == "item") {
|
||||
BoardItem item;
|
||||
item.loadData(is);
|
||||
m_items.append(item);
|
||||
} else
|
||||
throw TException("unexpected tag: " + tagName);
|
||||
is.closeChild();
|
||||
}
|
||||
} else
|
||||
throw TException("unexpected tag: " + tagName);
|
||||
is.closeChild();
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
#include "toonz/trasterimageutils.h"
|
||||
#include "toonz/levelupdater.h"
|
||||
#include "toutputproperties.h"
|
||||
#include "toonz/boardsettings.h"
|
||||
|
||||
// tcg includes
|
||||
#include "tcg/tcg_macros.h"
|
||||
|
@ -160,6 +161,8 @@ public:
|
|||
std::pair<bool, int> saveFrame(double frame,
|
||||
const std::pair<TRasterP, TRasterP> &rasters);
|
||||
std::string getRenderCacheId();
|
||||
|
||||
void addBoard();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -374,7 +377,15 @@ std::pair<bool, int> MovieRenderer::Imp::saveFrame(
|
|||
m_renderSettings.m_timeStretchFrom;
|
||||
|
||||
int fr = (stretchFac != 1) ? tround(frame * stretchFac) : int(frame);
|
||||
TFrameId fid(fr + 1);
|
||||
|
||||
int boardDuration = 0;
|
||||
if (m_movieType) {
|
||||
BoardSettings *bs =
|
||||
m_scene->getProperties()->getOutputProperties()->getBoardSettings();
|
||||
boardDuration = (bs->isActive()) ? bs->getDuration() : 0;
|
||||
}
|
||||
|
||||
TFrameId fid(fr + 1 + boardDuration);
|
||||
|
||||
if (m_levelUpdaterA.get()) {
|
||||
assert(m_levelUpdaterB.get() || !rasters.second);
|
||||
|
@ -474,6 +485,8 @@ void MovieRenderer::Imp::doRenderRasterCompleted(const RenderData &renderData) {
|
|||
if (m_levelUpdaterB.get())
|
||||
m_levelUpdaterB->getLevelWriter()->saveSoundTrack(m_st.getPointer());
|
||||
}
|
||||
|
||||
addBoard();
|
||||
}
|
||||
|
||||
// Output frames must be *cloned*, since the supplied rasters will be
|
||||
|
@ -732,6 +745,40 @@ void MovieRenderer::Imp::onRenderFinished(bool isCanceled) {
|
|||
// eventually be deleted.
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
void MovieRenderer::Imp::addBoard() {
|
||||
BoardSettings *boardSettings =
|
||||
m_scene->getProperties()->getOutputProperties()->getBoardSettings();
|
||||
if (!boardSettings->isActive()) return;
|
||||
int duration = boardSettings->getDuration();
|
||||
if (duration == 0) return;
|
||||
// Get the image size
|
||||
int shrinkX = m_renderSettings.m_shrinkX,
|
||||
shrinkY = m_renderSettings.m_shrinkY;
|
||||
TDimensionD cameraRes(double(m_frameSize.lx) / shrinkX,
|
||||
double(m_frameSize.ly) / shrinkY);
|
||||
TDimension cameraResI(cameraRes.lx, cameraRes.ly);
|
||||
|
||||
TRaster32P boardRas =
|
||||
boardSettings->getBoardRaster(cameraResI, shrinkX, m_scene);
|
||||
|
||||
if (m_levelUpdaterA.get()) {
|
||||
// Flush images
|
||||
try {
|
||||
TRasterImageP img(boardRas);
|
||||
for (int f = 0; f < duration; f++) {
|
||||
m_levelUpdaterA->update(TFrameId(f + 1), img);
|
||||
if (m_levelUpdaterB.get())
|
||||
m_levelUpdaterB->update(TFrameId(f + 1), img);
|
||||
}
|
||||
} catch (...) {
|
||||
// Nothing. The images could not be saved for whatever reason.
|
||||
// Failure is reported.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================================
|
||||
|
||||
//======================
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include "toutputproperties.h"
|
||||
|
||||
// TnzLib includes
|
||||
#include "toonz/boardsettings.h"
|
||||
|
||||
// TnzBase includes
|
||||
#include "trasterfx.h"
|
||||
|
||||
|
@ -37,7 +40,8 @@ TOutputProperties::TOutputProperties()
|
|||
, m_multimediaRendering(0)
|
||||
, m_maxTileSizeIndex(0)
|
||||
, m_threadIndex(2)
|
||||
, m_subcameraPreview(false) {
|
||||
, m_subcameraPreview(false)
|
||||
, m_boardSettings(new BoardSettings()) {
|
||||
m_renderSettings = new TRenderSettings();
|
||||
}
|
||||
|
||||
|
@ -56,7 +60,8 @@ TOutputProperties::TOutputProperties(const TOutputProperties &src)
|
|||
, m_multimediaRendering(src.m_multimediaRendering)
|
||||
, m_maxTileSizeIndex(src.m_maxTileSizeIndex)
|
||||
, m_threadIndex(src.m_threadIndex)
|
||||
, m_subcameraPreview(src.m_subcameraPreview) {
|
||||
, m_subcameraPreview(src.m_subcameraPreview)
|
||||
, m_boardSettings(new BoardSettings(*src.m_boardSettings)) {
|
||||
std::map<std::string, TPropertyGroup *>::iterator ft,
|
||||
fEnd = m_formatProperties.end();
|
||||
for (ft = m_formatProperties.begin(); ft != fEnd; ++ft) {
|
||||
|
@ -100,6 +105,9 @@ TOutputProperties &TOutputProperties::operator=(const TOutputProperties &src) {
|
|||
for (sft = src.m_formatProperties.begin(); sft != sfEnd; ++sft)
|
||||
m_formatProperties[sft->first] = sft->second->clone();
|
||||
|
||||
delete m_boardSettings;
|
||||
m_boardSettings = new BoardSettings(*src.m_boardSettings);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "toonz/txshleveltypes.h"
|
||||
#include "toonz/preferences.h"
|
||||
#include "cleanuppalette.h"
|
||||
#include "toonz/boardsettings.h"
|
||||
|
||||
// TnzBase includes
|
||||
#include "toutputproperties.h"
|
||||
|
@ -293,6 +294,12 @@ void TSceneProperties::saveData(TOStream &os) const {
|
|||
}
|
||||
os.closeChild();
|
||||
|
||||
if (out.getBoardSettings() && out.getBoardSettings()->getDuration()) {
|
||||
os.openChild("clapperboardSettings");
|
||||
out.getBoardSettings()->saveData(os);
|
||||
os.closeChild();
|
||||
}
|
||||
|
||||
os.closeChild(); // </output>
|
||||
}
|
||||
os.closeChild();
|
||||
|
@ -654,6 +661,9 @@ void TSceneProperties::loadData(TIStream &is, bool isLoadingProject) {
|
|||
} else
|
||||
throw TException("unexpected tag: " + tagName);
|
||||
} // end while
|
||||
} else if (tagName == "clapperboardSettings") {
|
||||
assert(out.getBoardSettings());
|
||||
out.getBoardSettings()->loadData(is);
|
||||
} else {
|
||||
throw TException("unexpected property tag: " + tagName);
|
||||
}
|
||||
|
|
|
@ -203,6 +203,7 @@ ChannelField::ChannelField(QWidget *parent, const QString &string, int value,
|
|||
|
||||
m_channelSlider->setRange(0, maxValue);
|
||||
m_channelSlider->setValue(value);
|
||||
if (sliderWidth > 0) m_channelSlider->setFixedWidth(sliderWidth);
|
||||
|
||||
//----layout
|
||||
QGridLayout *mainLayout = new QGridLayout(this);
|
||||
|
@ -339,7 +340,7 @@ ColorField::ColorFieldEditorController *ColorField::m_editorController = 0;
|
|||
Return ColorField current color.
|
||||
*/
|
||||
ColorField::ColorField(QWidget *parent, bool isAlphaActive, TPixel32 color,
|
||||
int squareSize, bool useStyleEditor)
|
||||
int squareSize, bool useStyleEditor, int sliderWidth)
|
||||
: QWidget(parent)
|
||||
, m_color(color)
|
||||
, m_notifyEditingChange(true)
|
||||
|
@ -355,16 +356,20 @@ ColorField::ColorField(QWidget *parent, bool isAlphaActive, TPixel32 color,
|
|||
|
||||
m_colorSample = new StyleSample(this, squareSize, squareSize);
|
||||
m_colorSample->setColor(m_color);
|
||||
m_redChannel = new ChannelField(this, tr("R:"), m_color.r);
|
||||
m_redChannel =
|
||||
new ChannelField(this, tr("R:"), m_color.r, 255, false, 13, sliderWidth);
|
||||
connect(m_redChannel, SIGNAL(valueChanged(int, bool)),
|
||||
SLOT(onRedChannelChanged(int, bool)));
|
||||
m_greenChannel = new ChannelField(this, tr("G:"), m_color.g);
|
||||
m_greenChannel =
|
||||
new ChannelField(this, tr("G:"), m_color.g, 255, false, 13, sliderWidth);
|
||||
connect(m_greenChannel, SIGNAL(valueChanged(int, bool)),
|
||||
SLOT(onGreenChannelChanged(int, bool)));
|
||||
m_blueChannel = new ChannelField(this, tr("B:"), m_color.b);
|
||||
m_blueChannel =
|
||||
new ChannelField(this, tr("B:"), m_color.b, 255, false, 13, sliderWidth);
|
||||
connect(m_blueChannel, SIGNAL(valueChanged(int, bool)),
|
||||
SLOT(onBlueChannelChanged(int, bool)));
|
||||
m_alphaChannel = new ChannelField(this, tr("A:"), m_color.m);
|
||||
m_alphaChannel =
|
||||
new ChannelField(this, tr("A:"), m_color.m, 255, false, 13, sliderWidth);
|
||||
connect(m_alphaChannel, SIGNAL(valueChanged(int, bool)),
|
||||
SLOT(onAlphaChannelChanged(int, bool)));
|
||||
|
||||
|
|
Loading…
Reference in a new issue