Add a new animated xed-paned

This replaces the GtkPaned we currently use and opens and closes the panes using
an animation.
This commit is contained in:
JosephMcc 2017-03-17 00:09:00 -07:00
parent 331e0e5824
commit c16232ee20
7 changed files with 374 additions and 17 deletions

View File

@ -44,6 +44,7 @@ NOINST_H_FILES = \
xed-encodings-dialog.h \
xed-history-entry.h \
xed-io-error-info-bar.h \
xed-paned.h \
xed-plugins-engine.h \
xed-preferences-dialog.h \
xed-print-job.h \
@ -119,6 +120,7 @@ libxed_c_files = \
xed-message-type.c \
xed-message.c \
xed-notebook.c \
xed-paned.c \
xed-panel.c \
xed-plugins-engine.c \
xed-preferences-dialog.c \

View File

@ -40,6 +40,7 @@
#include "xed-debug.h"
#include "xed-window.h"
#include "xed-window-private.h"
#include "xed-paned.h"
void
@ -80,21 +81,24 @@ _xed_cmd_view_show_side_pane (GtkAction *action,
{
gboolean visible;
XedPanel *panel;
XedPaned *paned;
xed_debug (DEBUG_COMMANDS);
visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
panel = xed_window_get_side_panel (window);
paned = _xed_window_get_hpaned (window);
if (visible)
{
gtk_widget_show (GTK_WIDGET (panel));
gtk_widget_show (GTK_WIDGET (panel));
xed_paned_open (paned, 1, _xed_window_get_side_panel_size (window));
gtk_widget_grab_focus (GTK_WIDGET (panel));
}
else
{
gtk_widget_hide (GTK_WIDGET (panel));
xed_paned_close (paned, 1);
}
}
@ -104,21 +108,31 @@ _xed_cmd_view_show_bottom_pane (GtkAction *action,
{
gboolean visible;
XedPanel *panel;
XedPaned *paned;
xed_debug (DEBUG_COMMANDS);
visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
panel = xed_window_get_bottom_panel (window);
paned = _xed_window_get_vpaned (window);
if (visible)
{
gint position;
gint panel_size;
gint paned_size;
panel_size = _xed_window_get_bottom_panel_size (window);
g_object_get (G_OBJECT (paned), "max-position", &paned_size, NULL);
position = paned_size - panel_size;
gtk_widget_show (GTK_WIDGET (panel));
xed_paned_open (paned, 2, position);
gtk_widget_grab_focus (GTK_WIDGET (panel));
}
else
{
gtk_widget_hide (GTK_WIDGET (panel));
xed_paned_close (paned, 2);
}
}

266
xed/xed-paned.c Normal file
View File

@ -0,0 +1,266 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "xed-paned.h"
#define ANIMATION_TIME 125
struct _XedPanedPrivate
{
gint start_pos;
gint current_pos;
gint target_pos;
gint64 start_time;
gint64 end_time;
guint tick_id;
gboolean animating;
gboolean show_child;
gboolean is_vertical;
gint pane_number;
};
G_DEFINE_TYPE_WITH_PRIVATE (XedPaned, xed_paned, GTK_TYPE_PANED)
static void
xed_paned_dispose (GObject *object)
{
XedPaned *paned = XED_PANED (object);
if (paned->priv->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (paned), paned->priv->tick_id);
}
paned->priv->tick_id = 0;
G_OBJECT_CLASS (xed_paned_parent_class)->dispose (object);
}
static void
xed_paned_class_init (XedPanedClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = xed_paned_dispose;
}
static void
xed_paned_init (XedPaned *paned)
{
paned->priv = xed_paned_get_instance_private (paned);
paned->priv->animating = FALSE;
}
GtkWidget *
xed_paned_new (GtkOrientation orientation)
{
return GTK_WIDGET (g_object_new (XED_TYPE_PANED,
"orientation", orientation,
NULL));
}
static void
animate_step (XedPaned *paned,
gint64 now)
{
gdouble t;
gint difference;
if ((paned->priv->show_child && paned->priv->pane_number == 1) ||
(!paned->priv->show_child && paned->priv->pane_number == 2))
{
difference = paned->priv->target_pos - paned->priv->start_pos;
if (now < paned->priv->end_time)
{
t = ((gdouble) (now - paned->priv->start_time) / (gdouble) (paned->priv->end_time - paned->priv->start_time));
}
else
{
t = 1.0;
}
paned->priv->current_pos = paned->priv->start_pos + (difference * t);
}
else
{
difference = paned->priv->start_pos - paned->priv->target_pos;
if (now < paned->priv->end_time)
{
t = ((gdouble) (now - paned->priv->start_time) / (gdouble) (paned->priv->end_time - paned->priv->start_time));
}
else
{
t = 1.0;
}
paned->priv->current_pos = paned->priv->start_pos - (difference * t);
}
gtk_paned_set_position (GTK_PANED (paned), paned->priv->current_pos);
gtk_widget_queue_draw (GTK_WIDGET (paned));
}
static gboolean
animate_cb (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
XedPaned *paned = XED_PANED (widget);
gint64 now;
now = gdk_frame_clock_get_frame_time (frame_clock);
animate_step (paned, now);
if (paned->priv->current_pos == paned->priv->target_pos)
{
paned->priv->tick_id = 0;
if (!paned->priv->show_child)
{
if (paned->priv->pane_number == 1)
{
gtk_widget_hide (gtk_paned_get_child1 (GTK_PANED (paned)));
}
else
{
gtk_widget_hide (gtk_paned_get_child2 (GTK_PANED (paned)));
}
}
paned->priv->animating = FALSE;
return G_SOURCE_REMOVE;
}
return G_SOURCE_CONTINUE;
}
static void
calculate_target_postion (XedPaned *paned,
gint target_position)
{
if (paned->priv->show_child)
{
if (target_position < 0)
{
paned->priv->target_pos = 0;
}
else
{
paned->priv->target_pos = target_position;
}
}
else
{
if (paned->priv->pane_number == 1)
{
paned->priv->target_pos = 0;
}
else
{
gint max_pos;
g_object_get (G_OBJECT (paned), "max-position", &max_pos, NULL);
paned->priv->target_pos = max_pos;
}
}
}
static void
calculate_start_position (XedPaned *paned)
{
if (paned->priv->show_child && paned->priv->pane_number == 1)
{
paned->priv->start_pos = 0;
}
else if (paned->priv->show_child && paned->priv->pane_number == 2)
{
gint max_pos;
g_object_get (G_OBJECT (paned), "max-position", &max_pos, NULL);
paned->priv->start_pos = max_pos;
}
else if (paned->priv->pane_number == 1 || paned->priv->pane_number == 2)
{
paned->priv->start_pos = gtk_paned_get_position (GTK_PANED (paned));
}
paned->priv->current_pos = paned->priv->start_pos;
}
static void
setup_animation (XedPaned *paned,
gint target_position)
{
if (!gtk_widget_get_mapped (GTK_WIDGET (paned)))
{
return;
}
if (gtk_orientable_get_orientation (GTK_ORIENTABLE (paned)) == GTK_ORIENTATION_HORIZONTAL)
{
paned->priv->is_vertical = FALSE;
}
else
{
paned->priv->is_vertical = TRUE;
}
calculate_start_position (paned);
calculate_target_postion (paned, target_position);
paned->priv->start_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (GTK_WIDGET (paned)));
paned->priv->end_time = paned->priv->start_time + (ANIMATION_TIME * 1000);
if (paned->priv->tick_id == 0)
{
paned->priv->animating = TRUE;
paned->priv->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (paned),
animate_cb,
NULL,
NULL);
}
if (paned->priv->show_child)
{
gtk_widget_show (gtk_paned_get_child1 (GTK_PANED (paned)));
}
animate_step (paned, paned->priv->start_time);
}
void
xed_paned_close (XedPaned *paned,
gint pane_number)
{
g_return_if_fail (XED_IS_PANED (paned));
g_return_if_fail (pane_number == 1 || pane_number == 2);
paned->priv->show_child = FALSE;
paned->priv->pane_number = pane_number;
setup_animation (paned, -1);
}
void
xed_paned_open (XedPaned *paned,
gint pane_number,
gint target_position)
{
g_return_if_fail (XED_IS_PANED (paned));
g_return_if_fail (pane_number == 1 || pane_number == 2);
paned->priv->show_child = TRUE;
paned->priv->pane_number = pane_number;
setup_animation (paned, target_position);
}
gboolean
xed_paned_get_is_animating (XedPaned *paned)
{
return paned->priv->animating;
}

