| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <gtk/gtk.h> | 5 #include <gtk/gtk.h> |
| 6 #include <math.h> | 6 #include <math.h> |
| 7 | 7 |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "remoting/base/string_resources.h" |
| 12 #include "remoting/host/client_session_control.h" | 13 #include "remoting/host/client_session_control.h" |
| 13 #include "remoting/host/host_window.h" | 14 #include "remoting/host/host_window.h" |
| 14 #include "remoting/host/ui_strings.h" | |
| 15 #include "ui/base/gtk/gtk_signal.h" | 15 #include "ui/base/gtk/gtk_signal.h" |
| 16 #include "ui/base/l10n/l10n_util.h" |
| 16 | 17 |
| 17 namespace remoting { | 18 namespace remoting { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 class DisconnectWindowGtk : public HostWindow { | 22 class DisconnectWindowGtk : public HostWindow { |
| 22 public: | 23 public: |
| 23 explicit DisconnectWindowGtk(const UiStrings& ui_strings); | 24 DisconnectWindowGtk(); |
| 24 virtual ~DisconnectWindowGtk(); | 25 virtual ~DisconnectWindowGtk(); |
| 25 | 26 |
| 26 // HostWindow overrides. | 27 // HostWindow overrides. |
| 27 virtual void Start( | 28 virtual void Start( |
| 28 const base::WeakPtr<ClientSessionControl>& client_session_control) | 29 const base::WeakPtr<ClientSessionControl>& client_session_control) |
| 29 OVERRIDE; | 30 OVERRIDE; |
| 30 | 31 |
| 31 private: | 32 private: |
| 32 CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnDelete, GdkEvent*); | 33 CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnDelete, GdkEvent*); |
| 33 CHROMEGTK_CALLBACK_0(DisconnectWindowGtk, void, OnClicked); | 34 CHROMEGTK_CALLBACK_0(DisconnectWindowGtk, void, OnClicked); |
| 34 CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnConfigure, | 35 CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnConfigure, |
| 35 GdkEventConfigure*); | 36 GdkEventConfigure*); |
| 36 CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnButtonPress, | 37 CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnButtonPress, |
| 37 GdkEventButton*); | 38 GdkEventButton*); |
| 38 | 39 |
| 39 // Used to disconnect the client session. | 40 // Used to disconnect the client session. |
| 40 base::WeakPtr<ClientSessionControl> client_session_control_; | 41 base::WeakPtr<ClientSessionControl> client_session_control_; |
| 41 | 42 |
| 42 // Localized UI strings. | |
| 43 UiStrings ui_strings_; | |
| 44 | |
| 45 GtkWidget* disconnect_window_; | 43 GtkWidget* disconnect_window_; |
| 46 GtkWidget* message_; | 44 GtkWidget* message_; |
| 47 GtkWidget* button_; | 45 GtkWidget* button_; |
| 48 | 46 |
| 49 // Used to distinguish resize events from other types of "configure-event" | 47 // Used to distinguish resize events from other types of "configure-event" |
| 50 // notifications. | 48 // notifications. |
| 51 int current_width_; | 49 int current_width_; |
| 52 int current_height_; | 50 int current_height_; |
| 53 | 51 |
| 54 DISALLOW_COPY_AND_ASSIGN(DisconnectWindowGtk); | 52 DISALLOW_COPY_AND_ASSIGN(DisconnectWindowGtk); |
| 55 }; | 53 }; |
| 56 | 54 |
| 57 // Helper function for creating a rectangular path with rounded corners, as | 55 // Helper function for creating a rectangular path with rounded corners, as |
| 58 // Cairo doesn't have this facility. |radius| is the arc-radius of each | 56 // Cairo doesn't have this facility. |radius| is the arc-radius of each |
| 59 // corner. The bounding rectangle extends from (0, 0) to (width, height). | 57 // corner. The bounding rectangle extends from (0, 0) to (width, height). |
| 60 void AddRoundRectPath(cairo_t* cairo_context, int width, int height, | 58 void AddRoundRectPath(cairo_t* cairo_context, int width, int height, |
| 61 int radius) { | 59 int radius) { |
| 62 cairo_new_sub_path(cairo_context); | 60 cairo_new_sub_path(cairo_context); |
| 63 cairo_arc(cairo_context, width - radius, radius, radius, -M_PI_2, 0); | 61 cairo_arc(cairo_context, width - radius, radius, radius, -M_PI_2, 0); |
| 64 cairo_arc(cairo_context, width - radius, height - radius, radius, 0, M_PI_2); | 62 cairo_arc(cairo_context, width - radius, height - radius, radius, 0, M_PI_2); |
| 65 cairo_arc(cairo_context, radius, height - radius, radius, M_PI_2, 2 * M_PI_2); | 63 cairo_arc(cairo_context, radius, height - radius, radius, M_PI_2, 2 * M_PI_2); |
| 66 cairo_arc(cairo_context, radius, radius, radius, 2 * M_PI_2, 3 * M_PI_2); | 64 cairo_arc(cairo_context, radius, radius, radius, 2 * M_PI_2, 3 * M_PI_2); |
| 67 cairo_close_path(cairo_context); | 65 cairo_close_path(cairo_context); |
| 68 } | 66 } |
| 69 | 67 |
| 70 DisconnectWindowGtk::DisconnectWindowGtk(const UiStrings& ui_strings) | 68 DisconnectWindowGtk::DisconnectWindowGtk() |
| 71 : ui_strings_(ui_strings), | 69 : disconnect_window_(NULL), |
| 72 disconnect_window_(NULL), | |
| 73 current_width_(0), | 70 current_width_(0), |
| 74 current_height_(0) { | 71 current_height_(0) { |
| 75 } | 72 } |
| 76 | 73 |
| 77 DisconnectWindowGtk::~DisconnectWindowGtk() { | 74 DisconnectWindowGtk::~DisconnectWindowGtk() { |
| 78 DCHECK(CalledOnValidThread()); | 75 DCHECK(CalledOnValidThread()); |
| 79 | 76 |
| 80 if (disconnect_window_) { | 77 if (disconnect_window_) { |
| 81 gtk_widget_destroy(disconnect_window_); | 78 gtk_widget_destroy(disconnect_window_); |
| 82 disconnect_window_ = NULL; | 79 disconnect_window_ = NULL; |
| 83 } | 80 } |
| 84 } | 81 } |
| 85 | 82 |
| 86 void DisconnectWindowGtk::Start( | 83 void DisconnectWindowGtk::Start( |
| 87 const base::WeakPtr<ClientSessionControl>& client_session_control) { | 84 const base::WeakPtr<ClientSessionControl>& client_session_control) { |
| 88 DCHECK(CalledOnValidThread()); | 85 DCHECK(CalledOnValidThread()); |
| 89 DCHECK(!client_session_control_.get()); | 86 DCHECK(!client_session_control_.get()); |
| 90 DCHECK(client_session_control.get()); | 87 DCHECK(client_session_control.get()); |
| 91 DCHECK(!disconnect_window_); | 88 DCHECK(!disconnect_window_); |
| 92 | 89 |
| 93 client_session_control_ = client_session_control; | 90 client_session_control_ = client_session_control; |
| 94 | 91 |
| 95 // Create the window. | 92 // Create the window. |
| 96 disconnect_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); | 93 disconnect_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
| 97 GtkWindow* window = GTK_WINDOW(disconnect_window_); | 94 GtkWindow* window = GTK_WINDOW(disconnect_window_); |
| 98 | 95 |
| 99 g_signal_connect(disconnect_window_, "delete-event", | 96 g_signal_connect(disconnect_window_, "delete-event", |
| 100 G_CALLBACK(OnDeleteThunk), this); | 97 G_CALLBACK(OnDeleteThunk), this); |
| 101 gtk_window_set_title(window, UTF16ToUTF8(ui_strings_.product_name).c_str()); | 98 gtk_window_set_title(window, |
| 99 l10n_util::GetStringUTF8(IDR_PRODUCT_NAME).c_str()); |
| 102 gtk_window_set_resizable(window, FALSE); | 100 gtk_window_set_resizable(window, FALSE); |
| 103 | 101 |
| 104 // Try to keep the window always visible. | 102 // Try to keep the window always visible. |
| 105 gtk_window_stick(window); | 103 gtk_window_stick(window); |
| 106 gtk_window_set_keep_above(window, TRUE); | 104 gtk_window_set_keep_above(window, TRUE); |
| 107 | 105 |
| 108 // Remove window titlebar. | 106 // Remove window titlebar. |
| 109 gtk_window_set_decorated(window, FALSE); | 107 gtk_window_set_decorated(window, FALSE); |
| 110 | 108 |
| 111 // In case the titlebar is still there, try to remove some of the buttons. | 109 // In case the titlebar is still there, try to remove some of the buttons. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 135 // left and right. The left margin is made larger to accommodate the | 133 // left and right. The left margin is made larger to accommodate the |
| 136 // window movement gripper. | 134 // window movement gripper. |
| 137 GtkWidget* align = gtk_alignment_new(0, 0, 1, 1); | 135 GtkWidget* align = gtk_alignment_new(0, 0, 1, 1); |
| 138 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 8, 8, 24, 12); | 136 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 8, 8, 24, 12); |
| 139 gtk_container_add(GTK_CONTAINER(window), align); | 137 gtk_container_add(GTK_CONTAINER(window), align); |
| 140 | 138 |
| 141 GtkWidget* button_row = gtk_hbox_new(FALSE, 12); | 139 GtkWidget* button_row = gtk_hbox_new(FALSE, 12); |
| 142 gtk_container_add(GTK_CONTAINER(align), button_row); | 140 gtk_container_add(GTK_CONTAINER(align), button_row); |
| 143 | 141 |
| 144 button_ = gtk_button_new_with_label( | 142 button_ = gtk_button_new_with_label( |
| 145 UTF16ToUTF8(ui_strings_.disconnect_button_text).c_str()); | 143 l10n_util::GetStringUTF8(IDR_STOP_SHARING_BUTTON).c_str()); |
| 146 gtk_box_pack_end(GTK_BOX(button_row), button_, FALSE, FALSE, 0); | 144 gtk_box_pack_end(GTK_BOX(button_row), button_, FALSE, FALSE, 0); |
| 147 | 145 |
| 148 g_signal_connect(button_, "clicked", G_CALLBACK(OnClickedThunk), this); | 146 g_signal_connect(button_, "clicked", G_CALLBACK(OnClickedThunk), this); |
| 149 | 147 |
| 150 message_ = gtk_label_new(NULL); | 148 message_ = gtk_label_new(NULL); |
| 151 gtk_box_pack_end(GTK_BOX(button_row), message_, FALSE, FALSE, 0); | 149 gtk_box_pack_end(GTK_BOX(button_row), message_, FALSE, FALSE, 0); |
| 152 | 150 |
| 153 // Override any theme setting for the text color, so that the text is | 151 // Override any theme setting for the text color, so that the text is |
| 154 // readable against the window's background pixmap. | 152 // readable against the window's background pixmap. |
| 155 PangoAttrList* attributes = pango_attr_list_new(); | 153 PangoAttrList* attributes = pango_attr_list_new(); |
| 156 PangoAttribute* text_color = pango_attr_foreground_new(0, 0, 0); | 154 PangoAttribute* text_color = pango_attr_foreground_new(0, 0, 0); |
| 157 pango_attr_list_insert(attributes, text_color); | 155 pango_attr_list_insert(attributes, text_color); |
| 158 gtk_label_set_attributes(GTK_LABEL(message_), attributes); | 156 gtk_label_set_attributes(GTK_LABEL(message_), attributes); |
| 159 pango_attr_list_unref(attributes); | 157 pango_attr_list_unref(attributes); |
| 160 | 158 |
| 161 gtk_widget_show_all(disconnect_window_); | 159 gtk_widget_show_all(disconnect_window_); |
| 162 | 160 |
| 163 // Extract the user name from the JID. | 161 // Extract the user name from the JID. |
| 164 std::string client_jid = client_session_control_->client_jid(); | 162 std::string client_jid = client_session_control_->client_jid(); |
| 165 string16 username = UTF8ToUTF16(client_jid.substr(0, client_jid.find('/'))); | 163 string16 username = UTF8ToUTF16(client_jid.substr(0, client_jid.find('/'))); |
| 166 string16 text = | 164 gtk_label_set_text( |
| 167 ReplaceStringPlaceholders(ui_strings_.disconnect_message, username, NULL); | 165 GTK_LABEL(message_), |
| 168 gtk_label_set_text(GTK_LABEL(message_), UTF16ToUTF8(text).c_str()); | 166 l10n_util::GetStringFUTF8(IDR_MESSAGE_SHARED, username).c_str()); |
| 169 gtk_window_present(window); | 167 gtk_window_present(window); |
| 170 } | 168 } |
| 171 | 169 |
| 172 void DisconnectWindowGtk::OnClicked(GtkWidget* button) { | 170 void DisconnectWindowGtk::OnClicked(GtkWidget* button) { |
| 173 DCHECK(CalledOnValidThread()); | 171 DCHECK(CalledOnValidThread()); |
| 174 | 172 |
| 175 if (client_session_control_.get()) | 173 if (client_session_control_.get()) |
| 176 client_session_control_->DisconnectSession(); | 174 client_session_control_->DisconnectSession(); |
| 177 } | 175 } |
| 178 | 176 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 event->button, | 279 event->button, |
| 282 event->x_root, | 280 event->x_root, |
| 283 event->y_root, | 281 event->y_root, |
| 284 event->time); | 282 event->time); |
| 285 return FALSE; | 283 return FALSE; |
| 286 } | 284 } |
| 287 | 285 |
| 288 } // namespace | 286 } // namespace |
| 289 | 287 |
| 290 // static | 288 // static |
| 291 scoped_ptr<HostWindow> HostWindow::CreateDisconnectWindow( | 289 scoped_ptr<HostWindow> HostWindow::CreateDisconnectWindow() { |
| 292 const UiStrings& ui_strings) { | 290 return scoped_ptr<HostWindow>(new DisconnectWindowGtk()); |
| 293 return scoped_ptr<HostWindow>(new DisconnectWindowGtk(ui_strings)); | |
| 294 } | 291 } |
| 295 | 292 |
| 296 } // namespace remoting | 293 } // namespace remoting |
| OLD | NEW |