aboutsummaryrefslogtreecommitdiff
path: root/lib/gtk-experiment-widgets
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2012-06-13 15:57:40 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2012-06-13 16:44:41 +0200
commit7f9099bf95de9c38fd6cf9d59326733e132fd761 (patch)
treee0a64f1033a550296dcfd7519cdef1270cbe838b /lib/gtk-experiment-widgets
parent68141b1fb33a1bf8497248e3d341d62487df2092 (diff)
downloadgtk-vlc-player-7f9099bf95de9c38fd6cf9d59326733e132fd761.tar.gz
implemented topdown (reverse) rendering of contributions
code has been refactored allowing for greater flexibility in rendering
Diffstat (limited to 'lib/gtk-experiment-widgets')
-rw-r--r--lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c1
-rw-r--r--lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h12
-rw-r--r--lib/gtk-experiment-widgets/gtk-experiment-transcript.c178
3 files changed, 141 insertions, 50 deletions
diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c b/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c
index 3604e3c..b14b770 100644
--- a/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c
+++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c
@@ -36,6 +36,7 @@
#include <gtk/gtk.h>
+#include "gtk-experiment-transcript.h"
#include "gtk-experiment-transcript-private.h"
#define FORMAT_REGEX_COMPILE_FLAGS (G_REGEX_CASELESS)
diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h b/lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h
index 98c689c..de03395 100644
--- a/lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h
+++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript-private.h
@@ -23,6 +23,13 @@
#ifndef __GTK_EXPERIMENT_TRANSCRIPT_PRIVATE_H
#define __GTK_EXPERIMENT_TRANSCRIPT_PRIVATE_H
+#include <glib.h>
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include <experiment-reader.h>
+
#include "gtk-experiment-transcript.h"
/** @private */
@@ -55,6 +62,11 @@ struct _GtkExperimentTranscriptPrivate {
GSList *alignment_group; /**< GtkRadioMenuItem group (owned by GTK) */
};
+/** @private */
+typedef gboolean (*GtkExperimentTranscriptContribRenderer)
+ (GtkExperimentTranscript *, ExperimentReaderContrib *,
+ gint64, gint64, gint *);
+
#define DEFAULT_WIDTH 100
#define DEFAULT_HEIGHT 200
diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript.c b/lib/gtk-experiment-widgets/gtk-experiment-transcript.c
index d722d94..2cfbf37 100644
--- a/lib/gtk-experiment-widgets/gtk-experiment-transcript.c
+++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript.c
@@ -31,10 +31,11 @@
#include <glib/gprintf.h>
#include <gdk/gdk.h>
-
#include <gtk/gtk.h>
+
#include <experiment-reader.h>
+#include "gtk-experiment-transcript.h"
#include "gtk-experiment-transcript-private.h"
static void gtk_experiment_transcript_class_init(GtkExperimentTranscriptClass *klass);
@@ -55,6 +56,20 @@ static void time_adj_on_value_changed(GtkAdjustment *adj, gpointer user_data);
static void gtk_experiment_transcript_reconfigure(GtkExperimentTranscript *trans);
+static gboolean configure_text_layout(GtkExperimentTranscript *trans,
+ ExperimentReaderContrib *contrib,
+ gint64 current_time,
+ gint y, gint last_contrib_y,
+ int *logical_height);
+static gboolean render_contribution_bottomup(GtkExperimentTranscript *trans,
+ ExperimentReaderContrib *contrib,
+ gint64 current_time, gint64 current_time_px,
+ gint *last_contrib_y);
+static gboolean render_contribution_topdown(GtkExperimentTranscript *trans,
+ ExperimentReaderContrib *contrib,
+ gint64 current_time, gint64 current_time_px,
+ gint *last_contrib_y);
+
static void state_changed(GtkWidget *widget, GtkStateType state);
static gboolean button_pressed(GtkWidget *widget, GdkEventButton *event);
static gboolean scrolled(GtkWidget *widget, GdkEventScroll *event);
@@ -400,6 +415,107 @@ gtk_experiment_transcript_reconfigure(GtkExperimentTranscript *trans)
gtk_experiment_transcript_text_layer_redraw(trans);
}
+static gboolean
+configure_text_layout(GtkExperimentTranscript *trans,
+ ExperimentReaderContrib *contrib,
+ gint64 current_time,
+ gint y, gint last_contrib_y,
+ int *logical_height)
+{
+ PangoAttrList *attrib_list;
+
+ if (contrib->start_time > current_time)
+ return FALSE;
+
+ attrib_list = pango_attr_list_new();
+
+ for (GSList *cur = trans->priv->formats; cur != NULL; cur = cur->next) {
+ GtkExperimentTranscriptFormat *fmt =
+ (GtkExperimentTranscriptFormat *)cur->data;
+
+ gtk_experiment_transcript_apply_format(fmt, contrib->text,
+ attrib_list);
+ }
+ gtk_experiment_transcript_apply_format(&trans->priv->interactive_format,
+ contrib->text, attrib_list);
+
+ pango_layout_set_attributes(trans->priv->layer_text_layout,
+ attrib_list);
+ pango_attr_list_unref(attrib_list);
+
+ pango_layout_set_text(trans->priv->layer_text_layout,
+ contrib->text, -1);
+
+ pango_layout_set_height(trans->priv->layer_text_layout,
+ last_contrib_y == -1
+ ? G_MAXINT
+ : ABS(last_contrib_y - y)*PANGO_SCALE);
+
+ pango_layout_get_pixel_size(trans->priv->layer_text_layout,
+ NULL, logical_height);
+
+ return TRUE;
+}
+
+static gboolean
+render_contribution_bottomup(GtkExperimentTranscript *trans,
+ ExperimentReaderContrib *contrib,
+ gint64 current_time, gint64 current_time_px,
+ gint *last_contrib_y)
+{
+ GtkWidget *widget = GTK_WIDGET(trans);
+
+ gint old_last_contrib_y = *last_contrib_y;
+ int logical_height;
+
+ *last_contrib_y = widget->allocation.height -
+ (current_time_px - TIME_TO_PX(contrib->start_time));
+
+ if (!configure_text_layout(trans, contrib, current_time,
+ *last_contrib_y, old_last_contrib_y,
+ &logical_height))
+ return TRUE;
+
+ if (*last_contrib_y + logical_height < 0)
+ return FALSE;
+
+ gdk_draw_layout(GDK_DRAWABLE(trans->priv->layer_text),
+ widget->style->text_gc[gtk_widget_get_state(widget)],
+ 0, *last_contrib_y,
+ trans->priv->layer_text_layout);
+
+ return *last_contrib_y > 0;
+}
+
+static gboolean
+render_contribution_topdown(GtkExperimentTranscript *trans,
+ ExperimentReaderContrib *contrib,
+ gint64 current_time, gint64 current_time_px,
+ gint *last_contrib_y)
+{
+ GtkWidget *widget = GTK_WIDGET(trans);
+
+ gint old_last_contrib_y = *last_contrib_y;
+ int logical_height;
+
+ *last_contrib_y = current_time_px - TIME_TO_PX(contrib->start_time);
+
+ if (!configure_text_layout(trans, contrib, current_time,
+ *last_contrib_y, old_last_contrib_y,
+ &logical_height))
+ return TRUE;
+
+ if (*last_contrib_y - logical_height > widget->allocation.height)
+ return FALSE;
+
+ gdk_draw_layout(GDK_DRAWABLE(trans->priv->layer_text),
+ widget->style->text_gc[gtk_widget_get_state(widget)],
+ 0, *last_contrib_y - logical_height,
+ trans->priv->layer_text_layout);
+
+ return *last_contrib_y < widget->allocation.height;
+}
+
/** @private */
void
gtk_experiment_transcript_text_layer_redraw(GtkExperimentTranscript *trans)
@@ -409,6 +525,8 @@ gtk_experiment_transcript_text_layer_redraw(GtkExperimentTranscript *trans)
gint64 current_time = 0, current_time_px;
gint last_contrib_y = -1;
+ GtkExperimentTranscriptContribRenderer renderer;
+
gdk_draw_rectangle(GDK_DRAWABLE(trans->priv->layer_text),
widget->style->bg_gc[gtk_widget_get_state(widget)],
TRUE,
@@ -423,12 +541,13 @@ gtk_experiment_transcript_text_layer_redraw(GtkExperimentTranscript *trans)
if (trans->priv->contribs == NULL)
return;
- /** @todo reverse mode */
-
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 = trans->reverse ? render_contribution_topdown
+ : render_contribution_bottomup;
+
for (GList *cur = experiment_reader_get_contribution_by_time(
trans->priv->contribs,
current_time);
@@ -437,54 +556,9 @@ gtk_experiment_transcript_text_layer_redraw(GtkExperimentTranscript *trans)
ExperimentReaderContrib *contrib = (ExperimentReaderContrib *)
cur->data;
- gint y = widget->allocation.height -
- (current_time_px - TIME_TO_PX(contrib->start_time));
- int logical_height;
-
- PangoAttrList *attrib_list;
-
- if (y >= widget->allocation.height) {
- last_contrib_y = y;
- continue;
- }
-
- attrib_list = pango_attr_list_new();
-
- for (GSList *cur = trans->priv->formats; cur != NULL; cur = cur->next) {
- GtkExperimentTranscriptFormat *fmt =
- (GtkExperimentTranscriptFormat *)cur->data;
-
- gtk_experiment_transcript_apply_format(fmt, contrib->text,
- attrib_list);
- }
- gtk_experiment_transcript_apply_format(&trans->priv->interactive_format,
- contrib->text, attrib_list);
-
- pango_layout_set_attributes(trans->priv->layer_text_layout,
- attrib_list);
- pango_attr_list_unref(attrib_list);
-
- pango_layout_set_text(trans->priv->layer_text_layout,
- contrib->text, -1);
-
- if (last_contrib_y == 1)
- pango_layout_set_height(trans->priv->layer_text_layout,
- G_MAXINT);
- else
- pango_layout_set_height(trans->priv->layer_text_layout,
- (last_contrib_y - y)*PANGO_SCALE);
-
- pango_layout_get_pixel_size(trans->priv->layer_text_layout,
- NULL, &logical_height);
- if (y + logical_height < 0)
- break;
-
- gdk_draw_layout(GDK_DRAWABLE(trans->priv->layer_text),
- widget->style->text_gc[gtk_widget_get_state(widget)],
- 0, y, trans->priv->layer_text_layout);
- if (y <= 0)
+ if (!renderer(trans, contrib, current_time, current_time_px,
+ &last_contrib_y))
break;
- last_contrib_y = y;
}
}
@@ -667,6 +741,10 @@ reverse_activated(GtkWidget *widget, gpointer data)
trans->reverse =
gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+
+ if (gtk_widget_get_realized(GTK_WIDGET(trans)) &&
+ trans->priv->layer_text != NULL)
+ gtk_experiment_transcript_text_layer_redraw(trans);
}
/*