46
xed/xed-paned.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef __XED_PANED_H__
#define __XED_PANED_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define XED_TYPE_PANED (xed_paned_get_type ())
#define XED_PANED(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XED_TYPE_PANED, XedPaned))
#define XED_PANED_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), XED_TYPE_PANED, XedPanedClass))
#define XED_IS_PANED(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XED_TYPE_PANED))
#define XED_IS_PANED_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), XED_TYPE_PANED))
#define XED_PANED_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), XED_TYPE_PANED, XedPanedClass))
typedef struct _XedPaned XedPaned;
typedef struct _XedPanedPrivate XedPanedPrivate;
typedef struct _XedPanedClass XedPanedClass;
struct _XedPaned
{
GtkPaned parent;
/* <private/> */
XedPanedPrivate *priv;
};
struct _XedPanedClass
{
GtkPanedClass parent_class;
};
GType xed_paned_get_type (void) G_GNUC_CONST;
GtkWidget *xed_paned_new (GtkOrientation orientation);
void xed_paned_close (XedPaned *paned,
gint pane_number);
void xed_paned_open (XedPaned *paned,
gint pane_number,
gint pos);
gboolean xed_paned_get_is_animating (XedPaned *paned);
G_END_DECLS
#endif /* __XED_PANED_H__ */

View File

