Hi,
I needed to improve the titler timecode to generate a working clock so I
added 2 fields, an offset (in frames) and a format. The offset allows you
to set the timecode value to any time (frame) you want (although without a
multiplier it's still fixed to playback time of course). The format
displays the timecode in various formats from units.C.
Is the preference on the list to attach patches? I usually like inline
patches, but I'll do whatever :) I've attached the patch this time.
Index: plugins/titler/titlewindow.h
===================================================================
--- plugins/titler/titlewindow.h (revision 746)
+++ plugins/titler/titlewindow.h (working copy)
@@ -43,6 +43,8 @@
class TitleColorStrokeThread;
class TitleSpeed;
class TitleTimecode;
+class TitleTimecodeOffset;
+class TitleTimecodeFormat;
class TitleWindow : public BC_Window
{
@@ -109,11 +111,16 @@
BC_Title *speed_title;
TitleSpeed *speed;
TitleTimecode *timecode;
+ BC_Title *timecode_offset_title;
+ TitleTimecodeOffset *timecode_offset;
+ BC_Title *timecode_format_title;
+ TitleTimecodeFormat *timecode_format;
// Color preview
ArrayList<BC_ListBoxItem*> sizes;
ArrayList<BC_ListBoxItem*> encodings;
ArrayList<BC_ListBoxItem*> paths;
+ ArrayList<BC_ListBoxItem*> tc_formats;
ArrayList<BC_ListBoxItem*> fonts;
};
@@ -216,6 +223,21 @@
TitleMain *client;
TitleWindow *window;
};
+class TitleTimecodeOffset : public BC_TumbleTextBox
+{
+public:
+ TitleTimecodeOffset(TitleMain *client, TitleWindow *window, int x, int
y);
+ int handle_event();
+ TitleMain *client;
+};
+class TitleTimecodeFormat : public BC_PopupTextBox
+{
+public:
+ TitleTimecodeFormat(TitleMain *client, TitleWindow *window, int x, int
y);
+ int handle_event();
+ TitleMain *client;
+ TitleWindow *window;
+};
class TitleFade : public BC_TextBox
{
public:
Index: plugins/titler/title.C
===================================================================
--- plugins/titler/title.C (revision 746)
+++ plugins/titler/title.C (working copy)
@@ -62,6 +62,8 @@
sprintf(encoding, DEFAULT_ENCODING);
pixels_per_second = 1.0;
timecode = 0;
+ timecode_offset = 0;
+ timecode_format = TIME_HMS;
stroke_width = 1.0;
}
@@ -75,6 +77,8 @@
color_stroke == that.color_stroke &&
stroke_width == that.stroke_width &&
timecode == that.timecode &&
+ timecode_offset == that.timecode_offset &&
+ timecode_format == that.timecode_format &&
hjustification == that.hjustification &&
vjustification == that.vjustification &&
EQUIV(pixels_per_second, that.pixels_per_second) &&
@@ -102,6 +106,8 @@
y = that.y;
dropshadow = that.dropshadow;
timecode = that.timecode;
+ timecode_offset = that.timecode_offset;
+ timecode_format = that.timecode_format;
strcpy(text, that.text);
strcpy(encoding, that.encoding);
}
@@ -137,6 +143,8 @@
this->x = prev.x;
this->y = prev.y;
timecode = prev.timecode;
+ timecode_offset = prev.timecode_offset;
+ timecode_format = prev.timecode_format;
// this->dropshadow = (int)(prev.dropshadow * prev_scale + next.dropshadow
* next_scale);
this->dropshadow = prev.dropshadow;
}
@@ -1935,7 +1943,28 @@
}
+char* TitleMain::timecode_format_to_text(int format)
+{
+ switch(format)
+ {
+ case TIME_SECONDS: return _("Seconds"); break;
+ case TIME_HMS: return _("HH:MM:SS:TTT"); break;
+ case TIME_HMS2: return _("H:MM:SS"); break;
+ case TIME_HMS3: return _("HH:MM:SS"); break;
+ case TIME_HMSF: return _("H:MM:SS:FF"); break;
+ case TIME_FRAMES: return _("Frames"); break;
+ }
+ return _("?");
+}
+int TitleMain::text_to_timecode_format(char *text)
+{
+ for(int i = 0; i < 9; i++)
+ {
+ if(!strcasecmp(timecode_format_to_text(i), text)) return i;
+ }
+ return 0;
+}
@@ -1955,9 +1984,10 @@
int64_t rendered_frame = get_source_position();
if (get_direction() == PLAY_REVERSE)
rendered_frame -= 1;
+ rendered_frame += config.timecode_offset;
Units::totext(config.text,
(double)rendered_frame /
PluginVClient::project_frame_rate,
- TIME_HMSF,
+ config.timecode_format,
0,
PluginVClient::project_frame_rate,
0);
@@ -2119,6 +2149,8 @@
config.y = defaults->get("TITLE_Y", config.y);
config.dropshadow = defaults->get("DROPSHADOW", config.dropshadow);
config.timecode = defaults->get("TIMECODE", config.timecode);
+ config.timecode_offset = defaults->get("TIMECODE_OFFSET",
config.timecode_offset);
+ config.timecode_format = defaults->get("TIMECODE_FORMAT",
config.timecode_format);
window_w = defaults->get("WINDOW_W", 660);
window_h = defaults->get("WINDOW_H", 480);
@@ -2164,6 +2196,8 @@
defaults->update("TITLE_Y", config.y);
defaults->update("DROPSHADOW", config.dropshadow);
defaults->update("TIMECODE", config.timecode);
+ defaults->update("TIMECODE_OFFSET", config.timecode_offset);
+ defaults->update("TIMECODE_FORMAT", config.timecode_format);
defaults->update("WINDOW_W", window_w);
defaults->update("WINDOW_H", window_h);
defaults->save();
@@ -2269,6 +2303,8 @@
output.tag.set_property("TITLE_Y", config.y);
output.tag.set_property("DROPSHADOW", config.dropshadow);
output.tag.set_property("TIMECODE", config.timecode);
+ output.tag.set_property("TIMECODE_OFFSET", config.timecode_offset);
+ output.tag.set_property("TIMECODE_FORMAT", config.timecode_format);
output.append_tag();
output.append_newline();
@@ -2320,6 +2356,8 @@
config.y = input.tag.get_property("TITLE_Y",
config.y);
config.dropshadow =
input.tag.get_property("DROPSHADOW", config.dropshadow);
config.timecode =
input.tag.get_property("TIMECODE", config.timecode);
+ config.timecode_offset =
input.tag.get_property("TIMECODE_OFFSET", config.timecode_offset);
+ config.timecode_format =
input.tag.get_property("TIMECODE_FORMAT", config.timecode_format);
strcpy(config.text, input.read_text());
//printf("TitleMain::read_data 1\n%s\n", input.string);
//printf("TitleMain::read_data 2\n%s\n", config.text);
Index: plugins/titler/title.h
===================================================================
--- plugins/titler/title.h (revision 746)
+++ plugins/titler/title.h (working copy)
@@ -104,6 +104,8 @@
int64_t next_keyframe_position;
// Stamp timecode
int timecode;
+ int64_t timecode_offset;
+ int timecode_format;
// Text to display
char text[BCTEXTLEN];
@@ -347,6 +349,9 @@
static char* motion_to_text(int motion);
static int text_to_motion(char *text);
+
+ static char* timecode_format_to_text(int motion);
+ static int text_to_timecode_format(char *text);
// a thread for the GUI
TitleThread *thread;
// Current configuration
Index: plugins/titler/titlewindow.C
===================================================================
--- plugins/titler/titlewindow.C (revision 746)
+++ plugins/titler/titlewindow.C (working copy)
@@ -106,6 +106,12 @@
paths.append(new
BC_ListBoxItem(TitleMain::motion_to_text(RIGHT_TO_LEFT)));
paths.append(new
BC_ListBoxItem(TitleMain::motion_to_text(LEFT_TO_RIGHT)));
+ tc_formats.append(new
BC_ListBoxItem(TitleMain::timecode_format_to_text(TIME_SECONDS)));
+ tc_formats.append(new
BC_ListBoxItem(TitleMain::timecode_format_to_text(TIME_HMS)));
+ tc_formats.append(new
BC_ListBoxItem(TitleMain::timecode_format_to_text(TIME_HMS2)));
+ tc_formats.append(new
BC_ListBoxItem(TitleMain::timecode_format_to_text(TIME_HMS3)));
+ tc_formats.append(new
BC_ListBoxItem(TitleMain::timecode_format_to_text(TIME_HMSF)));
+ tc_formats.append(new
BC_ListBoxItem(TitleMain::timecode_format_to_text(TIME_FRAMES)));
// Construct font list
@@ -269,7 +275,15 @@
x += 100;
add_tool(timecode = new TitleTimecode(client, x, y));
+ x += 125;
+ add_tool(timecode_offset_title = new BC_Title(x, y - 20, _("Offset
(frames):")));
+ timecode_offset = new TitleTimecodeOffset(client, this, x, y);
+ timecode_offset->create_objects();
+ x += 125;
+ add_tool(timecode_format_title = new BC_Title(x, y - 20, _("Format:")));
+ timecode_format = new TitleTimecodeFormat(client, this, x, y);
+ timecode_format->create_objects();
x = 10;
y += 30;
@@ -330,6 +344,10 @@
strokewidth_title->reposition_window(strokewidth_title->get_x(),
strokewidth_title->get_y());
#endif
timecode->reposition_window(timecode->get_x(), timecode->get_y());
+
timecode_offset_title->reposition_window(timecode_offset_title->get_x(),
timecode_offset_title->get_y());
+ timecode_offset->reposition_window(timecode_offset->get_x(),
timecode_offset->get_y());
+
timecode_format_title->reposition_window(timecode_format_title->get_x(),
timecode_format_title->get_y());
+ timecode_format->reposition_window(timecode_format->get_x(),
timecode_format->get_y());
text->reposition_window(text->get_x(),
text->get_y(),
@@ -620,7 +638,7 @@
}
TitleTimecode::TitleTimecode(TitleMain *client, int x, int y)
- : BC_CheckBox(x, y, client->config.timecode, _("Stamp timecode"))
+ : BC_CheckBox(x, y, client->config.timecode, _("Use timecode"))
{
this->client = client;
}
@@ -631,6 +649,43 @@
return 1;
}
+TitleTimecodeOffset::TitleTimecodeOffset(TitleMain *client, TitleWindow
*window, int x, int y)
+ : BC_TumbleTextBox(window,
+ (int)client->config.timecode_offset,
+ (int)-1024*1024*1024,
+ (int)1024*1024*1024,
+ x,
+ y,
+ 70)
+{
+ this->client = client;
+}
+int TitleTimecodeOffset::handle_event()
+{
+ client->config.timecode_offset = atoi(get_text());
+ client->send_configure_change();
+ return 1;
+}
+
+TitleTimecodeFormat::TitleTimecodeFormat(TitleMain *client, TitleWindow
*window, int x, int y)
+ : BC_PopupTextBox(window,
+ &window->tc_formats,
+ client->timecode_format_to_text(client->config.timecode_format),
+ x,
+ y,
+ 120,
+ 100)
+{
+ this->client = client;
+ this->window = window;
+}
+int TitleTimecodeFormat::handle_event()
+{
+ client->config.timecode_format =
client->text_to_timecode_format(get_text());
+ client->send_configure_change();
+ return 1;
+}
+
TitleFade::TitleFade(TitleMain *client,
TitleWindow *window,
double *value,