diff --git a/meson.build b/meson.build index c6ce587..a3d9195 100644 --- a/meson.build +++ b/meson.build @@ -26,6 +26,9 @@ project('call', 'c', default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ], ) +calls_id = 'sm.puri.Calls' +calls_homepage = 'https://source.puri.sm/Librem5/calls' +calls_version = meson.project_version() subdir('libgdbofono') subdir('src') diff --git a/src/calls-call-window.c b/src/calls-call-window.c new file mode 100644 index 0000000..36652e0 --- /dev/null +++ b/src/calls-call-window.c @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls 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 3 of the License, or + * (at your option) any later version. + * + * Calls 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 Calls. If not, see . + * + * Authors: + * Bob Ham + * Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "calls-call-window.h" +#include "calls-origin.h" +#include "calls-call-holder.h" +#include "calls-call-selector-item.h" +#include "calls-new-call-box.h" +#include "util.h" + +#include +#include + +#define HANDY_USE_UNSTABLE_API +#include + + +struct _CallsCallWindow +{ + GtkApplicationWindow parent_instance; + + GListStore *call_holders; + CallsCallHolder *focus; + + GtkInfoBar *info; + GtkLabel *info_label; + + GtkStack *main_stack; + GtkStack *header_bar_stack; + GtkButton *show_calls; + GtkStack *call_stack; + GtkFlowBox *call_selector; +}; + +enum { + ORIGIN_STORE_COLUMN_NAME, + ORIGIN_STORE_COLUMN_ORIGIN +}; + +G_DEFINE_TYPE (CallsCallWindow, calls_call_window, GTK_TYPE_APPLICATION_WINDOW); + + +CallsCallWindow * +calls_call_window_new (GtkApplication *application) +{ + return g_object_new (CALLS_TYPE_CALL_WINDOW, + "application", application, + NULL); +} + + +static void +update_visibility (CallsCallWindow *self) +{ + guint calls = g_list_model_get_n_items (G_LIST_MODEL (self->call_holders)); + + gtk_widget_set_visible (GTK_WIDGET (self), calls > 0); + gtk_widget_set_sensitive (GTK_WIDGET (self->show_calls), calls > 1); + + if (calls == 0) + { + gtk_stack_set_visible_child_name (self->main_stack, "calls"); + } + else if (calls == 1) + { + gtk_stack_set_visible_child_name (self->main_stack, "active-call"); + } +} + + +static void +show_message (CallsCallWindow *self, + const gchar *text, + GtkMessageType type) +{ + gtk_info_bar_set_message_type (self->info, type); + gtk_label_set_text (self->info_label, text); + gtk_widget_show (GTK_WIDGET (self->info)); + gtk_widget_queue_allocate (GTK_WIDGET (self)); +} + + +static void +info_response_cb (GtkInfoBar *infobar, + gint response_id, + CallsCallWindow *self) +{ + gtk_widget_hide (GTK_WIDGET (self->info)); + gtk_widget_queue_allocate (GTK_WIDGET (self)); +} + + +static GtkWidget * +call_holders_create_widget_cb (CallsCallHolder *holder, + CallsCallWindow *self) +{ + return GTK_WIDGET (calls_call_holder_get_selector_item (holder)); +} + + +static void +new_call_submitted_cb (CallsCallWindow *self, + CallsOrigin *origin, + const gchar *number, + CallsNewCallBox *new_call_box) +{ + g_return_if_fail (CALLS_IS_CALL_WINDOW (self)); + + calls_origin_dial (origin, number); +} + + +typedef gboolean (*FindCallHolderFunc) (CallsCallHolder *holder, + gpointer user_data); + + +static gboolean +find_call_holder_by_call (CallsCallHolder *holder, + gpointer user_data) +{ + CallsCallData *data = calls_call_holder_get_data (holder); + + return calls_call_data_get_call (data) == user_data; +} + + +/** Search through the list of call holders, returning the total + number of items in the list, the position of the holder within the + list and a pointer to the holder itself. */ +static gboolean +find_call_holder (CallsCallWindow *self, + guint *n_itemsp, + guint *positionp, + CallsCallHolder **holderp, + FindCallHolderFunc predicate, + gpointer user_data) +{ + GListModel * const model = G_LIST_MODEL (self->call_holders); + const guint n_items = g_list_model_get_n_items (model); + guint position = 0; + CallsCallHolder *holder; + + for (position = 0; position < n_items; ++position) + { + holder = CALLS_CALL_HOLDER (g_list_model_get_item (model, position)); + + if (predicate (holder, user_data)) + { +#define out(var) \ + if (var##p) \ + { \ + *var##p = var ; \ + } + + out (n_items); + out (position); + out (holder); + +#undef out + + return TRUE; + } + } + + return FALSE; +} + + +static void +set_focus (CallsCallWindow *self, + CallsCallHolder *holder) +{ + if (!holder) + { + holder = g_list_model_get_item (G_LIST_MODEL (self->call_holders), 0); + + if (!holder) + { + /* No calls */ + self->focus = NULL; + return; + } + } + + self->focus = holder; + + gtk_stack_set_visible_child_name (self->main_stack, "active-call"); + gtk_stack_set_visible_child_name (self->header_bar_stack, "active-call"); + gtk_stack_set_visible_child + (self->call_stack, + GTK_WIDGET (calls_call_holder_get_display (holder))); +} + + +static void +show_calls_clicked_cb (GtkButton *button, + CallsCallWindow *self) +{ + /* FIXME Setting only one of them should be enough as the properties are binded. */ + gtk_stack_set_visible_child_name (self->main_stack, "calls"); + gtk_stack_set_visible_child_name (self->header_bar_stack, "calls"); +} + + +static void +call_selector_child_activated_cb (GtkFlowBox *box, + GtkFlowBoxChild *child, + CallsCallWindow *self) +{ + GtkWidget *widget = gtk_bin_get_child (GTK_BIN (child)); + CallsCallSelectorItem *item = CALLS_CALL_SELECTOR_ITEM (widget); + CallsCallHolder *holder = calls_call_selector_item_get_holder (item); + + update_visibility (self); + set_focus (self, holder); +} + + +void +calls_call_window_add_call (CallsCallWindow *self, + CallsCall *call) +{ + CallsCallHolder *holder; + CallsCallDisplay *display; + + g_return_if_fail (CALLS_IS_CALL_WINDOW (self)); + g_return_if_fail (CALLS_IS_CALL (call)); + + g_signal_connect_swapped (call, "message", + G_CALLBACK (show_message), self); + + holder = calls_call_holder_new (call); + + display = calls_call_holder_get_display (holder); + gtk_stack_add_named (self->call_stack, GTK_WIDGET (display), + calls_call_get_number (call)); + + g_list_store_append (self->call_holders, holder); + + update_visibility (self); + set_focus (self, holder); +} + + +static void +remove_call_holder (CallsCallWindow *self, + guint n_items, + guint position, + CallsCallHolder *holder) +{ + g_list_store_remove (self->call_holders, position); + gtk_container_remove (GTK_CONTAINER (self->call_stack), + GTK_WIDGET (calls_call_holder_get_display (holder))); + + update_visibility (self); + if (self->focus == holder) + { + set_focus (self, NULL); + } +} + +void +calls_call_window_remove_call (CallsCallWindow *self, + CallsCall *call, + const gchar *reason) +{ + guint n_items, position; + CallsCallHolder *holder; + gboolean found; + + g_return_if_fail (CALLS_IS_CALL_WINDOW (self)); + g_return_if_fail (CALLS_IS_CALL (call)); + + found = find_call_holder (self, &n_items, &position, &holder, + find_call_holder_by_call, call); + g_return_if_fail (found); + + remove_call_holder (self, n_items, position, holder); + + if (!reason) + { + reason = "Call ended for unknown reason"; + } + show_message(self, reason, GTK_MESSAGE_INFO); +} + + +static void +remove_calls (CallsCallWindow *self) +{ + GList *children, *child; + + /* Safely remove the call stack's children. */ + children = gtk_container_get_children (GTK_CONTAINER (self->call_stack)); + for (child = children; child != NULL; child = child->next) + gtk_container_remove (GTK_CONTAINER (self->call_stack), + GTK_WIDGET (child->data)); + g_list_free (children); + + g_list_store_remove_all (self->call_holders); + + update_visibility (self); +} + + +static void +constructed (GObject *object) +{ + GObjectClass *parent_class = g_type_class_peek (GTK_TYPE_APPLICATION_WINDOW); + CallsCallWindow *self = CALLS_CALL_WINDOW (object); + + gtk_flow_box_bind_model (self->call_selector, + G_LIST_MODEL (self->call_holders), + (GtkFlowBoxCreateWidgetFunc) call_holders_create_widget_cb, + NULL, NULL); + + parent_class->constructed (object); +} + + +static void +calls_call_window_init (CallsCallWindow *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); + + self->call_holders = g_list_store_new (CALLS_TYPE_CALL_HOLDER); + + update_visibility (self); +} + + +static void +dispose (GObject *object) +{ + GObjectClass *parent_class = g_type_class_peek (GTK_TYPE_APPLICATION_WINDOW); + CallsCallWindow *self = CALLS_CALL_WINDOW (object); + + if (self->call_holders) + { + remove_calls (self); + } + + g_clear_object (&self->call_holders); + + parent_class->dispose (object); +} + + +static void +calls_call_window_class_init (CallsCallWindowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->constructed = constructed; + object_class->dispose = dispose; + + gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/call-window.ui"); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, info); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, info_label); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, main_stack); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, header_bar_stack); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, show_calls); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, call_stack); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, call_selector); + gtk_widget_class_bind_template_callback (widget_class, info_response_cb); + gtk_widget_class_bind_template_callback (widget_class, call_selector_child_activated_cb); + gtk_widget_class_bind_template_callback (widget_class, show_calls_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, new_call_submitted_cb); +} diff --git a/src/calls-call-window.h b/src/calls-call-window.h new file mode 100644 index 0000000..695e008 --- /dev/null +++ b/src/calls-call-window.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls 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 3 of the License, or + * (at your option) any later version. + * + * Calls 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 Calls. If not, see . + * + * Authors: + * Bob Ham + * Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef CALLS_CALL_WINDOW_H__ +#define CALLS_CALL_WINDOW_H__ + +#include + +#include "calls-call.h" + +G_BEGIN_DECLS + +#define CALLS_TYPE_CALL_WINDOW (calls_call_window_get_type ()) + +G_DECLARE_FINAL_TYPE (CallsCallWindow, calls_call_window, CALLS, CALL_WINDOW, GtkApplicationWindow); + +CallsCallWindow *calls_call_window_new (GtkApplication *application); +void calls_call_window_add_call (CallsCallWindow *self, CallsCall *call); +void calls_call_window_remove_call (CallsCallWindow *self, CallsCall *call, const gchar *reason); + +G_END_DECLS + +#endif /* CALLS_CALL_WINDOW_H__ */ diff --git a/src/calls-history-header-bar.c b/src/calls-history-header-bar.c new file mode 100644 index 0000000..86cc6a4 --- /dev/null +++ b/src/calls-history-header-bar.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls 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 3 of the License, or + * (at your option) any later version. + * + * Calls 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 Calls. If not, see . + * + * Author: Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "calls-history-header-bar.h" + +struct _CallsHistoryHeaderBar +{ + GtkHeaderBar parent_instance; +}; + +G_DEFINE_TYPE (CallsHistoryHeaderBar, calls_history_header_bar, GTK_TYPE_HEADER_BAR); + + +static void +calls_history_header_bar_init (CallsHistoryHeaderBar *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); +} + + +static void +calls_history_header_bar_class_init (CallsHistoryHeaderBarClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/history-header-bar.ui"); +} + diff --git a/src/calls-history-header-bar.h b/src/calls-history-header-bar.h new file mode 100644 index 0000000..b7958af --- /dev/null +++ b/src/calls-history-header-bar.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls 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 3 of the License, or + * (at your option) any later version. + * + * Calls 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 Calls. If not, see . + * + * Author: Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef CALLS_HISTORY_HEADER_BAR_H__ +#define CALLS_HISTORY_HEADER_BAR_H__ + +#include + +G_BEGIN_DECLS + +#define CALLS_TYPE_HISTORY_HEADER_BAR (calls_history_header_bar_get_type ()) + +G_DECLARE_FINAL_TYPE (CallsHistoryHeaderBar, calls_history_header_bar, CALLS, HISTORY_HEADER_BAR, GtkHeaderBar); + +G_END_DECLS + +#endif /* CALLS_HISTORY_HEADER_BAR_H__ */ diff --git a/src/calls-main-window.c b/src/calls-main-window.c index ee1de9a..27ca8ad 100644 --- a/src/calls-main-window.c +++ b/src/calls-main-window.c @@ -27,6 +27,7 @@ #include "calls-call-holder.h" #include "calls-call-selector-item.h" #include "calls-new-call-box.h" +#include "config.h" #include "util.h" #include @@ -48,10 +49,7 @@ struct _CallsMainWindow GtkLabel *info_label; GtkStack *main_stack; - GtkButton *back; - GtkStack *call_stack; - GtkScrolledWindow *call_scroll; - GtkFlowBox *call_selector; + GtkStack *header_bar_stack; GtkListStore *origin_store; }; @@ -71,6 +69,88 @@ enum { static GParamSpec *props[PROP_LAST_PROP]; +enum { + SIGNAL_CALL_ADDED, + SIGNAL_CALL_REMOVED, + SIGNAL_LAST_SIGNAL, +}; +static guint signals [SIGNAL_LAST_SIGNAL]; + + +static void +about_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + CallsMainWindow *self = user_data; + + const gchar *version = NULL; + + static const gchar *authors[] = { + "Adrien Plazas ", + "Bob Ham ", + "Guido Günther ", + NULL + }; + + static const gchar *artists[] = { + "Tobias Bernard ", + NULL + }; + + static const gchar *documenters[] = { + "Heather Ellsworth ", + NULL + }; + + version = g_str_equal (VCS_TAG, "") ? PACKAGE_VERSION: + PACKAGE_VERSION "-" VCS_TAG; + + gtk_show_about_dialog (GTK_WINDOW (self), + "artists", artists, + "authors", authors, + "copyright", "Copyright © 2018 Purism", + "documenters", documenters, + "license-type", GTK_LICENSE_GPL_3_0, + "logo-icon-name", APP_ID, + "program-name", _("Calls"), + "translator-credits", _("translator-credits"), + "version", version, + "website", PACKAGE_URL, + NULL); +} + + +static void +new_call_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + CallsMainWindow *self = user_data; + + gtk_stack_set_visible_child_name (self->header_bar_stack, "new-call"); +} + + +static void +back_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + CallsMainWindow *self = user_data; + + gtk_stack_set_visible_child_name (self->header_bar_stack, "history"); +} + + +static const GActionEntry window_entries [] = +{ + { "about", about_action }, + { "new-call", new_call_action }, + { "back", back_action }, +}; + + CallsMainWindow * calls_main_window_new (GtkApplication *application, CallsProvider *provider) { @@ -113,14 +193,6 @@ new_call_submitted_cb (CallsMainWindow *self, } -static GtkWidget * -call_holders_create_widget_cb (CallsCallHolder *holder, - CallsMainWindow *self) -{ - return GTK_WIDGET (calls_call_holder_get_selector_item (holder)); -} - - typedef gboolean (*FindCallHolderFunc) (CallsCallHolder *holder, gpointer user_data); @@ -193,66 +265,6 @@ set_focus (CallsMainWindow *self, CallsCallHolder *holder) } self->focus = holder; - - gtk_stack_set_visible_child - (self->call_stack, - GTK_WIDGET (calls_call_holder_get_display (holder))); -} - - -static void -back_clicked_cb (GtkButton *back, - CallsMainWindow *self) -{ - gtk_stack_set_visible_child (self->call_stack, GTK_WIDGET (self->call_scroll)); - gtk_stack_set_visible_child (self->main_stack, GTK_WIDGET (self->call_stack)); -} - - -static void -call_selector_child_activated_cb (GtkFlowBox *box, - GtkFlowBoxChild *child, - CallsMainWindow *self) -{ - GtkWidget *widget = gtk_bin_get_child (GTK_BIN (child)); - CallsCallSelectorItem *item = CALLS_CALL_SELECTOR_ITEM (widget); - CallsCallHolder *holder = calls_call_selector_item_get_holder (item); - - set_focus (self, holder); -} - - -/** Possibly show various call widgets */ -static void -show_calls (CallsMainWindow *self, guint old_call_count) -{ - if (old_call_count == 0) - { - gtk_stack_add_titled (self->main_stack, - GTK_WIDGET (self->call_stack), - "call", "Call"); - } - - if (old_call_count > 0) - { - gtk_widget_show (GTK_WIDGET (self->back)); - } -} - - -static void -hide_calls (CallsMainWindow *self, guint call_count) -{ - if (call_count == 0) - { - gtk_container_remove (GTK_CONTAINER (self->main_stack), - GTK_WIDGET (self->call_stack)); - } - - if (call_count <= 1) - { - gtk_widget_hide (GTK_WIDGET (self->back)); - } } @@ -260,20 +272,14 @@ static void add_call (CallsMainWindow *self, CallsCall *call) { CallsCallHolder *holder; - CallsCallDisplay *display; + + g_signal_emit (self, signals[SIGNAL_CALL_ADDED], 0, call); g_signal_connect_swapped (call, "message", G_CALLBACK (show_message), self); - show_calls (self, g_list_model_get_n_items (G_LIST_MODEL (self->call_holders))); - holder = calls_call_holder_new (call); - display = calls_call_holder_get_display (holder); - gtk_stack_add_named (self->call_stack, GTK_WIDGET (display), - calls_call_get_number (call)); - gtk_stack_set_visible_child (self->main_stack, GTK_WIDGET (self->call_stack)); - g_list_store_append (self->call_holders, holder); set_focus (self, holder); @@ -288,15 +294,11 @@ remove_call_holder (CallsMainWindow *self, CallsCallHolder *holder) { g_list_store_remove (self->call_holders, position); - gtk_container_remove (GTK_CONTAINER (self->call_stack), - GTK_WIDGET (calls_call_holder_get_display (holder))); if (self->focus == holder) { set_focus (self, NULL); } - - hide_calls (self, n_items - 1); } static void @@ -309,6 +311,8 @@ remove_call (CallsMainWindow *self, CallsCall *call, const gchar *reason) g_return_if_fail (CALLS_IS_MAIN_WINDOW (self)); g_return_if_fail (CALLS_IS_CALL (call)); + g_signal_emit (self, signals[SIGNAL_CALL_REMOVED], 0, call, reason); + found = find_call_holder (self, &n_items, &position, &holder, find_call_holder_by_call, call); g_return_if_fail (found); @@ -501,14 +505,18 @@ constructed (GObject *object) { GObjectClass *parent_class = g_type_class_peek (GTK_TYPE_APPLICATION_WINDOW); CallsMainWindow *self = CALLS_MAIN_WINDOW (object); + GSimpleActionGroup *simple_action_group; - gtk_container_remove (GTK_CONTAINER (self->main_stack), - GTK_WIDGET (self->call_stack)); - - gtk_flow_box_bind_model (self->call_selector, - G_LIST_MODEL (self->call_holders), - (GtkFlowBoxCreateWidgetFunc) call_holders_create_widget_cb, - NULL, NULL); + /* Add actions */ + simple_action_group = g_simple_action_group_new (); + g_action_map_add_action_entries (G_ACTION_MAP (simple_action_group), + window_entries, + G_N_ELEMENTS (window_entries), + self); + gtk_widget_insert_action_group (GTK_WIDGET (self), + "win", + G_ACTION_GROUP (simple_action_group)); + g_object_unref (simple_action_group); parent_class->constructed (object); } @@ -566,17 +574,34 @@ calls_main_window_class_init (CallsMainWindowClass *klass) g_object_class_install_properties (object_class, PROP_LAST_PROP, props); + signals[SIGNAL_CALL_ADDED] = + g_signal_new ("call-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 1, + CALLS_TYPE_CALL); + + signals[SIGNAL_CALL_REMOVED] = + g_signal_new ("call-removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 2, + CALLS_TYPE_CALL, + G_TYPE_STRING); + + gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/main-window.ui"); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, info); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, info_label); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, main_stack); - gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, back); - gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, call_stack); - gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, call_scroll); - gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, call_selector); + gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, header_bar_stack); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, origin_store); gtk_widget_class_bind_template_callback (widget_class, info_response_cb); - gtk_widget_class_bind_template_callback (widget_class, call_selector_child_activated_cb); - gtk_widget_class_bind_template_callback (widget_class, back_clicked_cb); gtk_widget_class_bind_template_callback (widget_class, new_call_submitted_cb); } diff --git a/src/calls-new-call-header-bar.c b/src/calls-new-call-header-bar.c new file mode 100644 index 0000000..cbdca6e --- /dev/null +++ b/src/calls-new-call-header-bar.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls 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 3 of the License, or + * (at your option) any later version. + * + * Calls 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 Calls. If not, see . + * + * Author: Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "calls-new-call-header-bar.h" + +struct _CallsNewCallHeaderBar +{ + GtkHeaderBar parent_instance; +}; + +G_DEFINE_TYPE (CallsNewCallHeaderBar, calls_new_call_header_bar, GTK_TYPE_HEADER_BAR); + + +static void +calls_new_call_header_bar_init (CallsNewCallHeaderBar *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); +} + + +static void +calls_new_call_header_bar_class_init (CallsNewCallHeaderBarClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/new-call-header-bar.ui"); +} + diff --git a/src/calls-new-call-header-bar.h b/src/calls-new-call-header-bar.h new file mode 100644 index 0000000..7eae143 --- /dev/null +++ b/src/calls-new-call-header-bar.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls 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 3 of the License, or + * (at your option) any later version. + * + * Calls 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 Calls. If not, see . + * + * Author: Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef CALLS_NEW_CALL_HEADER_BAR_H__ +#define CALLS_NEW_CALL_HEADER_BAR_H__ + +#include + +G_BEGIN_DECLS + +#define CALLS_TYPE_NEW_CALL_HEADER_BAR (calls_new_call_header_bar_get_type ()) + +G_DECLARE_FINAL_TYPE (CallsNewCallHeaderBar, calls_new_call_header_bar, CALLS, NEW_CALL_HEADER_BAR, GtkHeaderBar); + +G_END_DECLS + +#endif /* CALLS_NEW_CALL_HEADER_BAR_H__ */ diff --git a/src/calls.gresources.xml b/src/calls.gresources.xml index 355bfc8..73577f7 100644 --- a/src/calls.gresources.xml +++ b/src/calls.gresources.xml @@ -4,8 +4,11 @@ main-window.ui call-display.ui call-selector-item.ui + call-window.ui encryption-indicator.ui history-box.ui + history-header-bar.ui new-call-box.ui + new-call-header-bar.ui diff --git a/src/main.c b/src/main.c index 0dc5d0e..5609e92 100644 --- a/src/main.c +++ b/src/main.c @@ -27,13 +27,15 @@ #define HANDY_USE_UNSTABLE_API #include +#include "calls-call-window.h" #include "calls-encryption-indicator.h" #include "calls-history-box.h" +#include "calls-history-header-bar.h" #include "calls-main-window.h" #include "calls-mm-provider.h" #include "calls-new-call-box.h" - -#define APP_ID "sm.puri.Calls" +#include "calls-new-call-header-bar.h" +#include "config.h" static void show_window (GtkApplication *app) @@ -42,10 +44,13 @@ show_window (GtkApplication *app) GDBusConnection *connection; CallsProvider *provider; CallsMainWindow *main_window; + CallsCallWindow *call_window; CALLS_TYPE_ENCRYPTION_INDICATOR; CALLS_TYPE_HISTORY_BOX; + CALLS_TYPE_HISTORY_HEADER_BAR; CALLS_TYPE_NEW_CALL_BOX; + CALLS_TYPE_NEW_CALL_HEADER_BAR; HDY_TYPE_DIALER; connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); @@ -64,6 +69,13 @@ show_window (GtkApplication *app) gtk_window_set_title (GTK_WINDOW (main_window), "Calls"); gtk_widget_show_all (GTK_WIDGET (main_window)); + + call_window = calls_call_window_new (app); + + g_signal_connect_swapped (main_window, "call-added", + G_CALLBACK (calls_call_window_add_call), call_window); + g_signal_connect_swapped (main_window, "call-removed", + G_CALLBACK (calls_call_window_remove_call), call_window); } int diff --git a/src/meson.build b/src/meson.build index 2a215b1..0ad652b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -45,9 +45,12 @@ calls_sources = ['calls-message-source.c', 'calls-message-source.h', 'calls-call-holder.c', 'calls-call-holder.h', 'calls-call-display.c', 'calls-call-display.h', 'calls-call-selector-item.c', 'calls-call-selector-item.h', + 'calls-call-window.c', 'calls-call-window.h', 'calls-encryption-indicator.c', 'calls-encryption-indicator.h', 'calls-history-box.c', 'calls-history-box.h', + 'calls-history-header-bar.c', 'calls-history-header-bar.h', 'calls-new-call-box.c', 'calls-new-call-box.h', + 'calls-new-call-header-bar.c', 'calls-new-call-header-bar.h', 'calls-main-window.c', 'calls-main-window.h', 'util.c', 'util.h', ] @@ -57,6 +60,23 @@ calls_dummy_sources = ['calls-dummy-call.c', 'calls-dummy-call.h', 'calls-dummy-provider.c', 'calls-dummy-provider.h', ] +config_data = configuration_data() +config_data.set_quoted('APP_ID', calls_id) +config_data.set_quoted('PACKAGE_URL', calls_homepage) +config_data.set_quoted('PACKAGE_VERSION', calls_version) +config_data.set_quoted('VCS_TAG', '@VCS_TAG@') + +config_h_in = configure_file( + output: 'config.h.in', + configuration: config_data +) + +config_h = vcs_tag( + fallback: '', + input: config_h_in, + output: 'config.h', +) + calls_enum_headers = ['calls-call.h'] calls_enum_sources = gnome.mkenums_simple('enum-types', sources : calls_enum_headers) diff --git a/src/ui/call-window.ui b/src/ui/call-window.ui new file mode 100644 index 0000000..10c0f95 --- /dev/null +++ b/src/ui/call-window.ui @@ -0,0 +1,153 @@ + + + + + + + diff --git a/src/ui/history-header-bar.ui b/src/ui/history-header-bar.ui new file mode 100644 index 0000000..4a61ba8 --- /dev/null +++ b/src/ui/history-header-bar.ui @@ -0,0 +1,80 @@ + + + + + + + True + + + False + 12 + vertical + True + + + True + About + win.about + True + + + + + + + diff --git a/src/ui/main-window.ui b/src/ui/main-window.ui index 87a3c42..dfab70a 100644 --- a/src/ui/main-window.ui +++ b/src/ui/main-window.ui @@ -21,51 +21,6 @@ True False vertical - - - True - False - - - True - True - True - - - - True - False - go-previous-symbolic - - - - - False - True - 0 - - - - - True - False - center - 0 - main_stack - - - True - True - 1 - - - - - False - True - 0 - - False @@ -123,42 +78,13 @@ True False - + True - False - - - True - True - never - - - True - False - - - True - False - vertical - True - 12 - 12 - none - - - - - - - - page0 - page0 - - + True - call - Call + history + History @@ -173,17 +99,6 @@ New call - - - True - True - - - history - History - 3 - - True @@ -194,7 +109,29 @@ - + + False + True + + + + False + True + + + history + + + + + False + True + + + new-call + + + \ No newline at end of file diff --git a/src/ui/new-call-header-bar.ui b/src/ui/new-call-header-bar.ui new file mode 100644 index 0000000..90cf991 --- /dev/null +++ b/src/ui/new-call-header-bar.ui @@ -0,0 +1,43 @@ + + + + + +