@ -132,12 +132,6 @@ xed_panel_set_property (GObject *object,
}
}
static void
xed_panel_close (XedPanel *panel)
{
gtk_widget_hide (GTK_WIDGET (panel));
}
static void
xed_panel_focus_document (XedPanel *panel)
{
@ -257,7 +251,6 @@ xed_panel_class_init (XedPanelClass *klass)
widget_class->size_allocate = xed_panel_size_allocate;
widget_class->grab_focus = xed_panel_grab_focus;
klass->close = xed_panel_close;
klass->focus_document = xed_panel_focus_document;
g_object_class_install_property (object_class,

View File

@ -3173,7 +3173,10 @@ side_panel_size_allocate (GtkWidget *widget,
GtkAllocation *allocation,
XedWindow *window)
{
window->priv->side_panel_size = allocation->width;
if (!xed_paned_get_is_animating (window->priv->hpaned))
{
window->priv->side_panel_size = allocation->width;
}
}
static void
@ -3181,7 +3184,10 @@ bottom_panel_size_allocate (GtkWidget *widget,
GtkAllocation *allocation,
XedWindow *window)
{
window->priv->bottom_panel_size = allocation->height;
if (!xed_paned_get_is_animating (window->priv->vpaned))
{
window->priv->bottom_panel_size = allocation->height;
}
}
static void
@ -3256,7 +3262,7 @@ create_side_panel (XedWindow *window)
window->priv->side_panel = xed_panel_new (GTK_ORIENTATION_VERTICAL);
gtk_paned_pack1 (GTK_PANED (window->priv->hpaned), window->priv->side_panel, FALSE, FALSE);
gtk_paned_pack1 (GTK_PANED (window->priv->hpaned), window->priv->side_panel, FALSE, TRUE);
g_signal_connect_after (window->priv->side_panel, "show", G_CALLBACK (side_panel_visibility_changed), window);
g_signal_connect_after (window->priv->side_panel, "hide", G_CALLBACK (side_panel_visibility_changed), window);
@ -3299,7 +3305,7 @@ bottom_panel_item_removed (XedPanel *panel,
{
GtkAction *action;
gtk_widget_hide (GTK_WIDGET (panel));
xed_paned_close (window->priv->vpaned, 2);
gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->bottom_pane_button_revealer), FALSE);
action = gtk_action_group_get_action (window->priv->panes_action_group, "ViewBottomPane");
gtk_action_set_sensitive (action, FALSE);
@ -3335,7 +3341,7 @@ create_bottom_panel (XedWindow *window)
{
xed_debug (DEBUG_WINDOW);
window->priv->bottom_panel = xed_panel_new (GTK_ORIENTATION_HORIZONTAL);
gtk_paned_pack2 (GTK_PANED (window->priv->vpaned), window->priv->bottom_panel, FALSE, FALSE);
gtk_paned_pack2 (GTK_PANED (window->priv->vpaned), window->priv->bottom_panel, FALSE, TRUE);
g_signal_connect_after(window->priv->bottom_panel, "show", G_CALLBACK (bottom_panel_visibility_changed), window);
g_signal_connect_after(window->priv->bottom_panel, "hide", G_CALLBACK (bottom_panel_visibility_changed), window);
}
@ -3539,10 +3545,10 @@ xed_window_init (XedWindow *window)
/* Add the main area */
xed_debug_message (DEBUG_WINDOW, "Add main area");
window->priv->hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
window->priv->hpaned = xed_paned_new (GTK_ORIENTATION_HORIZONTAL);
gtk_box_pack_start (GTK_BOX (main_box), window->priv->hpaned, TRUE, TRUE, 0);
window->priv->vpaned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
window->priv->vpaned = xed_paned_new (GTK_ORIENTATION_VERTICAL);
gtk_paned_pack2 (GTK_PANED (window->priv->hpaned), window->priv->vpaned, TRUE, FALSE);
xed_debug_message (DEBUG_WINDOW, "Create xed notebook");
@ -4339,3 +4345,27 @@ _xed_window_get_default_size (gint *width,
*width = XED_WINDOW_DEFAULT_WIDTH;
*height = XED_WINDOW_DEFAULT_HEIGHT;
}
XedPaned *
_xed_window_get_hpaned (XedWindow *window)
{
return XED_PANED (window->priv->hpaned);
}
XedPaned *
_xed_window_get_vpaned (XedWindow *window)
{
return XED_PANED (window->priv->vpaned);
}
gint
_xed_window_get_side_panel_size (XedWindow *window)
{
return window->priv->side_panel_size;
}
gint
_xed_window_get_bottom_panel_size (XedWindow *window)
{
return window->priv->bottom_panel_size;
}

View File

@ -6,6 +6,7 @@
#include <xed/xed-tab.h>
#include <xed/xed-panel.h>
#include <xed/xed-message-bus.h>
#include <xed/xed-paned.h>
G_BEGIN_DECLS
@ -106,6 +107,11 @@ void _xed_recent_add (XedWindow *window, GFile *location, const gchar *mime);
void _xed_recent_remove (XedWindow *window, GFile *location);
void _xed_window_get_default_size (gint *width, gint *height);
gint _xed_window_get_side_panel_size (XedWindow *window);
gint _xed_window_get_bottom_panel_size (XedWindow *window);
XedPaned *_xed_window_get_hpaned (XedWindow *window);
XedPaned *_xed_window_get_vpaned (XedWindow *window);
G_END_DECLS