G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIONABLE,
gtk_switch_actionable_iface_init))
+static gboolean
+is_right_side (GtkWidget *widget,
+ gboolean active)
+{
+ if (_gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ return active;
+ else
+ return !active;
+}
+
static void
gtk_switch_end_toggle_animation (GtkSwitch *self)
{
gpointer user_data)
{
GtkSwitch *self = GTK_SWITCH (widget);
+ double progress;
gtk_progress_tracker_advance_frame (&self->tracker,
gdk_frame_clock_get_frame_time (clock));
if (gtk_progress_tracker_get_state (&self->tracker) != GTK_PROGRESS_STATE_AFTER)
{
- if (self->is_active)
- self->handle_pos = 1.0 - gtk_progress_tracker_get_ease_out_cubic (&self->tracker, FALSE);
+ progress = gtk_progress_tracker_get_ease_out_cubic (&self->tracker, FALSE);
+ if (is_right_side (widget, self->is_active))
+ self->handle_pos = 1.0 - progress;
else
- self->handle_pos = gtk_progress_tracker_get_ease_out_cubic (&self->tracker, FALSE);
+ self->handle_pos = progress;
}
else
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
- if (self->is_active)
+ if (is_right_side (widget, self->is_active))
offset += width / 2;
offset /= width / 2;
double y,
GtkSwitch *self)
{
+ GtkWidget *widget = GTK_WIDGET (self);
GdkEventSequence *sequence;
gboolean active;
/* if half the handle passed the middle of the switch, then we
* consider it to be on
*/
- active = self->handle_pos >= 0.5;
+ if (_gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ active = self->handle_pos >= 0.5;
+ else
+ active = self->handle_pos <= 0.5;
}
else if (!gtk_gesture_handles_sequence (self->click_gesture, sequence))
active = self->is_active;
else
return;
- self->handle_pos = active ? 1.0 : 0.0;
+ self->handle_pos = is_right_side (widget, active) ? 1.0 : 0.0;
gtk_switch_set_active (self, active);
- gtk_widget_queue_allocate (GTK_WIDGET (self));
+ gtk_widget_queue_allocate (widget);
}
static void
/* Center ON icon in left half */
gtk_widget_measure (self->on_image, GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL);
child_alloc.x = ((width / 2) - min) / 2;
+ if (is_right_side (widget, FALSE))
+ child_alloc.x += width / 2;
child_alloc.width = min;
gtk_widget_measure (self->on_image, GTK_ORIENTATION_VERTICAL, min, &min, NULL, NULL, NULL);
child_alloc.y = (height - min) / 2;
/* Center OFF icon in right half */
gtk_widget_measure (self->off_image, GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL);
- child_alloc.x = (width / 2) + ((width / 2) - min) / 2;
+ child_alloc.x = ((width / 2) - min) / 2;
+ if (is_right_side (widget, TRUE))
+ child_alloc.x += width / 2;
child_alloc.width = min;
gtk_widget_measure (self->off_image, GTK_ORIENTATION_VERTICAL, min, &min, NULL, NULL, NULL);
child_alloc.y = (height - min) / 2;
gtk_widget_size_allocate (self->off_image, &child_alloc, -1);
}
+static void
+gtk_switch_direction_changed (GtkWidget *widget,
+ GtkTextDirection previous_dir)
+{
+ GtkSwitch *self = GTK_SWITCH (widget);
+
+ self->handle_pos = 1.0 - self->handle_pos;
+ gtk_widget_queue_allocate (widget);
+
+ GTK_WIDGET_CLASS (gtk_switch_parent_class)->direction_changed (widget, previous_dir);
+}
+
static void
gtk_switch_set_action_name (GtkActionable *actionable,
const char *action_name)
g_object_class_install_properties (gobject_class, LAST_PROP, switch_props);
+ widget_class->direction_changed = gtk_switch_direction_changed;
+
klass->activate = gtk_switch_activate;
klass->state_set = state_set;
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
GTK_ACCESSIBLE_STATE_CHECKED, FALSE,
-1);
+ if (is_right_side (GTK_WIDGET (self), FALSE))
+ self->handle_pos = 1.0;
+ else
+ self->handle_pos = 0.0;
}
/**
self->is_active = is_active;
- if (self->is_active)
+ if (is_right_side (GTK_WIDGET (self), self->is_active))
self->handle_pos = 1.0;
else
self->handle_pos = 0.0;