views/month-view-row: Additive inverse in right-to-left languages
"Additive inverse" basically means transforming a positive number into a negative equivalent, or vice-versa; for example, from 5 to -5. Instead of inverting conditions in right-to-left languages to compare the X coordinate, a much simpler approach to this is to normalize the X coordinate by applying additive inverse in right-to-left languages. Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/744>
This commit is contained in:
@@ -100,7 +100,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
graphene_rect_t rect;
|
graphene_rect_t rect;
|
||||||
gint focal_x;
|
gint normalized_x;
|
||||||
} FocusEventData;
|
} FocusEventData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -116,13 +116,13 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (FocusEventData, focus_event_data_free)
|
|||||||
static FocusEventData *
|
static FocusEventData *
|
||||||
focus_event_data_new (GtkWidget *widget,
|
focus_event_data_new (GtkWidget *widget,
|
||||||
const graphene_rect_t *rect,
|
const graphene_rect_t *rect,
|
||||||
gint focal_x)
|
gint normalized_x)
|
||||||
{
|
{
|
||||||
g_autoptr (FocusEventData) focus_event_data = NULL;
|
g_autoptr (FocusEventData) focus_event_data = NULL;
|
||||||
|
|
||||||
focus_event_data = g_new0 (FocusEventData, 1);
|
focus_event_data = g_new0 (FocusEventData, 1);
|
||||||
focus_event_data->widget = widget;
|
focus_event_data->widget = widget;
|
||||||
focus_event_data->focal_x = focal_x;
|
focus_event_data->normalized_x = normalized_x;
|
||||||
graphene_rect_init_from_rect (&focus_event_data->rect, rect);
|
graphene_rect_init_from_rect (&focus_event_data->rect, rect);
|
||||||
|
|
||||||
return g_steal_pointer (&focus_event_data);
|
return g_steal_pointer (&focus_event_data);
|
||||||
@@ -147,9 +147,9 @@ static FocusEventData *
|
|||||||
create_focus_event_data (GcalMonthViewRow *self,
|
create_focus_event_data (GcalMonthViewRow *self,
|
||||||
GtkWidget *child)
|
GtkWidget *child)
|
||||||
{
|
{
|
||||||
|
gint focal_x, normalized_x;
|
||||||
graphene_rect_t rect;
|
graphene_rect_t rect;
|
||||||
gboolean is_rtl;
|
gboolean is_rtl;
|
||||||
gint focal_x;
|
|
||||||
|
|
||||||
g_assert (GTK_IS_WIDGET (child));
|
g_assert (GTK_IS_WIDGET (child));
|
||||||
|
|
||||||
@@ -158,8 +158,9 @@ create_focus_event_data (GcalMonthViewRow *self,
|
|||||||
|
|
||||||
is_rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
|
is_rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
|
||||||
focal_x = rect.origin.x + (is_rtl ? rect.size.width : 0);
|
focal_x = rect.origin.x + (is_rtl ? rect.size.width : 0);
|
||||||
|
normalized_x = is_rtl ? -focal_x : focal_x;
|
||||||
|
|
||||||
return focus_event_data_new (child, &rect, focal_x);
|
return focus_event_data_new (child, &rect, normalized_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FocusEventData *
|
static FocusEventData *
|
||||||
@@ -189,9 +190,6 @@ find_first_event_widget (GcalMonthViewRow *self)
|
|||||||
g_autoptr (FocusEventData) candidate = NULL;
|
g_autoptr (FocusEventData) candidate = NULL;
|
||||||
g_autoptr (FocusEventData) nearest = NULL;
|
g_autoptr (FocusEventData) nearest = NULL;
|
||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
gboolean is_rtl;
|
|
||||||
|
|
||||||
is_rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
|
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||||
child != NULL;
|
child != NULL;
|
||||||
@@ -207,10 +205,10 @@ find_first_event_widget (GcalMonthViewRow *self)
|
|||||||
|
|
||||||
if (nearest == NULL)
|
if (nearest == NULL)
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
else if ((is_rtl && candidate->focal_x > nearest->focal_x) ||
|
else if (candidate->normalized_x < nearest->normalized_x)
|
||||||
(!is_rtl && candidate->focal_x < nearest->focal_x))
|
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
else if (candidate->focal_x == nearest->focal_x && candidate->rect.origin.y < nearest->rect.origin.y)
|
else if (candidate->normalized_x == nearest->normalized_x &&
|
||||||
|
candidate->rect.origin.y < nearest->rect.origin.y)
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,9 +223,6 @@ find_last_event_widget (GcalMonthViewRow *self)
|
|||||||
g_autoptr (FocusEventData) candidate = NULL;
|
g_autoptr (FocusEventData) candidate = NULL;
|
||||||
g_autoptr (FocusEventData) nearest = NULL;
|
g_autoptr (FocusEventData) nearest = NULL;
|
||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
gboolean is_rtl;
|
|
||||||
|
|
||||||
is_rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
|
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||||
child != NULL;
|
child != NULL;
|
||||||
@@ -243,10 +238,10 @@ find_last_event_widget (GcalMonthViewRow *self)
|
|||||||
|
|
||||||
if (nearest == NULL)
|
if (nearest == NULL)
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
else if ((is_rtl && candidate->focal_x < nearest->focal_x) ||
|
else if (candidate->normalized_x > nearest->normalized_x)
|
||||||
(!is_rtl && candidate->focal_x > nearest->focal_x))
|
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
else if (candidate->focal_x == nearest->focal_x && candidate->rect.origin.y > nearest->rect.origin.y)
|
else if (candidate->normalized_x == nearest->normalized_x &&
|
||||||
|
candidate->rect.origin.y > nearest->rect.origin.y)
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,14 +259,12 @@ find_nearest_vertical_event_widget (GcalMonthViewRow *self,
|
|||||||
g_autoptr (FocusEventData) nearest = NULL;
|
g_autoptr (FocusEventData) nearest = NULL;
|
||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
gboolean downward, upward, forward_or_backward;
|
gboolean downward, upward, forward_or_backward;
|
||||||
gboolean is_rtl;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
GCAL_ENTRY;
|
||||||
|
|
||||||
downward = direction == GTK_DIR_DOWN || direction == GTK_DIR_TAB_FORWARD;
|
downward = direction == GTK_DIR_DOWN || direction == GTK_DIR_TAB_FORWARD;
|
||||||
upward = !downward;
|
upward = !downward;
|
||||||
|
|
||||||
is_rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
|
|
||||||
forward_or_backward = direction == GTK_DIR_TAB_FORWARD || direction == GTK_DIR_TAB_BACKWARD;
|
forward_or_backward = direction == GTK_DIR_TAB_FORWARD || direction == GTK_DIR_TAB_BACKWARD;
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||||
@@ -294,7 +287,7 @@ find_nearest_vertical_event_widget (GcalMonthViewRow *self,
|
|||||||
NULL))
|
NULL))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (forward_or_backward && focused->focal_x != candidate->focal_x)
|
if (forward_or_backward && focused->normalized_x != candidate->normalized_x)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((downward && candidate->rect.origin.y < focused->rect.origin.y) ||
|
if ((downward && candidate->rect.origin.y < focused->rect.origin.y) ||
|
||||||
@@ -307,8 +300,7 @@ find_nearest_vertical_event_widget (GcalMonthViewRow *self,
|
|||||||
(upward && candidate->rect.origin.y > nearest->rect.origin.y))
|
(upward && candidate->rect.origin.y > nearest->rect.origin.y))
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
else if (downward && candidate->rect.origin.y == nearest->rect.origin.y &&
|
else if (downward && candidate->rect.origin.y == nearest->rect.origin.y &&
|
||||||
((is_rtl && candidate->focal_x > nearest->focal_x) ||
|
candidate->normalized_x < nearest->normalized_x)
|
||||||
(!is_rtl && candidate->focal_x < nearest->focal_x)))
|
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +350,6 @@ find_nearest_horizontal_event_widget (GcalMonthViewRow *self,
|
|||||||
{
|
{
|
||||||
g_autoptr (FocusEventData) aux = NULL;
|
g_autoptr (FocusEventData) aux = NULL;
|
||||||
gboolean candidate_intersects_vertically;
|
gboolean candidate_intersects_vertically;
|
||||||
gboolean candidate_in_opposite_direction;
|
|
||||||
|
|
||||||
if (!(aux = create_focus_event_data_candidate (self, child)))
|
if (!(aux = create_focus_event_data_candidate (self, child)))
|
||||||
continue;
|
continue;
|
||||||
@@ -369,28 +360,29 @@ find_nearest_horizontal_event_widget (GcalMonthViewRow *self,
|
|||||||
if (candidate->widget == focused->widget)
|
if (candidate->widget == focused->widget)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (forward_or_backward &&
|
|
||||||
((lateral == GTK_DIR_LEFT && candidate->focal_x >= focused->focal_x) ||
|
if ((direction == GTK_DIR_TAB_FORWARD && candidate->normalized_x <= focused->normalized_x) ||
|
||||||
(lateral == GTK_DIR_RIGHT && candidate->focal_x <= focused->focal_x)))
|
(direction == GTK_DIR_TAB_BACKWARD && candidate->normalized_x >= focused->normalized_x))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
candidate_in_opposite_direction = ((lateral == GTK_DIR_LEFT && candidate->focal_x > focused->focal_x) ||
|
if ((direction == GTK_DIR_LEFT && ABS (candidate->normalized_x) > ABS (focused->normalized_x)) ||
|
||||||
(lateral == GTK_DIR_RIGHT && candidate->focal_x < focused->focal_x));
|
(direction == GTK_DIR_RIGHT && ABS (candidate->normalized_x) < ABS (focused->normalized_x)))
|
||||||
|
continue;
|
||||||
|
|
||||||
candidate_intersects_vertically =
|
candidate_intersects_vertically =
|
||||||
graphene_rect_intersection (&GRAPHENE_RECT_INIT (0, focused->rect.origin.y, 1, focused->rect.size.height),
|
graphene_rect_intersection (&GRAPHENE_RECT_INIT (0, focused->rect.origin.y, 1, focused->rect.size.height),
|
||||||
&GRAPHENE_RECT_INIT (0, candidate->rect.origin.y, 1, candidate->rect.size.height),
|
&GRAPHENE_RECT_INIT (0, candidate->rect.origin.y, 1, candidate->rect.size.height),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!forward_or_backward && (!candidate_intersects_vertically || candidate_in_opposite_direction))
|
if (!forward_or_backward && !candidate_intersects_vertically)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (nearest == NULL)
|
if (nearest == NULL)
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
else if ((lateral == GTK_DIR_LEFT && candidate->focal_x > nearest->focal_x) ||
|
else if ((lateral == GTK_DIR_LEFT && ABS (candidate->normalized_x) > ABS (nearest->normalized_x)) ||
|
||||||
(lateral == GTK_DIR_RIGHT && candidate->focal_x < nearest->focal_x))
|
(lateral == GTK_DIR_RIGHT && ABS (candidate->normalized_x) < ABS (nearest->normalized_x)))
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
else if (candidate->focal_x == nearest->focal_x &&
|
else if (ABS (candidate->normalized_x) == ABS (nearest->normalized_x) &&
|
||||||
((direction == GTK_DIR_TAB_FORWARD && candidate->rect.origin.y < nearest->rect.origin.y) ||
|
((direction == GTK_DIR_TAB_FORWARD && candidate->rect.origin.y < nearest->rect.origin.y) ||
|
||||||
(direction == GTK_DIR_TAB_BACKWARD && candidate->rect.origin.y > nearest->rect.origin.y)))
|
(direction == GTK_DIR_TAB_BACKWARD && candidate->rect.origin.y > nearest->rect.origin.y)))
|
||||||
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
swap_focus_event_data (&nearest, g_steal_pointer (&candidate));
|
||||||
@@ -1465,7 +1457,7 @@ gcal_month_view_row_focus_adjacent_cell (GcalMonthViewRow *self,
|
|||||||
|
|
||||||
data = create_focus_event_data (self, widget);
|
data = create_focus_event_data (self, widget);
|
||||||
|
|
||||||
cell = gcal_month_view_row_get_cell_at_x (self, data->focal_x);
|
cell = gcal_month_view_row_get_cell_at_x (self, ABS (data->normalized_x));
|
||||||
|
|
||||||
return gtk_widget_grab_focus (cell);
|
return gtk_widget_grab_focus (cell);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user