Commit 911d13b6 authored by Julian Sparber's avatar Julian Sparber Committed by Julian Sparber
Browse files

contact-editor: fix birthday picker and make it adaptive

This fixes the birthday picker and imporves some small bugs.
It also makes the picker adaptive by moving the entries to a popover
parent 61d90d4b
Pipeline #19966 failed with stage
......@@ -19,6 +19,166 @@ using Gtk;
using Folks;
using Gee;
public class Contacts.BirthdayEditor : Box {
public bool use_popover { get; set; }
private SpinButton day_spin;
private ComboBoxText month_combo;
private SpinButton year_spin;
private Widget birthday = null;
public signal void changed ();
delegate void AdjustingDateFn ();
public DateTime get_birthday () {
return new DateTime.local (year_spin.get_value_as_int (),
month_combo.get_active () + 1,
day_spin.get_value_as_int (),
0, 0, 0).to_utc ();
}
private void update() {
if (birthday is MenuButton) {
(birthday as MenuButton).set_label(get_birthday ().to_local ().format ("%x"));
}
}
construct {
notify["use-popover"].connect(() => {
if (use_popover) {
if (birthday is Grid) {
var grid = birthday as Grid;
foreach (var child in grid.get_children()) {
grid.remove(child);
}
birthday.destroy();
birthday = null;
create_popover (get_birthday ());
show_all();
}
} else {
if (birthday is MenuButton) {
var grid = (birthday as MenuButton).get_popover ().get_child () as Grid;
foreach (var child in grid.get_children()) {
grid.remove(child);
}
birthday.destroy();
birthday = null;
create_row ();
show_all();
}
}
});
}
public BirthdayEditor (DateTime birthday, bool use_popover) {
this.use_popover = use_popover;
day_spin = new SpinButton.with_range (1.0, 31.0, 1.0);
day_spin.set_digits (0);
day_spin.numeric = true;
day_spin.set_value ((double)birthday.to_local ().get_day_of_month ());
month_combo = new ComboBoxText ();
var january = new DateTime.local (1, 1, 1, 1, 1, 1);
for (int i = 0; i < 12; i++) {
var month = january.add_months (i);
month_combo.append_text (month.format ("%B"));
}
month_combo.set_active (birthday.to_local ().get_month () - 1);
month_combo.hexpand = true;
year_spin = new SpinButton.with_range (1800, 3000, 1);
year_spin.set_digits (0);
year_spin.numeric = true;
year_spin.set_value ((double)birthday.to_local ().get_year ());
if (this.use_popover) {
create_popover (birthday);
} else {
create_row ();
}
AdjustingDateFn fn = () => {
int[] month_of_31 = {3, 5, 8, 10};
if (month_combo.get_active () in month_of_31) {
day_spin.set_range (1, 30);
} else if (month_combo.get_active () == 1) {
if (year_spin.get_value_as_int () % 4 == 0 &&
year_spin.get_value_as_int () % 100 != 0) {
day_spin.set_range (1, 29);
} else {
day_spin.set_range (1, 28);
}
}
};
/* adjusting day_spin value using selected month/year constraints*/
fn ();
/* Notify change to upper layer */
day_spin.value_changed.connect (() => {
changed();
update();
});
month_combo.changed.connect (() => {
changed();
update();
/* adjusting day_spin value using selected month constraints*/
fn ();
});
year_spin.value_changed.connect (() => {
changed();
update();
fn ();
});
}
private void create_popover(DateTime birthday) {
var box = new Grid ();
box.set_column_spacing (12);
box.set_row_spacing (12);
var birthday_button = new MenuButton ();
birthday_button.set_label (birthday.to_local ().format ("%x"));
birthday_button.set_hexpand (true);
Label day = new Label(_("Day"));
day.set_halign (Align.END);
box.attach (day, 0, 0);
box.attach (day_spin, 1, 0);
Label month = new Label(_("Month"));
month.set_halign (Align.END);
box.attach (month, 0, 1);
box.attach (month_combo, 1, 1);
Label year = new Label(_("Year"));
year.set_halign (Align.END);
box.attach (year, 0, 2);
box.attach (year_spin, 1, 2);
box.margin = 12;
box.show_all ();
var popover = new Popover (birthday_button);
popover.add (box);
birthday_button.set_popover (popover);
add (birthday_button);
this.birthday = birthday_button;
}
private void create_row () {
var box = new Grid ();
box.set_column_spacing (12);
box.add (day_spin);
box.add (month_combo);
box.add (year_spin);
add (box);
birthday = box;
}
}
public class Contacts.AddressEditor : Box {
public Entry? entries[7]; /* must be the number of elements in postal_element_props */
public PostalAddressFieldDetails details;
......@@ -105,6 +265,8 @@ public class Contacts.ContactEditor : ContactForm {
/* the key of the hash_map is the uid of the persona */
private HashMap<string, HashMap<string, Field?>> writable_personas;
public bool narrow { get; set; default = true; }
public bool has_birthday_row {
get; private set; default = false;
}
......@@ -121,7 +283,6 @@ public class Contacts.ContactEditor : ContactForm {
this.writable_personas = new HashMap<string, HashMap<string, Field?>> ();
this.container_grid.size_allocate.connect(on_container_grid_size_allocate);
bool small = false;
int old_width = this.get_allocated_width ();
Image trash_icon = new Image.from_icon_name ("user-trash-symbolic", IconSize.MENU);
string label = _("Remove Contact");
......@@ -130,16 +291,16 @@ public class Contacts.ContactEditor : ContactForm {
size_allocate.connect(() => {
int width = this.get_allocated_width ();
if (old_width != width) {
if (!small && width <= RESIZE_WIDTH) {
if (!narrow && width <= RESIZE_WIDTH) {
this.avatar.set_display_size (PROFILE_SMALL_SIZE);
this.remove_button.image = trash_icon;
this.remove_button.label = null;
small = true;
} else if (small && width > RESIZE_WIDTH) {
narrow = true;
} else if (narrow && width > RESIZE_WIDTH) {
this.avatar.set_display_size (PROFILE_SIZE);
this.remove_button.image = null;
this.remove_button.label = label;
small = false;
narrow = false;
}
old_width = this.get_allocated_width ();
}
......@@ -299,18 +460,8 @@ public class Contacts.ContactEditor : ContactForm {
Value get_value_from_birthday (HashMap<int, RowData?> rows) {
var new_value = Value (typeof (DateTime));
foreach (var row_entry in rows.entries) {
var box = container_grid.get_child_at (1, row_entry.key) as Grid;
var day_spin = box.get_child_at (0, 0) as SpinButton;
var combo = box.get_child_at (1, 0) as ComboBoxText;
var year_spin = box.get_child_at (2, 0) as SpinButton;
var bday = new DateTime.local (year_spin.get_value_as_int (),
combo.get_active () + 1,
day_spin.get_value_as_int (),
0, 0, 0);
bday = bday.to_utc ();
new_value.set_boxed (bday);
var box = container_grid.get_child_at (1, row_entry.key) as BirthdayEditor;
new_value.set_boxed (box.get_birthday());
}
return new_value;
}
......@@ -501,8 +652,6 @@ public class Contacts.ContactEditor : ContactForm {
focus_widget = value_text;
}
delegate void AdjustingDateFn();
void attach_row_for_birthday (string title, AbstractFieldDetails? details, DateTime birthday, int row) {
var title_label = new Label (title);
title_label.set_hexpand (false);
......@@ -510,70 +659,21 @@ public class Contacts.ContactEditor : ContactForm {
title_label.margin_end = 6;
container_grid.attach (title_label, 0, row, 1, 1);
var box = new Grid ();
box.set_column_spacing (12);
var day_spin = new SpinButton.with_range (1.0, 31.0, 1.0);
day_spin.set_digits (0);
day_spin.numeric = true;
day_spin.set_value ((double)birthday.to_local ().get_day_of_month ());
var month_combo = new ComboBoxText ();
var january = new DateTime.local (1, 1, 1, 1, 1, 1);
for (int i = 0; i < 12; i++) {
var month = january.add_months (i);
month_combo.append_text (month.format ("%B"));
}
month_combo.set_active (birthday.to_local ().get_month () - 1);
month_combo.hexpand = true;
var year_spin = new SpinButton.with_range (1800, 3000, 1);
year_spin.set_digits (0);
year_spin.numeric = true;
year_spin.set_value ((double)birthday.to_local ().get_year ());
box.add (day_spin);
box.add (month_combo);
box.add (year_spin);
var box = new BirthdayEditor (birthday, narrow);
bind_property("narrow", box, "use-popover");
container_grid.attach (box, 1, row, 1, 1);
box.changed.connect(() => {
set_field_changed (get_current_row (box));
});
var delete_button = new Button.from_icon_name ("user-trash-symbolic", IconSize.MENU);
delete_button.get_accessible ().set_name (_("Delete field"));
container_grid.attach (delete_button, 2, row, 1, 1);
AdjustingDateFn fn = () => {
int[] month_of_31 = {3, 5, 8, 10};
if (month_combo.get_active () in month_of_31) {
day_spin.set_range (1, 30);
} else if (month_combo.get_active () == 1) {
if (year_spin.get_value_as_int () % 4 == 0 &&
year_spin.get_value_as_int () % 100 != 0) {
day_spin.set_range (1, 29);
} else {
day_spin.set_range (1, 28);
}
}
};
/* Notify change to upper layer */
day_spin.changed.connect (() => {
set_field_changed (get_current_row (day_spin));
});
month_combo.changed.connect (() => {
set_field_changed (get_current_row (month_combo));
/* adjusting day_spin value using selected month constraints*/
fn ();
});
year_spin.changed.connect (() => {
set_field_changed (get_current_row (year_spin));
fn ();
});
delete_button.clicked.connect (() => {
remove_row (get_current_row (delete_button));
has_birthday_row = false;
});
remove_row (get_current_row (delete_button));
has_birthday_row = false;
});
}
void attach_row_for_address (int row, TypeSet type_set, PostalAddressFieldDetails details, string? type = null) {
......
......@@ -21,7 +21,7 @@ using Gee;
const int PROFILE_SIZE = 128;
const int PROFILE_SMALL_SIZE = 95;
const int RESIZE_WIDTH = 450;
const int RESIZE_WIDTH = 600;
/**
* The ContactPage is the right pane. It consists of 3 possible pages:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment