Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Multimedia
Kdenlive
Commits
885a968b
Commit
885a968b
authored
Feb 27, 2021
by
Rafał Lalik
Committed by
Julius Künzel
Feb 27, 2021
Browse files
Builtin typewriter for kdenlive titler
Fixes
#789
parent
89c5c95f
Pipeline
#52463
passed with stage
in 10 minutes and 33 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/titler/graphicsscenerectmove.cpp
View file @
885a968b
...
...
@@ -76,6 +76,7 @@ MyTextItem::MyTextItem(const QString &txt, QGraphicsItem *parent)
setGraphicsEffect
(
m_shadowEffect
);
updateGeometry
();
connect
(
document
(),
SIGNAL
(
contentsChange
(
int
,
int
,
int
)),
this
,
SLOT
(
updateGeometry
(
int
,
int
,
int
)));
updateTW
(
0
,
2
,
1
,
0
,
0
);
}
Qt
::
Alignment
MyTextItem
::
alignment
()
const
...
...
@@ -242,6 +243,33 @@ void MyTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
}
}
void
MyTextItem
::
updateTW
(
bool
enabled
,
int
step
,
int
mode
,
int
sigma
,
int
seed
)
{
tw_enabled
=
enabled
;
tw_step
=
step
;
tw_mode
=
mode
;
tw_sigma
=
sigma
;
tw_seed
=
seed
;
}
void
MyTextItem
::
loadTW
(
const
QStringList
&
info
)
{
if
(
info
.
count
()
<
5
)
{
return
;
}
updateTW
((
static_cast
<
bool
>
(
info
.
at
(
0
).
toInt
())),
info
.
at
(
1
).
toInt
(),
info
.
at
(
2
).
toInt
(),
info
.
at
(
3
).
toInt
(),
info
.
at
(
4
).
toInt
());
}
QStringList
MyTextItem
::
twInfo
()
const
{
QStringList
info
;
info
<<
QString
::
number
(
tw_enabled
)
<<
QString
::
number
(
tw_step
)
<<
QString
::
number
(
tw_mode
)
<<
QString
::
number
(
tw_sigma
)
<<
QString
::
number
(
tw_seed
);
return
info
;
}
void
MyTextItem
::
updateShadow
()
{
QString
text
=
toPlainText
();
...
...
src/titler/graphicsscenerectmove.h
View file @
885a968b
...
...
@@ -60,6 +60,9 @@ public:
void
updateShadow
(
bool
enabled
,
int
blur
,
int
xoffset
,
int
yoffset
,
QColor
color
);
QStringList
shadowInfo
()
const
;
void
loadShadow
(
const
QStringList
&
info
);
void
updateTW
(
bool
enabled
,
int
mode
,
int
step
,
int
sigma
,
int
seed
);
QStringList
twInfo
()
const
;
void
loadTW
(
const
QStringList
&
info
);
void
mouseDoubleClickEvent
(
QGraphicsSceneMouseEvent
*
evt
)
override
;
void
setTextColor
(
const
QColor
&
col
);
...
...
@@ -77,6 +80,11 @@ private:
void
updateShadow
();
void
blurShadow
(
QImage
&
image
,
int
radius
);
void
refreshFormat
();
bool
tw_enabled
;
int
tw_step
;
int
tw_mode
;
int
tw_sigma
;
int
tw_seed
;
public
slots
:
void
updateGeometry
(
int
,
int
,
int
);
...
...
src/titler/titledocument.cpp
View file @
885a968b
...
...
@@ -268,6 +268,7 @@ QDomDocument TitleDocument::xml(const QList<QGraphicsItem *> & items, int width,
}
content
.
setAttribute
(
QStringLiteral
(
"shadow"
),
t
->
shadowInfo
().
join
(
QLatin1Char
(
';'
)));
content
.
setAttribute
(
QStringLiteral
(
"typewriter"
),
t
->
twInfo
().
join
(
QLatin1Char
(
';'
)));
break
;
default:
continue
;
...
...
@@ -524,9 +525,8 @@ int TitleDocument::loadFromXml(const QDomDocument &doc, QList<QGraphicsItem *> &
// Effects
if
(
!
txtProperties
.
namedItem
(
QStringLiteral
(
"typewriter"
)).
isNull
())
{
QStringList
effData
=
QStringList
()
<<
QStringLiteral
(
"typewriter"
)
<<
txtProperties
.
namedItem
(
QStringLiteral
(
"typewriter"
)).
nodeValue
();
txt
->
setData
(
100
,
effData
);
QString
info
=
txtProperties
.
namedItem
(
QStringLiteral
(
"typewriter"
)).
nodeValue
();
txt
->
loadTW
(
info
.
split
(
QLatin1Char
(
';'
)));
}
if
(
txt
->
toPlainText
()
==
QLatin1String
(
"%s"
))
{
// template text box, adjust size for later remplacement text
...
...
src/titler/titlewidget.cpp
View file @
885a968b
...
...
@@ -183,6 +183,26 @@ TitleWidget::TitleWidget(const QUrl &url, const Timecode &tc, QString projectTit
connect
(
shadowX
,
static_cast
<
void
(
QSpinBox
::*
)(
int
)
>
(
&
QSpinBox
::
valueChanged
),
this
,
&
TitleWidget
::
slotUpdateShadow
);
connect
(
shadowY
,
static_cast
<
void
(
QSpinBox
::*
)(
int
)
>
(
&
QSpinBox
::
valueChanged
),
this
,
&
TitleWidget
::
slotUpdateShadow
);
connect
(
typewriterBox
,
&
QGroupBox
::
toggled
,
this
,
&
TitleWidget
::
slotUpdateTW
);
connect
(
tw_sb_step
,
static_cast
<
void
(
QSpinBox
::*
)(
int
)
>
(
&
QSpinBox
::
valueChanged
),
this
,
&
TitleWidget
::
slotUpdateTW
);
connect
(
tw_sb_sigma
,
static_cast
<
void
(
QSpinBox
::*
)(
int
)
>
(
&
QSpinBox
::
valueChanged
),
this
,
&
TitleWidget
::
slotUpdateTW
);
connect
(
tw_sb_seed
,
static_cast
<
void
(
QSpinBox
::*
)(
int
)
>
(
&
QSpinBox
::
valueChanged
),
this
,
&
TitleWidget
::
slotUpdateTW
);
connect
(
tw_rd_char
,
&
QRadioButton
::
toggled
,
this
,
&
TitleWidget
::
slotUpdateTW
);
connect
(
tw_rd_word
,
&
QRadioButton
::
toggled
,
this
,
&
TitleWidget
::
slotUpdateTW
);
connect
(
tw_rd_line
,
&
QRadioButton
::
toggled
,
this
,
&
TitleWidget
::
slotUpdateTW
);
connect
(
tw_rd_custom
,
&
QRadioButton
::
toggled
,
this
,
&
TitleWidget
::
slotUpdateTW
);
tw_rd_custom
->
setEnabled
(
false
);
if
(
mlt_version_get_int
()
<=
0x061a00
)
{
typewriterBox
->
setEnabled
(
false
);
auto
*
twinfo
=
new
KMessageWidget
(
typewriterBox
);
twinfo
->
setText
(
i18n
(
"Typewriter requires MLT-6.26.0 or newer."
));
twinfo
->
setMessageType
(
KMessageWidget
::
Warning
);
twinfo
->
setCloseButtonVisible
(
false
);
twinfo
->
setEnabled
(
true
);
gridLayout_12
->
addWidget
(
twinfo
,
3
,
0
,
1
,
4
,
0
);
}
connect
(
fontColorButton
,
&
KColorButton
::
changed
,
this
,
&
TitleWidget
::
slotUpdateText
);
connect
(
plain_color
,
&
QAbstractButton
::
clicked
,
this
,
&
TitleWidget
::
slotUpdateText
);
connect
(
gradient_color
,
&
QAbstractButton
::
clicked
,
this
,
&
TitleWidget
::
slotUpdateText
);
...
...
@@ -2935,6 +2955,22 @@ void TitleWidget::prepareTools(QGraphicsItem *referenceItem)
shadowBox
->
blockSignals
(
false
);
}
sInfo
=
i
->
twInfo
();
if
(
sInfo
.
count
()
>=
5
)
{
typewriterBox
->
setChecked
(
static_cast
<
bool
>
(
sInfo
.
at
(
0
).
toInt
()));
typewriterBox
->
blockSignals
(
true
);
tw_sb_step
->
setValue
(
sInfo
.
at
(
1
).
toInt
());
switch
(
sInfo
.
at
(
2
).
toInt
())
{
case
1
:
tw_rd_char
->
setChecked
(
true
);
break
;
case
2
:
tw_rd_word
->
setChecked
(
true
);
break
;
case
3
:
tw_rd_line
->
setChecked
(
true
);
break
;
default:
tw_rd_custom
->
setChecked
(
true
);
break
;
}
tw_sb_sigma
->
setValue
(
sInfo
.
at
(
3
).
toInt
());
tw_sb_seed
->
setValue
(
sInfo
.
at
(
4
).
toInt
());
typewriterBox
->
blockSignals
(
false
);
}
letter_spacing
->
blockSignals
(
true
);
line_spacing
->
blockSignals
(
true
);
QTextCursor
cur
=
i
->
textCursor
();
...
...
@@ -3170,6 +3206,27 @@ void TitleWidget::slotUpdateShadow()
}
}
void
TitleWidget
::
slotUpdateTW
()
{
QList
<
QGraphicsItem
*>
l
=
graphicsView
->
scene
()
->
selectedItems
();
for
(
int
i
=
0
;
i
<
graphicsView
->
scene
()
->
selectedItems
().
length
();
++
i
)
{
MyTextItem
*
item
=
nullptr
;
if
(
l
.
at
(
i
)
->
type
()
==
TEXTITEM
)
{
item
=
static_cast
<
MyTextItem
*>
(
l
.
at
(
i
));
}
if
(
!
item
)
{
// No text item, try next one.
continue
;
}
int
mode
=
0
;
if
(
tw_rd_char
->
isChecked
())
mode
=
1
;
else
if
(
tw_rd_word
->
isChecked
())
mode
=
2
;
else
if
(
tw_rd_line
->
isChecked
())
mode
=
3
;
item
->
updateTW
(
typewriterBox
->
isChecked
(),
tw_sb_step
->
value
(),
mode
,
tw_sb_sigma
->
value
(),
tw_sb_seed
->
value
());
}
}
const
QString
TitleWidget
::
titleSuggest
()
{
// Find top item to extract title proposal
...
...
src/titler/titlewidget.h
View file @
885a968b
...
...
@@ -384,6 +384,9 @@ private slots:
void
templateIndexChanged
(
int
);
void
slotEditGradient
();
void
slotUpdateShadow
();
/** TW stuff */
void
slotUpdateTW
();
/** @brief Remove missing items from the scene. */
void
deleteMissingItems
();
/** @brief List missing items from the scene. */
...
...
src/ui/titlewidget_ui.ui
View file @
885a968b
...
...
@@ -1034,6 +1034,115 @@
</property>
</widget>
</item>
<item
row=
"9"
column=
"0"
colspan=
"7"
>
<widget
class=
"QGroupBox"
name=
"typewriterBox"
>
<property
name=
"title"
>
<string>
&
Typewriter effect
</string>
</property>
<property
name=
"checkable"
>
<bool>
true
</bool>
</property>
<property
name=
"checked"
>
<bool>
false
</bool>
</property>
<layout
class=
"QGridLayout"
name=
"gridLayout_12"
>
<item
row=
"0"
column=
"1"
>
<widget
class=
"QSpinBox"
name=
"tw_sb_step"
>
<property
name=
"minimum"
>
<number>
1
</number>
</property>
<property
name=
"maximum"
>
<number>
240
</number>
</property>
<property
name=
"value"
>
<number>
2
</number>
</property>
</widget>
</item>
<item
row=
"2"
column=
"0"
colspan=
"4"
>
<widget
class=
"QGroupBox"
name=
"groupBox_2"
>
<property
name=
"title"
>
<string>
Expansion mode
</string>
</property>
<property
name=
"alignment"
>
<set>
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
</set>
</property>
<property
name=
"flat"
>
<bool>
true
</bool>
</property>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_5"
>
<item>
<widget
class=
"QRadioButton"
name=
"tw_rd_char"
>
<property
name=
"text"
>
<string>
by
&
char
</string>
</property>
<property
name=
"checked"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"tw_rd_word"
>
<property
name=
"text"
>
<string>
by
&
word
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"tw_rd_line"
>
<property
name=
"text"
>
<string>
by
&
line
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"tw_rd_custom"
>
<property
name=
"text"
>
<string>
custo
&
m
</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item
row=
"0"
column=
"2"
>
<widget
class=
"QLabel"
name=
"label_6"
>
<property
name=
"text"
>
<string>
Variation
</string>
</property>
</widget>
</item>
<item
row=
"0"
column=
"3"
>
<widget
class=
"QSpinBox"
name=
"tw_sb_sigma"
>
<property
name=
"maximum"
>
<number>
240
</number>
</property>
</widget>
</item>
<item
row=
"0"
column=
"0"
>
<widget
class=
"QLabel"
name=
"label_5"
>
<property
name=
"text"
>
<string>
Frame step
</string>
</property>
</widget>
</item>
<item
row=
"1"
column=
"2"
>
<widget
class=
"QLabel"
name=
"label_8"
>
<property
name=
"text"
>
<string>
Seed
</string>
</property>
</widget>
</item>
<item
row=
"1"
column=
"3"
>
<widget
class=
"QSpinBox"
name=
"tw_sb_seed"
>
<property
name=
"maximum"
>
<number>
9999
</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment