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

Side by Side Diff: views/controls/tabbed_pane/native_tabbed_pane_win.cc

Issue 155668: Refactoring of tabbed-pane component so it can be ported to Linux toolkit_view (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 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 "views/controls/tabbed_pane/native_tabbed_pane_win.h"
6
7 #include <vssym32.h>
8
9 #include "app/gfx/canvas.h"
10 #include "app/gfx/font.h"
11 #include "app/l10n_util_win.h"
12 #include "app/resource_bundle.h"
13 #include "base/gfx/native_theme.h"
14 #include "base/logging.h"
15 #include "base/stl_util-inl.h"
16 #include "views/controls/tabbed_pane/tabbed_pane.h"
17 #include "views/fill_layout.h"
18 #include "views/widget/root_view.h"
19 #include "views/widget/widget_win.h"
20
21 namespace views {
22
23 // A background object that paints the tab panel background which may be
24 // rendered by the system visual styles system.
25 class TabBackground : public Background {
26 public:
27 explicit TabBackground() {
28 // TMT_FILLCOLORHINT returns a color value that supposedly
29 // approximates the texture drawn by PaintTabPanelBackground.
30 SkColor tab_page_color =
31 gfx::NativeTheme::instance()->GetThemeColorWithDefault(
32 gfx::NativeTheme::TAB, TABP_BODY, 0, TMT_FILLCOLORHINT,
33 COLOR_3DFACE);
34 SetNativeControlColor(tab_page_color);
35 }
36 virtual ~TabBackground() {}
37
38 virtual void Paint(gfx::Canvas* canvas, View* view) const {
39 HDC dc = canvas->beginPlatformPaint();
40 RECT r = {0, 0, view->width(), view->height()};
41 gfx::NativeTheme::instance()->PaintTabPanelBackground(dc, &r);
42 canvas->endPlatformPaint();
43 }
44
45 private:
46 DISALLOW_COPY_AND_ASSIGN(TabBackground);
47 };
48
49 ////////////////////////////////////////////////////////////////////////////////
50 // NativeTabbedPaneWin, public:
51
52 NativeTabbedPaneWin::NativeTabbedPaneWin(TabbedPane* tabbed_pane)
53 : NativeControlWin(),
54 tabbed_pane_(tabbed_pane),
55 content_window_(NULL) {
56 // Associates the actual HWND with the tabbed-pane so the tabbed-pane is
57 // the one considered as having the focus (not the wrapper) when the HWND is
58 // focused directly (with a click for example).
59 set_focus_view(tabbed_pane);
60 }
61
62 NativeTabbedPaneWin::~NativeTabbedPaneWin() {
63 // We own the tab views, let's delete them.
64 STLDeleteContainerPointers(tab_views_.begin(), tab_views_.end());
65 }
66
67 ////////////////////////////////////////////////////////////////////////////////
68 // NativeTabbedPaneWin, NativeTabbedPaneWrapper implementation:
69
70 void NativeTabbedPaneWin::AddTab(const std::wstring& title, View* contents) {
71 AddTabAtIndex(static_cast<int>(tab_views_.size()), title, contents, true);
72 }
73
74 void NativeTabbedPaneWin::AddTabAtIndex(int index, const std::wstring& title,
75 View* contents,
76 bool select_if_first_tab) {
77 DCHECK(index <= static_cast<int>(tab_views_.size()));
78 contents->SetParentOwned(false);
79 tab_views_.insert(tab_views_.begin() + index, contents);
80
81 TCITEM tcitem;
82 tcitem.mask = TCIF_TEXT;
83
84 // If the locale is RTL, we set the TCIF_RTLREADING so that BiDi text is
85 // rendered properly on the tabs.
86 if (UILayoutIsRightToLeft()) {
87 tcitem.mask |= TCIF_RTLREADING;
88 }
89
90 tcitem.pszText = const_cast<wchar_t*>(title.c_str());
91 int result = TabCtrl_InsertItem(native_view(), index, &tcitem);
92 DCHECK(result != -1);
93
94 if (!contents->background())
95 contents->set_background(new TabBackground);
96
97 if (tab_views_.size() == 1 && select_if_first_tab) {
98 // If this is the only tab displayed, make sure the contents is set.
99 content_window_->GetRootView()->AddChildView(contents);
100 }
101
102 // The newly added tab may have made the contents window smaller.
103 ResizeContents();
104 }
105
106 View* NativeTabbedPaneWin::RemoveTabAtIndex(int index) {
107 int tab_count = static_cast<int>(tab_views_.size());
108 DCHECK(index >= 0 && index < tab_count);
109
110 if (index < (tab_count - 1)) {
111 // Select the next tab.
112 SelectTabAt(index + 1);
113 } else {
114 // We are the last tab, select the previous one.
115 if (index > 0) {
116 SelectTabAt(index - 1);
117 } else {
118 // That was the last tab. Remove the contents.
119 content_window_->GetRootView()->RemoveAllChildViews(false);
120 }
121 }
122 TabCtrl_DeleteItem(native_view(), index);
123
124 // The removed tab may have made the contents window bigger.
125 ResizeContents();
126
127 std::vector<View*>::iterator iter = tab_views_.begin() + index;
128 View* removed_tab = *iter;
129 tab_views_.erase(iter);
130
131 return removed_tab;
132 }
133
134 void NativeTabbedPaneWin::SelectTabAt(int index) {
135 DCHECK((index >= 0) && (index < static_cast<int>(tab_views_.size())));
136 TabCtrl_SetCurSel(native_view(), index);
137 DoSelectTabAt(index);
138 }
139
140 int NativeTabbedPaneWin::GetTabCount() {
141 return TabCtrl_GetItemCount(native_view());
142 }
143
144 int NativeTabbedPaneWin::GetSelectedTabIndex() {
145 return TabCtrl_GetCurSel(native_view());
146 }
147
148 View* NativeTabbedPaneWin::GetSelectedTab() {
149 return content_window_->GetRootView()->GetChildViewAt(0);
150 }
151
152 View* NativeTabbedPaneWin::GetView() {
153 return this;
154 }
155
156 void NativeTabbedPaneWin::SetFocus() {
157 // Focus the associated HWND.
158 Focus();
159 }
160
161 gfx::NativeView NativeTabbedPaneWin::GetTestingHandle() const {
162 return native_view();
163 }
164
165 ////////////////////////////////////////////////////////////////////////////////
166 // NativeTabbedPaneWin, NativeControlWin override:
167
168 void NativeTabbedPaneWin::CreateNativeControl() {
169 // Create the tab control.
170 //
171 // Note that we don't follow the common convention for NativeControl
172 // subclasses and we don't pass the value returned from
173 // NativeControl::GetAdditionalExStyle() as the dwExStyle parameter. Here is
174 // why: on RTL locales, if we pass NativeControl::GetAdditionalExStyle() when
175 // we basically tell Windows to create our HWND with the WS_EX_LAYOUTRTL. If
176 // we do that, then the HWND we create for |content_window_| below will
177 // inherit the WS_EX_LAYOUTRTL property and this will result in the contents
178 // being flipped, which is not what we want (because we handle mirroring in
179 // views without the use of Windows' support for mirroring). Therefore,
180 // we initially create our HWND without the aforementioned property and we
181 // explicitly set this property our child is created. This way, on RTL
182 // locales, our tabs will be nicely rendered from right to left (by virtue of
183 // Windows doing the right thing with the TabbedPane HWND) and each tab
184 // contents will use an RTL layout correctly (by virtue of the mirroring
185 // infrastructure in views doing the right thing with each View we put
186 // in the tab).
187 HWND tab_control = ::CreateWindowEx(0,
188 WC_TABCONTROL,
189 L"",
190 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
191 0, 0, width(), height(),
192 GetWidget()->GetNativeView(), NULL, NULL,
193 NULL);
194
195 HFONT font = ResourceBundle::GetSharedInstance().
196 GetFont(ResourceBundle::BaseFont).hfont();
197 SendMessage(tab_control, WM_SETFONT, reinterpret_cast<WPARAM>(font), FALSE);
198
199 // Create the view container which is a child of the TabControl.
200 content_window_ = new WidgetWin();
201 content_window_->Init(tab_control, gfx::Rect());
202
203 // Explicitly setting the WS_EX_LAYOUTRTL property for the HWND (see above
204 // for a thorough explanation regarding why we waited until |content_window_|
205 // if created before we set this property for the tabbed pane's HWND).
206 if (UILayoutIsRightToLeft())
207 l10n_util::HWNDSetRTLLayout(tab_control);
208
209 RootView* root_view = content_window_->GetRootView();
210 root_view->SetLayoutManager(new FillLayout());
211 DWORD sys_color = ::GetSysColor(COLOR_3DHILIGHT);
212 SkColor color = SkColorSetRGB(GetRValue(sys_color), GetGValue(sys_color),
213 GetBValue(sys_color));
214 root_view->set_background(Background::CreateSolidBackground(color));
215
216 content_window_->SetFocusTraversableParentView(this);
217 ResizeContents();
218
219 NativeControlCreated(tab_control);
220 }
221
222 bool NativeTabbedPaneWin::ProcessMessage(UINT message,
223 WPARAM w_param,
224 LPARAM l_param,
225 LRESULT* result) {
226 if (message == WM_NOTIFY &&
227 reinterpret_cast<LPNMHDR>(l_param)->code == TCN_SELCHANGE) {
228 int selected_tab = TabCtrl_GetCurSel(native_view());
229 DCHECK(selected_tab != -1);
230 DoSelectTabAt(selected_tab);
231 return TRUE;
232 }
233 return NativeControlWin::ProcessMessage(message, w_param, l_param, result);
234 }
235
236 ////////////////////////////////////////////////////////////////////////////////
237 // View override:
238
239 void NativeTabbedPaneWin::Layout() {
240 NativeControlWin::Layout();
241 ResizeContents();
242 }
243
244 FocusTraversable* NativeTabbedPaneWin::GetFocusTraversable() {
245 return content_window_;
246 }
247
248 void NativeTabbedPaneWin::ViewHierarchyChanged(bool is_add,
249 View *parent,
250 View *child) {
251 NativeControlWin::ViewHierarchyChanged(is_add, parent, child);
252
253 if (is_add && (child == this) && content_window_) {
254 // We have been added to a view hierarchy, update the FocusTraversable
255 // parent.
256 content_window_->SetFocusTraversableParent(GetRootView());
257 }
258 }
259
260 ////////////////////////////////////////////////////////////////////////////////
261 // NativeTabbedPaneWin, private:
262
263 void NativeTabbedPaneWin::DoSelectTabAt(int index) {
264 RootView* content_root = content_window_->GetRootView();
265
266 // Clear the focus if the focused view was on the tab.
267 FocusManager* focus_manager = GetFocusManager();
268 DCHECK(focus_manager);
269 View* focused_view = focus_manager->GetFocusedView();
270 if (focused_view && content_root->IsParentOf(focused_view))
271 focus_manager->ClearFocus();
272
273 content_root->RemoveAllChildViews(false);
274 content_root->AddChildView(tab_views_[index]);
275 content_root->Layout();
276
277 if (tabbed_pane_->listener())
278 tabbed_pane_->listener()->TabSelectedAt(index);
279 }
280
281 void NativeTabbedPaneWin::ResizeContents() {
282 CRect content_bounds;
283 if (!GetClientRect(native_view(), &content_bounds))
284 return;
285 TabCtrl_AdjustRect(native_view(), FALSE, &content_bounds);
286 content_window_->MoveWindow(content_bounds.left, content_bounds.top,
287 content_bounds.Width(), content_bounds.Height(),
288 TRUE);
289 }
290
291 ////////////////////////////////////////////////////////////////////////////////
292 // NativeTabbedPaneWrapper, public:
293
294 // static
295 NativeTabbedPaneWrapper* NativeTabbedPaneWrapper::CreateNativeWrapper(
296 TabbedPane* tabbed_pane) {
297 return new NativeTabbedPaneWin(tabbed_pane);
298 }
299
300 } // namespace views
OLDNEW
« no previous file with comments | « views/controls/tabbed_pane/native_tabbed_pane_win.h ('k') | views/controls/tabbed_pane/native_tabbed_pane_wrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698