Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: ui/views/controls/textfield/native_textfield_gtk.cc

Issue 9728002: Removing deprecated GTK-Views code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/controls/textfield/native_textfield_gtk.h ('k') | ui/views/events/event_gtk.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <gdk/gdkkeysyms.h>
6 #include <gtk/gtk.h>
7
8 #include "ui/views/controls/textfield/native_textfield_gtk.h"
9
10 #include "base/logging.h"
11 #include "base/utf_string_conversions.h"
12 #include "ui/base/range/range.h"
13 #include "ui/gfx/gtk_util.h"
14 #include "ui/gfx/insets.h"
15 #include "ui/gfx/selection_model.h"
16 #include "ui/gfx/skia_utils_gtk.h"
17 #include "ui/views/controls/textfield/gtk_views_entry.h"
18 #include "ui/views/controls/textfield/gtk_views_textview.h"
19 #include "ui/views/controls/textfield/native_textfield_views.h"
20 #include "ui/views/controls/textfield/textfield.h"
21 #include "ui/views/controls/textfield/textfield_controller.h"
22 #include "ui/views/widget/native_widget_gtk.h"
23
24 namespace views {
25
26 // A character used to hide a text in obscured mode.
27 static const char kObscuredChar = '*';
28
29 // Border width for GtkTextView.
30 const int kTextViewBorderWidth = 4;
31
32 ////////////////////////////////////////////////////////////////////////////////
33 // NativeTextfieldGtk, public:
34
35 NativeTextfieldGtk::NativeTextfieldGtk(Textfield* textfield)
36 : textfield_(textfield),
37 paste_clipboard_requested_(false) {
38 // Make |textfield| the focused view, so that when we get focused the focus
39 // manager sees |textfield| as the focused view (since we are just a wrapper
40 // view).
41 set_focus_view(textfield);
42 }
43
44 NativeTextfieldGtk::~NativeTextfieldGtk() {
45 }
46
47 // Returns the inner border of an entry.
48 // static
49 gfx::Insets NativeTextfieldGtk::GetEntryInnerBorder(GtkEntry* entry) {
50 const GtkBorder* inner_border = gtk_entry_get_inner_border(entry);
51 if (inner_border)
52 return gfx::Insets(*inner_border);
53
54 // No explicit border set, try the style.
55 GtkBorder* style_border;
56 gtk_widget_style_get(GTK_WIDGET(entry), "inner-border", &style_border, NULL);
57 if (style_border) {
58 gfx::Insets insets = gfx::Insets(*style_border);
59 gtk_border_free(style_border);
60 return insets;
61 }
62
63 // If border is null, Gtk uses 2 on all sides.
64 return gfx::Insets(2, 2, 2, 2);
65 }
66
67 gfx::Insets NativeTextfieldGtk::GetTextViewInnerBorder(GtkTextView* text_view) {
68 return gfx::Insets(kTextViewBorderWidth / 2, kTextViewBorderWidth / 2,
69 kTextViewBorderWidth / 2, kTextViewBorderWidth / 2);
70 }
71
72 ////////////////////////////////////////////////////////////////////////////////
73 // NativeTextfieldGtk, NativeTextfieldWrapper implementation:
74
75 string16 NativeTextfieldGtk::GetText() const {
76 return UTF8ToUTF16(gtk_entry_get_text(GTK_ENTRY(native_view())));
77 }
78
79 void NativeTextfieldGtk::UpdateText() {
80 if (!native_view())
81 return;
82 gtk_entry_set_text(GTK_ENTRY(native_view()),
83 UTF16ToUTF8(textfield_->text()).c_str());
84 }
85
86 void NativeTextfieldGtk::AppendText(const string16& text) {
87 if (!native_view())
88 return;
89 gtk_entry_append_text(GTK_ENTRY(native_view()), UTF16ToUTF8(text).c_str());
90 }
91
92 string16 NativeTextfieldGtk::GetSelectedText() const {
93 if (!native_view())
94 return string16();
95
96 string16 result;
97
98 gint start_pos;
99 gint end_pos;
100 if (!gtk_editable_get_selection_bounds(GTK_EDITABLE(native_view()),
101 &start_pos, &end_pos))
102 return result; // No selection.
103
104 UTF8ToUTF16(gtk_editable_get_chars(GTK_EDITABLE(native_view()),
105 start_pos, end_pos),
106 end_pos - start_pos, &result);
107
108 return result;
109 }
110
111 void NativeTextfieldGtk::SelectAll() {
112 if (!native_view())
113 return;
114 // -1 as the end position selects to the end of the text.
115 gtk_editable_select_region(GTK_EDITABLE(native_view()), 0, -1);
116 }
117
118 void NativeTextfieldGtk::ClearSelection() {
119 if (!native_view())
120 return;
121 gtk_editable_select_region(GTK_EDITABLE(native_view()), 0, 0);
122 }
123
124 void NativeTextfieldGtk::UpdateBorder() {
125 if (!native_view())
126 return;
127
128 if (!textfield_->draw_border())
129 gtk_entry_set_has_frame(GTK_ENTRY(native_view()), false);
130 }
131
132 void NativeTextfieldGtk::UpdateTextColor() {
133 if (textfield_->use_default_text_color()) {
134 // Passing NULL as the color undoes the effect of previous calls to
135 // gtk_widget_modify_text.
136 gtk_widget_modify_text(native_view(), GTK_STATE_NORMAL, NULL);
137 return;
138 }
139 GdkColor gdk_color = gfx::SkColorToGdkColor(textfield_->text_color());
140 gtk_widget_modify_text(native_view(), GTK_STATE_NORMAL, &gdk_color);
141 }
142
143 void NativeTextfieldGtk::UpdateBackgroundColor() {
144 if (textfield_->use_default_background_color()) {
145 // Passing NULL as the color undoes the effect of previous calls to
146 // gtk_widget_modify_base.
147 gtk_widget_modify_base(native_view(), GTK_STATE_NORMAL, NULL);
148 return;
149 }
150 GdkColor gdk_color = gfx::SkColorToGdkColor(textfield_->background_color());
151 gtk_widget_modify_base(native_view(), GTK_STATE_NORMAL, &gdk_color);
152 }
153
154 void NativeTextfieldGtk::UpdateCursorColor() {
155 if (!textfield_->use_default_cursor_color())
156 NOTIMPLEMENTED();
157 }
158
159 void NativeTextfieldGtk::UpdateReadOnly() {
160 if (!native_view())
161 return;
162 gtk_editable_set_editable(GTK_EDITABLE(native_view()),
163 !textfield_->read_only());
164 }
165
166 void NativeTextfieldGtk::UpdateFont() {
167 if (!native_view())
168 return;
169 PangoFontDescription* pfd = textfield_->font().GetNativeFont();
170 gtk_widget_modify_font(native_view(), pfd);
171 pango_font_description_free(pfd);
172 }
173
174 void NativeTextfieldGtk::UpdateIsObscured() {
175 if (!native_view())
176 return;
177 gtk_entry_set_visibility(GTK_ENTRY(native_view()), !textfield_->IsObscured());
178 }
179
180 void NativeTextfieldGtk::UpdateEnabled() {
181 if (!native_view())
182 return;
183 SetEnabled(textfield_->enabled());
184 }
185
186 gfx::Insets NativeTextfieldGtk::CalculateInsets() {
187 if (!native_view())
188 return gfx::Insets();
189
190 GtkWidget* widget = native_view();
191 gfx::Insets insets;
192
193 GtkEntry* entry = GTK_ENTRY(widget);
194 insets += GetEntryInnerBorder(entry);
195 if (entry->has_frame) {
196 insets += gfx::Insets(widget->style->ythickness,
197 widget->style->xthickness,
198 widget->style->ythickness,
199 widget->style->xthickness);
200 }
201
202 gboolean interior_focus;
203 gint focus_width;
204 gtk_widget_style_get(widget,
205 "focus-line-width", &focus_width,
206 "interior-focus", &interior_focus,
207 NULL);
208 if (!interior_focus)
209 insets += gfx::Insets(focus_width, focus_width, focus_width, focus_width);
210
211 return insets;
212 }
213
214 void NativeTextfieldGtk::UpdateHorizontalMargins() {
215 if (!native_view())
216 return;
217
218 int left, right;
219 if (!textfield_->GetHorizontalMargins(&left, &right))
220 return;
221
222 gfx::Insets insets = GetEntryInnerBorder(GTK_ENTRY(native_view()));
223 GtkBorder border = {left, right, insets.top(), insets.bottom()};
224 gtk_entry_set_inner_border(GTK_ENTRY(native_view()), &border);
225 }
226
227 void NativeTextfieldGtk::UpdateVerticalMargins() {
228 if (!native_view())
229 return;
230
231 int top, bottom;
232 if (!textfield_->GetVerticalMargins(&top, &bottom))
233 return;
234
235 gfx::Insets insets = GetEntryInnerBorder(GTK_ENTRY(native_view()));
236 GtkBorder border = {insets.left(), insets.right(), top, bottom};
237 gtk_entry_set_inner_border(GTK_ENTRY(native_view()), &border);
238 }
239
240 bool NativeTextfieldGtk::SetFocus() {
241 OnFocus();
242 return true;
243 }
244
245 View* NativeTextfieldGtk::GetView() {
246 return this;
247 }
248
249 gfx::NativeView NativeTextfieldGtk::GetTestingHandle() const {
250 return native_view();
251 }
252
253 bool NativeTextfieldGtk::IsIMEComposing() const {
254 return false;
255 }
256
257 void NativeTextfieldGtk::GetSelectedRange(ui::Range* range) const {
258 gint start_pos;
259 gint end_pos;
260 gtk_editable_get_selection_bounds(
261 GTK_EDITABLE(native_view()), &start_pos, &end_pos);
262 *range = ui::Range(start_pos, end_pos);
263 }
264
265 void NativeTextfieldGtk::SelectRange(const ui::Range& range) {
266 NOTREACHED();
267 }
268
269 void NativeTextfieldGtk::GetSelectionModel(gfx::SelectionModel* sel) const {
270 NOTREACHED();
271 }
272
273 void NativeTextfieldGtk::SelectSelectionModel(const gfx::SelectionModel& sel) {
274 NOTREACHED();
275 }
276
277 size_t NativeTextfieldGtk::GetCursorPosition() const {
278 NOTREACHED();
279 return 0U;
280 }
281
282 bool NativeTextfieldGtk::HandleKeyPressed(const views::KeyEvent& e) {
283 return false;
284 }
285
286 bool NativeTextfieldGtk::HandleKeyReleased(const views::KeyEvent& e) {
287 return false;
288 }
289
290 void NativeTextfieldGtk::HandleFocus() {
291 }
292
293 void NativeTextfieldGtk::HandleBlur() {
294 }
295
296 ui::TextInputClient* NativeTextfieldGtk::GetTextInputClient() {
297 return NULL;
298 }
299
300 void NativeTextfieldGtk::ApplyStyleRange(const gfx::StyleRange& style) {
301 NOTREACHED();
302 }
303
304 void NativeTextfieldGtk::ApplyDefaultStyle() {
305 NOTREACHED();
306 }
307
308 void NativeTextfieldGtk::ClearEditHistory() {
309 NOTREACHED();
310 }
311
312 int NativeTextfieldGtk::GetFontHeight() {
313 return textfield_->font().GetHeight();
314 }
315
316 void NativeTextfieldGtk::OnActivate(GtkWidget* native_widget) {
317 GdkEvent* event = gtk_get_current_event();
318 if (!event || event->type != GDK_KEY_PRESS)
319 return;
320
321 KeyEvent views_key_event(event);
322 gboolean handled = false;
323
324 TextfieldController* controller = textfield_->GetController();
325 if (controller)
326 handled = controller->HandleKeyEvent(textfield_, views_key_event);
327
328 Widget* widget = GetWidget();
329 if (!handled && widget) {
330 NativeWidgetGtk* native_widget =
331 static_cast<NativeWidgetGtk*>(widget->native_widget());
332 handled = native_widget->HandleKeyboardEvent(views_key_event);
333 }
334
335 // Stop signal emission if the key event is handled by us.
336 if (handled) {
337 // Only GtkEntry has "activate" signal.
338 static guint signal_id = g_signal_lookup("activate", GTK_TYPE_ENTRY);
339 g_signal_stop_emission(native_widget, signal_id, 0);
340 }
341 }
342
343 void NativeTextfieldGtk::OnChanged(GObject* object) {
344 // We need to call TextfieldController::ContentsChanged() explicitly if the
345 // paste action didn't change the content at all. See http://crbug.com/79002
346 const bool call_contents_changed =
347 paste_clipboard_requested_ && GetText() == textfield_->text();
348 textfield_->SyncText();
349 textfield_->GetWidget()->NotifyAccessibilityEvent(
350 textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
351 if (call_contents_changed) {
352 TextfieldController* controller = textfield_->GetController();
353 if (controller)
354 controller->ContentsChanged(textfield_, textfield_->text());
355 }
356 paste_clipboard_requested_ = false;
357 }
358
359 gboolean NativeTextfieldGtk::OnButtonPressEvent(GtkWidget* widget,
360 GdkEventButton* event) {
361 paste_clipboard_requested_ = false;
362 return false;
363 }
364
365 gboolean NativeTextfieldGtk::OnButtonReleaseEventAfter(GtkWidget* widget,
366 GdkEventButton* event) {
367 textfield_->GetWidget()->NotifyAccessibilityEvent(
368 textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
369 return false;
370 }
371
372 gboolean NativeTextfieldGtk::OnKeyPressEvent(GtkWidget* widget,
373 GdkEventKey* event) {
374 paste_clipboard_requested_ = false;
375 return false;
376 }
377
378 gboolean NativeTextfieldGtk::OnKeyPressEventAfter(GtkWidget* widget,
379 GdkEventKey* event) {
380 TextfieldController* controller = textfield_->GetController();
381 if (controller) {
382 KeyEvent key_event(reinterpret_cast<GdkEvent*>(event));
383 return controller->HandleKeyEvent(textfield_, key_event);
384 }
385 return false;
386 }
387
388 void NativeTextfieldGtk::OnMoveCursor(GtkWidget* widget,
389 GtkMovementStep step,
390 gint count,
391 gboolean extend_selection) {
392 textfield_->GetWidget()->NotifyAccessibilityEvent(
393 textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
394 }
395
396 void NativeTextfieldGtk::OnPasteClipboard(GtkWidget* widget) {
397 if (!textfield_->read_only())
398 paste_clipboard_requested_ = true;
399 }
400
401 ////////////////////////////////////////////////////////////////////////////////
402 // NativeTextfieldGtk, NativeControlGtk overrides:
403
404 void NativeTextfieldGtk::CreateNativeControl() {
405 NativeControlCreated(gtk_views_entry_new(this));
406 gtk_entry_set_invisible_char(GTK_ENTRY(native_view()),
407 static_cast<gunichar>(kObscuredChar));
408 textfield_->UpdateAllProperties();
409 }
410
411 void NativeTextfieldGtk::NativeControlCreated(GtkWidget* widget) {
412 NativeControlGtk::NativeControlCreated(widget);
413
414 g_signal_connect(widget, "changed", G_CALLBACK(OnChangedThunk), this);
415 // In order to properly trigger Accelerators bound to VKEY_RETURN, we need
416 // to send an event when the widget gets the activate signal.
417 g_signal_connect(widget, "activate", G_CALLBACK(OnActivateThunk), this);
418 g_signal_connect(widget, "move-cursor", G_CALLBACK(OnMoveCursorThunk), this);
419 g_signal_connect(widget, "button-press-event",
420 G_CALLBACK(OnButtonPressEventThunk), this);
421 g_signal_connect(widget, "key-press-event",
422 G_CALLBACK(OnKeyPressEventThunk), this);
423 g_signal_connect(widget, "paste-clipboard",
424 G_CALLBACK(OnPasteClipboardThunk), this);
425
426 g_signal_connect_after(widget, "button-release-event",
427 G_CALLBACK(OnButtonReleaseEventAfterThunk), this);
428 g_signal_connect_after(widget, "key-press-event",
429 G_CALLBACK(OnKeyPressEventAfterThunk), this);
430 }
431
432 bool NativeTextfieldGtk::IsObscured() {
433 return textfield_->IsObscured();
434 }
435
436 ///////////////////////////////////////////////////////////////////////////////
437 // NativeTextfieldWrapper:
438
439 // static
440 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper(
441 Textfield* field) {
442 if (Widget::IsPureViews())
443 return new NativeTextfieldViews(field);
444 return new NativeTextfieldGtk(field);
445 }
446
447 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/textfield/native_textfield_gtk.h ('k') | ui/views/events/event_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698