mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-09-02 02:03:54 +00:00
add text box to set durations from formatted strings
This commit is contained in:
parent
496c654728
commit
d67801792d
2 changed files with 139 additions and 6 deletions
|
@ -18,9 +18,13 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <ges/ges.h>
|
#include <ges/ges.h>
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
typedef struct App
|
typedef struct App
|
||||||
{
|
{
|
||||||
|
@ -44,6 +48,8 @@ typedef struct App
|
||||||
GtkComboBox *halign;
|
GtkComboBox *halign;
|
||||||
GtkComboBox *valign;
|
GtkComboBox *valign;
|
||||||
GtkEntry *text;
|
GtkEntry *text;
|
||||||
|
GtkEntry *seconds;
|
||||||
|
GtkWidget *generic_duration;
|
||||||
GstState state;
|
GstState state;
|
||||||
GType selected_type;
|
GType selected_type;
|
||||||
} App;
|
} App;
|
||||||
|
@ -108,6 +114,9 @@ void connect_to_title_source (GESTimelineObject * object, App * app);
|
||||||
|
|
||||||
void disconnect_from_title_source (GESTimelineObject * object, App * app);
|
void disconnect_from_title_source (GESTimelineObject * object, App * app);
|
||||||
|
|
||||||
|
void seconds_notify_text_changed_cb (GtkEntry * widget, GParamSpec * unused,
|
||||||
|
App * app);
|
||||||
|
|
||||||
/* UI state functions *******************************************************/
|
/* UI state functions *******************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -194,6 +203,9 @@ app_selection_changed_cb (GtkTreeSelection * selection, App * app)
|
||||||
|
|
||||||
gtk_widget_set_visible (app->text_properties,
|
gtk_widget_set_visible (app->text_properties,
|
||||||
app->selected_type == GES_TYPE_TIMELINE_TITLE_SOURCE);
|
app->selected_type == GES_TYPE_TIMELINE_TITLE_SOURCE);
|
||||||
|
|
||||||
|
gtk_widget_set_visible (app->generic_duration,
|
||||||
|
app->selected_type == GES_TYPE_TIMELINE_TITLE_SOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -278,6 +290,74 @@ text_notify_text_changed_cb (GtkEntry * widget, GParamSpec * unused, App * app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
check_time (const gchar * time)
|
||||||
|
{
|
||||||
|
static regex_t re;
|
||||||
|
static gboolean compiled = FALSE;
|
||||||
|
|
||||||
|
if (!compiled) {
|
||||||
|
compiled = TRUE;
|
||||||
|
regcomp (&re, "^[0-9][0-9]:[0-5][0-9]:[0-5][0-9](.[0-9]+)?$",
|
||||||
|
REG_EXTENDED | REG_NOSUB);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!regexec (&re, time, (size_t) 0, NULL, 0))
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint64
|
||||||
|
str_to_time (const gchar * str)
|
||||||
|
{
|
||||||
|
guint64 ret;
|
||||||
|
guint64 h, m;
|
||||||
|
gdouble s;
|
||||||
|
gchar buf[15];
|
||||||
|
|
||||||
|
buf[0] = str[0];
|
||||||
|
buf[1] = str[1];
|
||||||
|
buf[2] = '\0';
|
||||||
|
|
||||||
|
h = strtoull (buf, NULL, 10);
|
||||||
|
|
||||||
|
buf[0] = str[3];
|
||||||
|
buf[1] = str[4];
|
||||||
|
buf[2] = '\0';
|
||||||
|
|
||||||
|
m = strtoull (buf, NULL, 10);
|
||||||
|
|
||||||
|
strncpy (buf, &str[6], sizeof (buf));
|
||||||
|
s = strtod (buf, NULL);
|
||||||
|
|
||||||
|
ret = (h * 3600 * GST_SECOND) +
|
||||||
|
(m * 60 * GST_SECOND) + ((guint64) (s * GST_SECOND));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
seconds_notify_text_changed_cb (GtkEntry * widget, GParamSpec * unused,
|
||||||
|
App * app)
|
||||||
|
{
|
||||||
|
GList *tmp;
|
||||||
|
const gchar *text;
|
||||||
|
|
||||||
|
text = gtk_entry_get_text (app->seconds);
|
||||||
|
|
||||||
|
if (!check_time (text)) {
|
||||||
|
gtk_entry_set_icon_from_stock (app->seconds,
|
||||||
|
GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_WARNING);
|
||||||
|
} else {
|
||||||
|
gtk_entry_set_icon_from_stock (app->seconds,
|
||||||
|
GTK_ENTRY_ICON_SECONDARY, NULL);
|
||||||
|
for (tmp = app->selected_objects; tmp; tmp = tmp->next) {
|
||||||
|
g_object_set (GES_TIMELINE_OBJECT (tmp->data), "duration",
|
||||||
|
(guint64) str_to_time (text), NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* application methods ******************************************************/
|
/* application methods ******************************************************/
|
||||||
|
|
||||||
static void selection_foreach (GtkTreeModel * model, GtkTreePath * path,
|
static void selection_foreach (GtkTreeModel * model, GtkTreePath * path,
|
||||||
|
@ -653,11 +733,23 @@ disconnect_from_filesource (GESTimelineObject * object, App * app)
|
||||||
void
|
void
|
||||||
connect_to_title_source (GESTimelineObject * object, App * app)
|
connect_to_title_source (GESTimelineObject * object, App * app)
|
||||||
{
|
{
|
||||||
|
gdouble s;
|
||||||
|
guint64 duration;
|
||||||
|
gchar buf[30];
|
||||||
|
|
||||||
GESTimelineTitleSource *obj;
|
GESTimelineTitleSource *obj;
|
||||||
obj = GES_TIMELINE_TITLE_SOURCE (object);
|
obj = GES_TIMELINE_TITLE_SOURCE (object);
|
||||||
gtk_combo_box_set_active (app->halign, obj->halign);
|
gtk_combo_box_set_active (app->halign, obj->halign);
|
||||||
gtk_combo_box_set_active (app->valign, obj->valign);
|
gtk_combo_box_set_active (app->valign, obj->valign);
|
||||||
gtk_entry_set_text (app->text, obj->text);
|
gtk_entry_set_text (app->text, obj->text);
|
||||||
|
|
||||||
|
duration = GES_TIMELINE_OBJECT_DURATION (object);
|
||||||
|
|
||||||
|
s = (duration / (float) GST_SECOND);
|
||||||
|
|
||||||
|
g_snprintf (buf, sizeof (buf), "%02u:%02u:%02u.%09u",
|
||||||
|
GST_TIME_ARGS (duration));
|
||||||
|
gtk_entry_set_text (app->seconds, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -717,12 +809,17 @@ create_ui (App * app)
|
||||||
GET_WIDGET (app->add_file, "add_file", GTK_ACTION);
|
GET_WIDGET (app->add_file, "add_file", GTK_ACTION);
|
||||||
GET_WIDGET (app->delete, "delete", GTK_ACTION);
|
GET_WIDGET (app->delete, "delete", GTK_ACTION);
|
||||||
GET_WIDGET (app->play, "play", GTK_ACTION);
|
GET_WIDGET (app->play, "play", GTK_ACTION);
|
||||||
|
GET_WIDGET (app->seconds, "seconds", GTK_ENTRY);
|
||||||
|
GET_WIDGET (app->generic_duration, "generic_duration", GTK_WIDGET);
|
||||||
|
|
||||||
/* get text notifications */
|
/* get text notifications */
|
||||||
|
|
||||||
g_signal_connect (app->text, "notify::text",
|
g_signal_connect (app->text, "notify::text",
|
||||||
G_CALLBACK (text_notify_text_changed_cb), app);
|
G_CALLBACK (text_notify_text_changed_cb), app);
|
||||||
|
|
||||||
|
g_signal_connect (app->seconds, "notify::text",
|
||||||
|
G_CALLBACK (seconds_notify_text_changed_cb), app);
|
||||||
|
|
||||||
/* we care when the tree selection changes */
|
/* we care when the tree selection changes */
|
||||||
|
|
||||||
if (!(app->selection = gtk_tree_view_get_selection (timeline)))
|
if (!(app->selection = gtk_tree_view_get_selection (timeline)))
|
||||||
|
|
|
@ -133,8 +133,8 @@
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="delete_item">
|
<object class="GtkImageMenuItem" id="delete_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="related_action">delete</property>
|
|
||||||
<property name="use_action_appearance">True</property>
|
<property name="use_action_appearance">True</property>
|
||||||
|
<property name="related_action">delete</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</object>
|
</object>
|
||||||
|
@ -161,15 +161,15 @@
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="add_file_item">
|
<object class="GtkMenuItem" id="add_file_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="related_action">add_file</property>
|
|
||||||
<property name="use_action_appearance">True</property>
|
<property name="use_action_appearance">True</property>
|
||||||
|
<property name="related_action">add_file</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="menuitem4">
|
<object class="GtkMenuItem" id="menuitem4">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="related_action">add_text</property>
|
|
||||||
<property name="use_action_appearance">True</property>
|
<property name="use_action_appearance">True</property>
|
||||||
|
<property name="related_action">add_text</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -181,8 +181,8 @@
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="menuitem2">
|
<object class="GtkImageMenuItem" id="menuitem2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="related_action">play</property>
|
|
||||||
<property name="use_action_appearance">True</property>
|
<property name="use_action_appearance">True</property>
|
||||||
|
<property name="related_action">play</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</object>
|
</object>
|
||||||
|
@ -357,6 +357,40 @@
|
||||||
<object class="GtkVBox" id="vbox2">
|
<object class="GtkVBox" id="vbox2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHBox" id="generic_duration">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="label4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<property name="xpad">12</property>
|
||||||
|
<property name="label" translatable="yes">Duration:</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="seconds">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="invisible_char">●</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkVBox" id="filesource_properties">
|
<object class="GtkVBox" id="filesource_properties">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -444,7 +478,7 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="position">0</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -540,7 +574,7 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="position">1</property>
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
@ -570,12 +604,14 @@
|
||||||
<object class="GtkTreeSelection" id="selection"/>
|
<object class="GtkTreeSelection" id="selection"/>
|
||||||
<object class="GtkSizeGroup" id="LabelSizeGroup">
|
<object class="GtkSizeGroup" id="LabelSizeGroup">
|
||||||
<widgets>
|
<widgets>
|
||||||
|
<widget name="label4"/>
|
||||||
<widget name="label3"/>
|
<widget name="label3"/>
|
||||||
<widget name="label2"/>
|
<widget name="label2"/>
|
||||||
<widget name="label_inpoint"/>
|
<widget name="label_inpoint"/>
|
||||||
<widget name="label_duration"/>
|
<widget name="label_duration"/>
|
||||||
<widget name="label_duration"/>
|
<widget name="label_duration"/>
|
||||||
<widget name="label_inpoint"/>
|
<widget name="label_inpoint"/>
|
||||||
|
<widget name="label4"/>
|
||||||
</widgets>
|
</widgets>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkAction" id="delete">
|
<object class="GtkAction" id="delete">
|
||||||
|
|
Loading…
Reference in a new issue