Commit e2764cdf authored by Alexandre Savard's avatar Alexandre Savard
Browse files

#10304 Cleanup mainwindow creation code, wrap playback slider inside new widget

parent 7da129f5
......@@ -29,6 +29,7 @@ sflphone_client_gnome_SOURCES = \
eel-gconf-extensions.c \
shortcuts.c \
str_utils.c \
seekslider.c \
gtk2_wrappers.c
noinst_HEADERS = actions.h sflnotify.h mainwindow.h dialpad.h codeclist.h \
......
......@@ -427,10 +427,7 @@ update_playback_scale_cb(DBusGProxy *proxy UNUSED, const gchar *callid, guint va
guint size = (value & SIZE_MASK);
guint position = (value & POSITION_MASK);
// DEBUG("Playback scale update position: %d, size: %d", position << 8, size >> 16);
// DEBUG("Playback scale update value: %d, sizeof guint: %d", value, sizeof(guint));
update_playback_scale(position, size >> 16);
main_window_update_playback_scale(position, size >> 16);
}
static void
......
......@@ -52,6 +52,7 @@
#include "unused.h"
#include "config/audioconf.h"
#include "str_utils.h"
#include "seekslider.h"
#include "eel-gconf-extensions.h"
......@@ -71,13 +72,11 @@ static GtkWidget *dialpad;
static GtkWidget *speaker_control;
static GtkWidget *mic_control;
static GtkWidget *statusBar;
static GtkWidget *hscale;
static gboolean can_update_scale = TRUE;
static GtkWidget *seekslider = NULL;
static gchar *status_current_message;
static gboolean focus_is_on_searchbar;
static gboolean focus_is_on_searchbar = FALSE;
void
focus_on_searchbar_out()
......@@ -107,53 +106,6 @@ static gboolean window_configure_cb(GtkWidget *win UNUSED, GdkEventConfigure *ev
return FALSE;
}
gboolean
on_playback_scale_value_changed_cb(GtkRange *range, GtkScrollType scroll, gdouble value, gpointer user_data)
{
dbus_set_record_playback_seek(value);
return FALSE;
}
gboolean
on_playback_scale_pressed_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
if(event->button == 1)
event->button = 2;
can_update_scale = FALSE;
return FALSE;
}
gboolean
on_playback_scale_released_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
if(event->button == 1)
event->button = 2;
can_update_scale = TRUE;
return FALSE;
}
gboolean
on_playback_scale_moved_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
return FALSE;
}
gboolean
on_playback_scale_scrolled_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
DEBUG("on_playback_scale_scrolled_cb");
return TRUE;
}
/**
* Minimize the main window.
*/
......@@ -229,8 +181,6 @@ on_key_released(GtkWidget *widget UNUSED, GdkEventKey *event, gpointer user_data
void
create_main_window()
{
focus_is_on_searchbar = FALSE;
// Get configuration stored in gconf
int width = eel_gconf_get_integer(CONF_MAIN_WINDOW_WIDTH);
int height = eel_gconf_get_integer(CONF_MAIN_WINDOW_HEIGHT);
......@@ -238,7 +188,9 @@ create_main_window()
int position_y = eel_gconf_get_integer(CONF_MAIN_WINDOW_POSITION_Y);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(window), 0);
gtk_window_set_title(GTK_WINDOW(window), "SFLphone VoIP Client");
gtk_window_set_default_size(GTK_WINDOW(window), width, height);
struct stat st;
......@@ -247,6 +199,7 @@ create_main_window()
gtk_window_set_default_icon_from_file(LOGO, NULL);
gtk_window_set_position(GTK_WINDOW(window) , GTK_WIN_POS_MOUSE);
gtk_widget_set_name(window, "mainwindow");
/* Connect the destroy event of the window with our on_destroy function
* When the window is about to be destroyed we get a notificaiton and
......@@ -261,7 +214,6 @@ create_main_window()
g_signal_connect_object(G_OBJECT(window), "configure-event",
G_CALLBACK(window_configure_cb), NULL, 0);
gtk_widget_set_name(window, "mainwindow");
ui_manager = uimanager_new();
if (!ui_manager) {
......@@ -270,82 +222,36 @@ create_main_window()
}
/* Create an accel group for window's shortcuts */
gtk_window_add_accel_group(GTK_WINDOW(window),
gtk_ui_manager_get_accel_group(ui_manager));
gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(ui_manager));
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0 /*spacing*/);
/* Populate the main window */
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
gtk_box_set_spacing(GTK_BOX(vbox), 0);
subvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5 /*spacing*/);
subvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_box_set_homogeneous(GTK_BOX(subvbox), FALSE);
gtk_box_set_spacing(GTK_BOX(vbox), 0);
GtkWidget *widget = create_menus(ui_manager);
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE /*expand*/, TRUE /*fill*/,
0 /*padding*/);
if(widget == NULL)
WARN("Error could not create widget\n");
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
widget = create_toolbar_actions(ui_manager);
// Do not override GNOME user settings
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE /*expand*/, TRUE /*fill*/,
0 /*padding*/);
gdouble init_value = 0.0;
gdouble min_value = 0.0;
gdouble max_value = 100.0;
gdouble stepincrement = 1.0;
gdouble pageincrement = 1.0;
gdouble pagesize = 1.0;
GtkAdjustment *adjustment = gtk_adjustment_new(init_value, min_value, max_value, stepincrement, pageincrement, pagesize);
if(adjustment == NULL) {
WARN("Invalid adjustment value for horizontal scale");
}
hscale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adjustment);
if(hscale == NULL) {
WARN("Could not create new horizontal scale");
}
g_signal_connect(G_OBJECT(hscale), "change-value",
G_CALLBACK(on_playback_scale_value_changed_cb), NULL);
g_signal_connect_object(G_OBJECT (hscale), "button-press-event",
G_CALLBACK (on_playback_scale_pressed_cb), NULL, 0);
g_signal_connect_object(G_OBJECT (hscale), "button-release-event",
G_CALLBACK (on_playback_scale_released_cb), NULL, 0);
g_signal_connect_object(G_OBJECT (hscale), "motion-notify-event",
G_CALLBACK (on_playback_scale_moved_cb), NULL, 0);
// g_signal_connect_object (G_OBJECT (hscale), "value_changed",
// G_CALLBACK (on_playback_scale_changed_cb), NULL);
g_signal_connect_object (G_OBJECT (hscale), "scroll-event",
G_CALLBACK (on_playback_scale_scrolled_cb), NULL, 0);
gfloat xalign = 0.0f;
gfloat yalign = 0.0f;
gfloat xscale = 1.0f;
gfloat yscale = 0.0f;
GtkWidget *align = gtk_alignment_new(xalign, yalign, xscale, yscale);
gtk_container_add(GTK_CONTAINER(align), hscale);
if(widget == NULL)
WARN("Error could not create widget\n");
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(align), TRUE, TRUE, 0);
seekslider = GTK_WIDGET(sfl_seekslider_new());
if(seekslider == NULL)
WARN("Error could not create widget\n");
gtk_box_pack_start(GTK_BOX(vbox), seekslider, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), current_calls_tab->tree, TRUE /*expand*/,
TRUE /*fill*/, 0 /*padding*/);
gtk_box_pack_start(GTK_BOX(vbox), history_tab->tree, TRUE /*expand*/,
TRUE /*fill*/, 0 /*padding*/);
gtk_box_pack_start(GTK_BOX(vbox), contacts_tab->tree, TRUE /*expand*/,
TRUE /*fill*/, 0 /*padding*/);
/* Add tree views */
gtk_box_pack_start(GTK_BOX(vbox), current_calls_tab->tree, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), history_tab->tree, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), contacts_tab->tree, TRUE, TRUE, 0);
g_signal_connect_object(G_OBJECT(window), "configure-event",
G_CALLBACK(window_configure_cb), NULL, 0);
gtk_box_pack_start(GTK_BOX(vbox), subvbox, FALSE /*expand*/,
FALSE /*fill*/, 0 /*padding*/);
gtk_box_pack_start(GTK_BOX(vbox), subvbox, FALSE, FALSE, 0);
speaker_control = create_slider("speaker");
mic_control = create_slider("mic");
......@@ -353,10 +259,8 @@ create_main_window()
g_object_ref(mic_control);
if (SHOW_VOLUME) {
gtk_box_pack_end(GTK_BOX(subvbox), speaker_control, FALSE /*expand*/,
TRUE /*fill*/, 0 /*padding*/);
gtk_box_pack_end(GTK_BOX(subvbox), mic_control, FALSE /*expand*/,
TRUE /*fill*/, 0 /*padding*/);
gtk_box_pack_end(GTK_BOX(subvbox), speaker_control, FALSE, TRUE, 0);
gtk_box_pack_end(GTK_BOX(subvbox), mic_control, FALSE, TRUE, 0);
gtk_widget_show_all(speaker_control);
gtk_widget_show_all(mic_control);
} else {
......@@ -366,14 +270,17 @@ create_main_window()
if (eel_gconf_get_boolean(CONF_SHOW_DIALPAD)) {
dialpad = create_dialpad();
gtk_box_pack_end(GTK_BOX(subvbox), dialpad, FALSE /*expand*/, TRUE /*fill*/, 0 /*padding*/);
gtk_box_pack_end(GTK_BOX(subvbox), dialpad, FALSE, TRUE, 0);
gtk_widget_show_all(dialpad);
}
/* Status bar */
statusBar = gtk_statusbar_new();
gtk_box_pack_start(GTK_BOX(vbox), statusBar, FALSE /*expand*/,
TRUE /*fill*/, 0 /*padding*/);
if(statusBar == NULL)
WARN("Error could not create widget\n");
gtk_box_pack_start(GTK_BOX(vbox), statusBar, FALSE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
/* make sure that everything, window and label, are visible */
......@@ -385,6 +292,9 @@ create_main_window()
/* dont't show the contact list */
gtk_widget_hide(contacts_tab->tree);
/* show playback scale only if a recorded call is selected */
gtk_widget_hide(seekslider);
/* don't show waiting layer */
gtk_widget_hide(waitingLayer);
......@@ -577,11 +487,20 @@ main_window_confirm_go_clear(callable_obj_t * c)
add_error_dialog(GTK_WIDGET(mini_dialog));
}
void update_playback_scale(guint current, guint size)
void
main_window_update_playback_scale(guint current, guint size)
{
gdouble val = ((gdouble) current / (gdouble) size) * 100.0;
sfl_seekslider_update_scale(SFL_SEEKSLIDER(seekslider), current, size);
}
if(can_update_scale == TRUE) {
gtk_range_set_value(GTK_RANGE(hscale), val);
}
void
main_window_show_playback_scale()
{
gtk_widget_show(seekslider);
}
void
main_window_hide_playback_scale()
{
gtk_widget_hide(seekslider);
}
......@@ -103,5 +103,20 @@ void main_window_confirm_go_clear (callable_obj_t * c);
void focus_on_searchbar_out();
void focus_on_searchbar_in();
void update_playback_scale(guint current, guint size);
/**
* Given the current position and the full length of the file, update the playback position
* if the size is 0 or if the current value is larger than the size, the cursor position
* is moved at the end of the scale.
*/
void main_window_update_playback_scale(guint current, guint size);
/**
* Show the playback scale, (should occur if the user selected an history entry witch has been recorded)
*/
void main_window_show_playback_scale();
/**
* Hide the playback scale
*/
void main_window_hide_playback_scale();
#endif
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2012 Savoir-Faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The Rhythmbox authors hereby grant permission for non-GPL compatible
* GStreamer plugins to be used and distributed together with GStreamer
* and Rhythmbox. This permission is above and beyond the permissions granted
* by the GPL license by which Rhythmbox is covered. If you modify this code
* you may extend this exception to your version of the code, but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
// #include <config.h>
#include <gtk/gtk.h>
#include "seekslider.h"
#include "dbus.h"
#include "logger.h"
#include "config.h"
/**
* SECTION:sfl-seekslider
* @short_description: playback area widgetry
*
* The SFLSeekSlider widget displays information about the current playing track
* (title, album, artist), the elapsed or remaining playback time, and a
* position slider indicating the playback position. It translates slider
* move and drag events into seek requests for the player backend.
*
* For shoutcast-style streams, the title/artist/album display is supplemented
* by metadata extracted from the stream. See #RBStreamingSource for more information
* on how the metadata is reported.
*/
#define SEEKSLIDER_INIT_VALUE 0.0
#define SEEKSLIDER_MIN_VALUE 0.0
#define SEEKSLIDER_MAX_VALUE 100.0
#define SEEKSLIDER_STEPINCREMENT 1.0
#define SEEKSLIDER_PAGEINCREMENT 1.0
#define SEEKSLIDER_PAGESIZE 1.0
static void sfl_seekslider_class_init (SFLSeekSliderClass *klass);
static void sfl_seekslider_init (SFLSeekSlider *seekslider);
static void sfl_seekslider_finalize (GObject *object);
static void sfl_seekslider_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void sfl_seekslider_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static gboolean on_playback_scale_value_changed_cb(GtkRange *range, GtkScrollType scroll, gdouble value, gpointer user_data);
static gboolean on_playback_scale_pressed_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data);
static gboolean on_playback_scale_released_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data);
static gboolean on_playback_scale_moved_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data);
static gboolean on_playback_scale_scrolled_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data);
struct SFLSeekSliderPrivate
{
GtkWidget *hscale;
gboolean can_update_scale;
};
enum
{
PROP_0,
};
G_DEFINE_TYPE (SFLSeekSlider, sfl_seekslider, GTK_TYPE_HBOX)
static void
sfl_seekslider_class_init (SFLSeekSliderClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = sfl_seekslider_finalize;
object_class->set_property = sfl_seekslider_set_property;
object_class->get_property = sfl_seekslider_get_property;
g_type_class_add_private (klass, sizeof (SFLSeekSliderPrivate));
}
static void
sfl_seekslider_init (SFLSeekSlider *seekslider)
{
seekslider->priv = G_TYPE_INSTANCE_GET_PRIVATE (seekslider, SFL_TYPE_SEEKSLIDER, SFLSeekSliderPrivate);
gdouble init_value = SEEKSLIDER_INIT_VALUE;
gdouble min_value = SEEKSLIDER_MIN_VALUE;
gdouble max_value = SEEKSLIDER_MAX_VALUE;
gdouble stepincrement = SEEKSLIDER_STEPINCREMENT;
gdouble pageincrement = SEEKSLIDER_PAGEINCREMENT;
gdouble pagesize = SEEKSLIDER_PAGESIZE;
GtkAdjustment *adjustment = gtk_adjustment_new(init_value, min_value, max_value, stepincrement, pageincrement, pagesize);
if(adjustment == NULL) {
WARN("Invalid adjustment value for horizontal scale");
}
seekslider->priv->hscale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adjustment);
if(seekslider->priv->hscale == NULL) {
WARN("Could not create new horizontal scale");
}
g_signal_connect(G_OBJECT(seekslider->priv->hscale), "change-value",
G_CALLBACK(on_playback_scale_value_changed_cb), seekslider);
g_signal_connect_object(G_OBJECT (seekslider->priv->hscale), "button-press-event",
G_CALLBACK (on_playback_scale_pressed_cb), seekslider, 0);
g_signal_connect_object(G_OBJECT (seekslider->priv->hscale), "button-release-event",
G_CALLBACK (on_playback_scale_released_cb), seekslider, 0);
g_signal_connect_object(G_OBJECT (seekslider->priv->hscale), "motion-notify-event",
G_CALLBACK (on_playback_scale_moved_cb), seekslider, 0);
g_signal_connect_object (G_OBJECT (seekslider->priv->hscale), "scroll-event",
G_CALLBACK (on_playback_scale_scrolled_cb), seekslider, 0);
g_object_set(G_OBJECT(seekslider->priv->hscale), "draw-value", FALSE, NULL);
gtk_widget_show (seekslider->priv->hscale);
gtk_box_pack_start(GTK_BOX(&seekslider->parent), seekslider->priv->hscale, TRUE, TRUE, 0);
seekslider->priv->can_update_scale = TRUE;
}
static void
sfl_seekslider_finalize (GObject *object)
{
SFLSeekSlider *seekslider;
g_return_if_fail (object != NULL);
g_return_if_fail (SFL_IS_SEEKSLIDER (object));
seekslider = SFL_SEEKSLIDER (object);
g_return_if_fail (seekslider->priv != NULL);
G_OBJECT_CLASS (sfl_seekslider_parent_class)->finalize (object);
}
static void
sfl_seekslider_set_property (GObject *object, guint prop_id, const GValue *value G_GNUC_UNUSED, GParamSpec *pspec)
{
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
sfl_seekslider_get_property (GObject *object, guint prop_id, GValue *value G_GNUC_UNUSED, GParamSpec *pspec)
{
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* sfl_seekslider_new:
* @shell_player: the #RBShellPlayer instance
* @db: the #RhythmDB instance
*
* Creates a new seekslider widget.
*
* Return value: the seekslider widget
*/
SFLSeekSlider *
sfl_seekslider_new ()
{
SFLSeekSlider *seekslider;
seekslider = SFL_SEEKSLIDER (g_object_new (SFL_TYPE_SEEKSLIDER, NULL));
g_return_val_if_fail (seekslider->priv != NULL, NULL);
return seekslider;
}
static gboolean
on_playback_scale_value_changed_cb(GtkRange *range G_GNUC_UNUSED, GtkScrollType scroll G_GNUC_UNUSED, gdouble value, gpointer user_data G_GNUC_UNUSED)
{
dbus_set_record_playback_seek(value);
return FALSE;
}
static gboolean
on_playback_scale_pressed_cb(GtkWidget *widget G_GNUC_UNUSED, GdkEventButton *event, gpointer user_data)
{
if(event->button == 1)
event->button = 2;
SFLSeekSlider *seekslider = (SFLSeekSlider *)user_data;
seekslider->priv->can_update_scale = FALSE;
return FALSE;
}
static gboolean
on_playback_scale_released_cb(GtkWidget *widget G_GNUC_UNUSED, GdkEventButton *event, gpointer user_data)
{
if(event->button == 1)
event->button = 2;
SFLSeekSlider *seekslider = (SFLSeekSlider *)user_data;
seekslider->priv->can_update_scale = TRUE;
return FALSE;
}
static gboolean
on_playback_scale_moved_cb(GtkWidget *widget G_GNUC_UNUSED, GdkEvent *event G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
{
return FALSE;
}
static gboolean
on_playback_scale_scrolled_cb(GtkWidget *widget G_GNUC_UNUSED, GdkEvent *event G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
{
return TRUE;
}
void sfl_seekslider_update_scale(SFLSeekSlider *seekslider, guint current, guint size)
{
if(size == 0)
size = 1;
if(current > size)
current = size;
gdouble val = ((gdouble) current / (gdouble) size) * 100.0;
if(seekslider->priv->can_update_scale == TRUE) {
gtk_range_set_value(GTK_RANGE(seekslider->priv->hscale), val); }
}
/*
* Copyright (C) 2012 Savoir-Faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The Rhythmbox authors hereby grant permission for non-GPL compatible
* GStreamer plugins to be used and distributed together with GStreamer
* and Rhythmbox. This permission is above and beyond the permissions granted
* by the GPL license by which Rhythmbox is covered. If you modify this code
* you may extend this exception to your version of the code, but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef __SFL_SEEKSLIDER_H
#define __SFL_SEEKSLIDER_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define SFL_TYPE_SEEKSLIDER (sfl_seekslider_get_type ())
#define SFL_SEEKSLIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SFL_TYPE_SEEKSLIDER, SFLSeekSlider))
#define SFL_SEEKSLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SFL_TYPE_SEEKSLIDER, SFLSeekSliderClass))
#define SFL_IS_SEEKSLIDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SFL_TYPE_SEEKSLIDER))
#define SFL_IS_SEEKSLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SFL_TYPE_SEEKSLIDER))
#define SFL_SEEKSLIDER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SFL_TYPE_SEEKSLIDER, SFLSeekSliderClass))
typedef struct _SFLSeekSlider SFLSeekSlider;
typedef struct _SFLSeekSliderClass SFLSeekSliderClass;