diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h | 8 | ||||
-rw-r--r-- | lib/gtk-experiment-widgets/gtk-experiment-transcript.c | 96 | ||||
-rw-r--r-- | lib/gtk-experiment-widgets/gtk-experiment-transcript.h | 3 |
4 files changed, 105 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac index 6664eaf..96b7ccf 100644 --- a/configure.ac +++ b/configure.ac @@ -220,6 +220,8 @@ AC_DEFINE(GTK_VLC_PLAYER_TIME_ADJ_PAGE, [30000.], [VLC Player time adjustment pa AC_DEFINE(GTK_VLC_PLAYER_VOL_ADJ_STEP, [0.02], [VLC Player volume adjustment step increment]) AC_DEFINE(GTK_VLC_PLAYER_VOL_ADJ_PAGE, [0.], [VLC Player volume adjustment page increment]) +AC_DEFINE(GTK_EXPERIMENT_TRANSCRIPT_BACKDROP, [16], [Experiment Transcript backdrop area color change (percent)]) + AC_DEFINE(DEFAULT_QUICKOPEN_DIR, ["."], [Default directory for listing experiments]) AC_DEFINE(EXPERIMENT_MOVIE_FILTER, ["*.mp4;*.avi"], [Filters for (quick) opening movies]) AC_DEFINE(EXPERIMENT_TRANSCRIPT_EXT, ["xml"], [File extension of experiment transcripts]) diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h b/lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h index 3632cca..384566a 100644 --- a/lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h +++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h @@ -61,6 +61,11 @@ struct _GtkExperimentTranscriptPrivate { GdkPixmap *layer_text; PangoLayout *layer_text_layout; + struct _GtkExperimentTranscriptBackdropArea { + gint64 start; + gint64 end; + } backdrop; + GList *contribs; GSList *formats; GtkExperimentTranscriptFormat interactive_format; @@ -83,6 +88,9 @@ typedef gboolean (*GtkExperimentTranscriptContribRenderer) #define TIME_TO_PX(TIME) ((TIME)/(1000/PX_PER_SECOND)) #define PX_TO_TIME(PX) (((PX)*1000)/PX_PER_SECOND) +#define BACKDROP_VALUE \ + ((G_MAXUINT16*GTK_EXPERIMENT_TRANSCRIPT_BACKDROP)/100) + /** * @private * Unreference object given by variable, but only once. diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript.c b/lib/gtk-experiment-widgets/gtk-experiment-transcript.c index 312722f..e93398d 100644 --- a/lib/gtk-experiment-widgets/gtk-experiment-transcript.c +++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript.c @@ -69,6 +69,8 @@ static gboolean render_contribution_topdown(GtkExperimentTranscript *trans, ExperimentReaderContrib *contrib, gint64 current_time, gint64 current_time_px, gint *last_contrib_y); +static inline void render_backdrop_area(GtkExperimentTranscript *trans, + gint64 current_time_px); static void state_changed(GtkWidget *widget, GtkStateType state); static gboolean button_pressed(GtkWidget *widget, GdkEventButton *event); @@ -150,6 +152,8 @@ gtk_experiment_transcript_init(GtkExperimentTranscript *klass) pango_layout_set_wrap(klass->priv->layer_text_layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(klass->priv->layer_text_layout, PANGO_ELLIPSIZE_END); + klass->priv->backdrop.start = klass->priv->backdrop.end = -1; + klass->priv->contribs = NULL; klass->priv->formats = NULL; klass->priv->interactive_format.regexp = NULL; @@ -234,6 +238,8 @@ gtk_experiment_transcript_init(GtkExperimentTranscript *klass) gtk_menu_shell_append(GTK_MENU_SHELL(klass->priv->menu), klass->priv->menu_reverse_item); gtk_widget_show(klass->priv->menu_reverse_item); + + gtk_widget_set_can_focus(GTK_WIDGET(klass), TRUE); } /** @@ -519,6 +525,55 @@ render_contribution_topdown(GtkExperimentTranscript *trans, return *last_contrib_y < widget->allocation.height; } +static inline void +render_backdrop_area(GtkExperimentTranscript *trans, gint64 current_time_px) +{ + GtkWidget *widget = GTK_WIDGET(trans); + + gint y_start, y_end; + GdkColor color; + GdkColor *bg = &widget->style->bg[gtk_widget_get_state(widget)]; + + if (trans->priv->backdrop.start < 0 || + trans->priv->backdrop.end < 0) + return; + + if (gtk_experiment_transcript_get_reverse_mode(trans)) { + y_end = current_time_px - TIME_TO_PX(trans->priv->backdrop.start); + y_start = current_time_px - TIME_TO_PX(trans->priv->backdrop.end); + } else { + y_start = widget->allocation.height - + (current_time_px - TIME_TO_PX(trans->priv->backdrop.start)); + y_end = widget->allocation.height - + (current_time_px - TIME_TO_PX(trans->priv->backdrop.end)); + } + + if ((y_start < 0 && y_end < 0) || + (y_start > widget->allocation.height && + y_end > widget->allocation.height)) + return; + + y_start = CLAMP(y_start, 0, widget->allocation.height); + y_end = CLAMP(y_end, 0, widget->allocation.height); + + color.pixel = 0; + color.red = MAX((gint)bg->red - BACKDROP_VALUE, 0); + color.blue = MAX((gint)bg->blue - BACKDROP_VALUE, 0); + color.green = MAX((gint)bg->green - BACKDROP_VALUE, 0); + if (!color.red && !color.blue && !color.green) { + color.red = MIN((gint)bg->red + BACKDROP_VALUE, G_MAXUINT16); + color.blue = MIN((gint)bg->blue + BACKDROP_VALUE, G_MAXUINT16); + color.green = MIN((gint)bg->green + BACKDROP_VALUE, G_MAXUINT16); + } + gtk_widget_modify_fg(widget, gtk_widget_get_state(widget), &color); + + gdk_draw_rectangle(GDK_DRAWABLE(trans->priv->layer_text), + widget->style->fg_gc[gtk_widget_get_state(widget)], + TRUE, + 0, y_start, + widget->allocation.width, y_end - y_start); +} + /** @private */ void gtk_experiment_transcript_text_layer_redraw(GtkExperimentTranscript *trans) @@ -530,6 +585,13 @@ gtk_experiment_transcript_text_layer_redraw(GtkExperimentTranscript *trans) GtkExperimentTranscriptContribRenderer renderer; + if (trans->priv->time_adjustment != NULL) { + GtkAdjustment *adj = + GTK_ADJUSTMENT(trans->priv->time_adjustment); + current_time = (gint64)gtk_adjustment_get_value(adj); + } + current_time_px = TIME_TO_PX(current_time); + gdk_draw_rectangle(GDK_DRAWABLE(trans->priv->layer_text), widget->style->bg_gc[gtk_widget_get_state(widget)], TRUE, @@ -537,6 +599,8 @@ gtk_experiment_transcript_text_layer_redraw(GtkExperimentTranscript *trans) widget->allocation.width, widget->allocation.height); + render_backdrop_area(trans, current_time_px); + gtk_widget_queue_draw_area(widget, 0, 0, widget->allocation.width, widget->allocation.height); @@ -544,10 +608,6 @@ gtk_experiment_transcript_text_layer_redraw(GtkExperimentTranscript *trans) if (trans->priv->contribs == NULL) return; - if (trans->priv->time_adjustment != NULL) - current_time = (gint64)gtk_adjustment_get_value(GTK_ADJUSTMENT(trans->priv->time_adjustment)); - current_time_px = TIME_TO_PX(current_time); - renderer = gtk_experiment_transcript_get_reverse_mode(trans) ? render_contribution_topdown : render_contribution_bottomup; @@ -581,6 +641,8 @@ button_pressed(GtkWidget *widget, GdkEventButton *event) { GtkExperimentTranscript *trans = GTK_EXPERIMENT_TRANSCRIPT(widget); + gtk_widget_grab_focus(widget); + /* Ignore double-clicks and triple-clicks */ if (event->button != 3 || event->type != GDK_BUTTON_PRESS) return FALSE; @@ -830,6 +892,32 @@ gtk_experiment_transcript_load_filename(GtkExperimentTranscript *trans, } /** + * @brief Configure transcript's backdrop area + * + * Set or unset a highlighted area of the transcript by specifying start + * and end timepoints. The highlighted area is drawn with a 16% lighter or + * darker background color than the widgets current background color. + * + * @param trans Widget instance + * @param start Start time in milliseconds, or negative value (disable backdrop area) + * @param end End time in milliseconds, or negative value (disable backdrop area) + */ +void +gtk_experiment_transcript_set_backdrop_area(GtkExperimentTranscript *trans, + gint64 start, gint64 end) +{ + if (start > end) + start = end = -1; + + trans->priv->backdrop.start = start; + trans->priv->backdrop.end = end; + + if (gtk_widget_get_realized(GTK_WIDGET(trans)) && + trans->priv->layer_text != NULL) + gtk_experiment_transcript_text_layer_redraw(trans); +} + +/** * @brief Set or unset reverse (top-down) render mode * * The render mode defaults to bottom-up mode for new widget instances. diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript.h b/lib/gtk-experiment-widgets/gtk-experiment-transcript.h index fa36b0f..6615fd7 100644 --- a/lib/gtk-experiment-widgets/gtk-experiment-transcript.h +++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript.h @@ -112,6 +112,9 @@ gboolean gtk_experiment_transcript_load(GtkExperimentTranscript *trans, gboolean gtk_experiment_transcript_load_filename(GtkExperimentTranscript *trans, const gchar *filename); +void gtk_experiment_transcript_set_backdrop_area(GtkExperimentTranscript *trans, + gint64 start, gint64 end); + void gtk_experiment_transcript_set_reverse_mode(GtkExperimentTranscript *trans, gboolean reverse); gboolean gtk_experiment_transcript_get_reverse_mode(GtkExperimentTranscript *trans); |