1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2008 George Giolfan
23 // George Giolfan (georgegiolfan@yahoo.com)
25 using System.Windows.Forms.VisualStyles;
27 namespace System.Windows.Forms.Theming.VisualStyles
29 class TabControlPainter : Default.TabControlPainter
31 static bool ShouldPaint (TabControl tabControl) {
32 return tabControl.Alignment == TabAlignment.Top &&
33 tabControl.DrawMode == TabDrawMode.Normal;
35 public override void Draw (Graphics dc, Rectangle area, TabControl tab) {
36 if (!ShouldPaint (tab)) {
37 base.Draw (dc, area, tab);
41 VisualStyleElement element = VisualStyleElement.Tab.Pane.Normal;
42 if (!VisualStyleRenderer.IsElementDefined (element)) {
43 base.Draw (dc, area, tab);
46 Rectangle panel_rectangle = GetTabPanelRect (tab);
47 if (panel_rectangle.IntersectsWith (area))
48 new VisualStyleRenderer (element).DrawBackground (dc, panel_rectangle, area);
50 //TODO: The base method should be refactored to allow this class to override only what it needs to.
52 int end = tab.TabPages.Count;
55 if (tab.Alignment == TabAlignment.Top) {
61 for (; counter != end; counter += delta) {
62 for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
63 if (i == tab.SelectedIndex)
65 if (counter != tab.TabPages[i].Row)
67 Rectangle rect = tab.GetTabRect (i);
68 if (!rect.IntersectsWith (area))
70 DrawTab (dc, tab.TabPages[i], tab, rect, false);
74 if (tab.SelectedIndex != -1 && tab.SelectedIndex >= tab.SliderPos) {
75 Rectangle rect = tab.GetTabRect (tab.SelectedIndex);
76 if (rect.IntersectsWith (area))
77 DrawTab (dc, tab.TabPages[tab.SelectedIndex], tab, rect, true);
81 Rectangle right = GetRightScrollRect (tab);
82 Rectangle left = GetLeftScrollRect (tab);
83 ControlPaint.DrawScrollButton (dc, right, ScrollButton.Right, tab.RightSliderState);
84 ControlPaint.DrawScrollButton (dc, left, ScrollButton.Left, tab.LeftSliderState);
87 protected override int DrawTab (Graphics dc, TabPage page, TabControl tab, Rectangle bounds, bool is_selected)
89 if (!ShouldPaint (tab))
90 return base.DrawTab (dc, page, tab, bounds, is_selected);
91 VisualStyleElement element = GetVisualStyleElement (tab, page, is_selected);
92 if (!VisualStyleRenderer.IsElementDefined (element))
93 return base.DrawTab (dc, page, tab, bounds, is_selected);
94 new VisualStyleRenderer (element).DrawBackground (dc, bounds);
96 -(FocusRectSpacing.X + BorderThickness.X),
97 -(FocusRectSpacing.Y + BorderThickness.Y));
98 Rectangle text_area = bounds;
99 if (tab.ImageList != null && page.ImageIndex >= 0 && page.ImageIndex < tab.ImageList.Images.Count) {
100 int image_y = bounds.Y + (bounds.Height - tab.ImageList.ImageSize.Height) / 2;
101 tab.ImageList.Draw (dc, new Point (bounds.X, image_y), page.ImageIndex);
102 int image_occupied_space = tab.ImageList.ImageSize.Width + 2;
103 text_area.X += image_occupied_space;
104 text_area.Width -= image_occupied_space;
106 if (page.Text != null)
107 dc.DrawString (page.Text, page.Font, SystemBrushes.ControlText, text_area, DefaultFormatting);
108 if (tab.Focused && is_selected)
109 ControlPaint.DrawFocusRectangle (dc, bounds);
112 static VisualStyleElement GetVisualStyleElement (TabControl tabControl, TabPage tabPage, bool selected)
114 bool top_edge = tabPage.Row == tabControl.RowCount;
115 int tab_page_index = tabControl.TabPages.IndexOf (tabPage);
116 bool left_edge = true;
118 for (index = tabControl.SliderPos; index < tab_page_index; index++)
119 if (tabControl.TabPages [index].Row == tabPage.Row) {
123 bool right_edge = true;
124 for (index = tab_page_index; index < tabControl.TabCount; index++)
125 if (tabControl.TabPages [index].Row == tabPage.Row) {
129 if (!tabPage.Enabled)
134 return VisualStyleElement.Tab.TopTabItem.Disabled;
136 return VisualStyleElement.Tab.TopTabItemLeftEdge.Disabled;
139 return VisualStyleElement.Tab.TopTabItemRightEdge.Disabled;
141 return VisualStyleElement.Tab.TopTabItem.Disabled;
145 return VisualStyleElement.Tab.TabItem.Disabled;
147 return VisualStyleElement.Tab.TabItemLeftEdge.Disabled;
150 return VisualStyleElement.Tab.TabItemRightEdge.Disabled;
152 return VisualStyleElement.Tab.TabItem.Disabled;
154 /*TODO Repaint the tab when the mouse enters or leaves its area.
160 return VisualStyleElement.Tab.TopTabItem.Hot;
162 return VisualStyleElement.Tab.TopTabItemLeftEdge.Hot;
165 return VisualStyleElement.Tab.TopTabItemRightEdge.Hot;
167 return VisualStyleElement.Tab.TopTabItem.Hot;
171 return VisualStyleElement.Tab.TabItem.Hot;
173 return VisualStyleElement.Tab.TabItemLeftEdge.Hot;
176 return VisualStyleElement.Tab.TabItemRightEdge.Hot;
178 return VisualStyleElement.Tab.TabItem.Hot;
186 return VisualStyleElement.Tab.TopTabItem.Pressed;
188 return VisualStyleElement.Tab.TopTabItemLeftEdge.Pressed;
191 return VisualStyleElement.Tab.TopTabItemRightEdge.Pressed;
193 return VisualStyleElement.Tab.TopTabItem.Pressed;
197 return VisualStyleElement.Tab.TabItem.Pressed;
199 return VisualStyleElement.Tab.TabItemLeftEdge.Pressed;
202 return VisualStyleElement.Tab.TabItemRightEdge.Pressed;
204 return VisualStyleElement.Tab.TabItem.Pressed;
211 return VisualStyleElement.Tab.TopTabItemBothEdges.Normal;
213 return VisualStyleElement.Tab.TopTabItemLeftEdge.Normal;
216 return VisualStyleElement.Tab.TopTabItemRightEdge.Normal;
218 return VisualStyleElement.Tab.TopTabItem.Normal;
222 return VisualStyleElement.Tab.TabItemBothEdges.Normal;
224 return VisualStyleElement.Tab.TabItemLeftEdge.Normal;
227 return VisualStyleElement.Tab.TabItemRightEdge.Normal;
229 return VisualStyleElement.Tab.TabItem.Normal;
234 // Permission is hereby granted, free of charge, to any person obtaining
235 // a copy of this software and associated documentation files (the
236 // "Software"), to deal in the Software without restriction, including
237 // without limitation the rights to use, copy, modify, merge, publish,
238 // distribute, sublicense, and/or sell copies of the Software, and to
239 // permit persons to whom the Software is furnished to do so, subject to
240 // the following conditions:
242 // The above copyright notice and this permission notice shall be
243 // included in all copies or substantial portions of the Software.
245 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
246 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
247 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
248 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
249 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
250 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
251 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
253 // Copyright (c) 2008 George Giolfan
256 // George Giolfan (georgegiolfan@yahoo.com)
258 using System.Windows.Forms.VisualStyles;
259 using System.Drawing;
260 namespace System.Windows.Forms.Theming.VisualStyles
262 class TabControlPainter : Default.TabControlPainter
264 static bool ShouldPaint (TabControl tabControl) {
265 return tabControl.Alignment == TabAlignment.Top &&
266 tabControl.DrawMode == TabDrawMode.Normal;
268 public override void Draw (Graphics dc, Rectangle area, TabControl tab) {
269 if (!ShouldPaint (tab)) {
270 base.Draw (dc, area, tab);
274 VisualStyleElement element = VisualStyleElement.Tab.Pane.Normal;
275 if (!VisualStyleRenderer.IsElementDefined (element)) {
276 base.Draw (dc, area, tab);
279 Rectangle panel_rectangle = GetTabPanelRect (tab);
280 if (panel_rectangle.IntersectsWith (area))
281 new VisualStyleRenderer (element).DrawBackground (dc, panel_rectangle, area);
283 //TODO: The base method should be refactored to allow this class to override only what it needs to.
285 int end = tab.TabPages.Count;
288 if (tab.Alignment == TabAlignment.Top) {
294 for (; counter != end; counter += delta) {
295 for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
296 if (i == tab.SelectedIndex)
298 if (counter != tab.TabPages[i].Row)
300 Rectangle rect = tab.GetTabRect (i);
301 if (!rect.IntersectsWith (area))
303 DrawTab (dc, tab.TabPages[i], tab, rect, false);
307 if (tab.SelectedIndex != -1 && tab.SelectedIndex >= tab.SliderPos) {
308 Rectangle rect = tab.GetTabRect (tab.SelectedIndex);
309 if (rect.IntersectsWith (area))
310 DrawTab (dc, tab.TabPages[tab.SelectedIndex], tab, rect, true);
313 if (tab.ShowSlider) {
314 Rectangle right = GetRightScrollRect (tab);
315 Rectangle left = GetLeftScrollRect (tab);
316 ControlPaint.DrawScrollButton (dc, right, ScrollButton.Right, tab.RightSliderState);
317 ControlPaint.DrawScrollButton (dc, left, ScrollButton.Left, tab.LeftSliderState);
320 protected override int DrawTab (Graphics dc, TabPage page, TabControl tab, Rectangle bounds, bool is_selected)
322 if (!ShouldPaint (tab))
323 return base.DrawTab (dc, page, tab, bounds, is_selected);
324 VisualStyleElement element = GetVisualStyleElement (tab, page, is_selected);
325 if (!VisualStyleRenderer.IsElementDefined (element))
326 return base.DrawTab (dc, page, tab, bounds, is_selected);
327 new VisualStyleRenderer (element).DrawBackground (dc, bounds);
329 -(FocusRectSpacing.X + BorderThickness.X),
330 -(FocusRectSpacing.Y + BorderThickness.Y));
331 Rectangle text_area = bounds;
332 if (tab.ImageList != null && page.ImageIndex >= 0 && page.ImageIndex < tab.ImageList.Images.Count) {
333 int image_y = bounds.Y + (bounds.Height - tab.ImageList.ImageSize.Height) / 2;
334 tab.ImageList.Draw (dc, new Point (bounds.X, image_y), page.ImageIndex);
335 int image_occupied_space = tab.ImageList.ImageSize.Width + 2;
336 text_area.X += image_occupied_space;
337 text_area.Width -= image_occupied_space;
339 if (page.Text != null)
340 dc.DrawString (page.Text, page.Font, SystemBrushes.ControlText, text_area, DefaultFormatting);
341 if (tab.Focused && is_selected)
342 ControlPaint.DrawFocusRectangle (dc, bounds);
345 static VisualStyleElement GetVisualStyleElement (TabControl tabControl, TabPage tabPage, bool selected)
347 bool top_edge = tabPage.Row == tabControl.RowCount;
348 int tab_page_index = tabControl.TabPages.IndexOf (tabPage);
349 bool left_edge = true;
351 for (index = tabControl.SliderPos; index < tab_page_index; index++)
352 if (tabControl.TabPages [index].Row == tabPage.Row) {
356 bool right_edge = true;
357 for (index = tab_page_index; index < tabControl.TabCount; index++)
358 if (tabControl.TabPages [index].Row == tabPage.Row) {
362 if (!tabPage.Enabled)
367 return VisualStyleElement.Tab.TopTabItem.Disabled;
369 return VisualStyleElement.Tab.TopTabItemLeftEdge.Disabled;
372 return VisualStyleElement.Tab.TopTabItemRightEdge.Disabled;
374 return VisualStyleElement.Tab.TopTabItem.Disabled;
378 return VisualStyleElement.Tab.TabItem.Disabled;
380 return VisualStyleElement.Tab.TabItemLeftEdge.Disabled;
383 return VisualStyleElement.Tab.TabItemRightEdge.Disabled;
385 return VisualStyleElement.Tab.TabItem.Disabled;
387 /*TODO Repaint the tab when the mouse enters or leaves its area.
393 return VisualStyleElement.Tab.TopTabItem.Hot;
395 return VisualStyleElement.Tab.TopTabItemLeftEdge.Hot;
398 return VisualStyleElement.Tab.TopTabItemRightEdge.Hot;
400 return VisualStyleElement.Tab.TopTabItem.Hot;
404 return VisualStyleElement.Tab.TabItem.Hot;
406 return VisualStyleElement.Tab.TabItemLeftEdge.Hot;
409 return VisualStyleElement.Tab.TabItemRightEdge.Hot;
411 return VisualStyleElement.Tab.TabItem.Hot;
419 return VisualStyleElement.Tab.TopTabItem.Pressed;
421 return VisualStyleElement.Tab.TopTabItemLeftEdge.Pressed;
424 return VisualStyleElement.Tab.TopTabItemRightEdge.Pressed;
426 return VisualStyleElement.Tab.TopTabItem.Pressed;
430 return VisualStyleElement.Tab.TabItem.Pressed;
432 return VisualStyleElement.Tab.TabItemLeftEdge.Pressed;
435 return VisualStyleElement.Tab.TabItemRightEdge.Pressed;
437 return VisualStyleElement.Tab.TabItem.Pressed;
444 return VisualStyleElement.Tab.TopTabItemBothEdges.Normal;
446 return VisualStyleElement.Tab.TopTabItemLeftEdge.Normal;
449 return VisualStyleElement.Tab.TopTabItemRightEdge.Normal;
451 return VisualStyleElement.Tab.TopTabItem.Normal;
455 return VisualStyleElement.Tab.TabItemBothEdges.Normal;
457 return VisualStyleElement.Tab.TabItemLeftEdge.Normal;
460 return VisualStyleElement.Tab.TabItemRightEdge.Normal;
462 return VisualStyleElement.Tab.TabItem.Normal;