Merge branch 'bugfix-main-thread-root'
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms.Theming / VisualStyles / TabControlPainter.cs
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:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
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.
19 //
20 // Copyright (c) 2008 George Giolfan
21 //
22 // Authors:
23 //      George Giolfan (georgegiolfan@yahoo.com)
24
25 using System.Drawing;
26 using System.Windows.Forms.VisualStyles;
27 namespace System.Windows.Forms.Theming.VisualStyles
28 {
29         class TabControlPainter : Default.TabControlPainter
30         {
31                 static bool ShouldPaint (TabControl tabControl) {
32                         return ThemeVisualStyles.RenderClientAreas &&
33                                 tabControl.Alignment == TabAlignment.Top &&
34                                 tabControl.DrawMode == TabDrawMode.Normal;
35                 }
36                 protected override void DrawBackground (Graphics dc, Rectangle area, TabControl tab)
37                 {
38                         if (!ShouldPaint (tab)) {
39                                 base.DrawBackground (dc, area, tab);
40                                 return;
41                         }
42
43                         VisualStyleElement element = VisualStyleElement.Tab.Pane.Normal;
44                         if (!VisualStyleRenderer.IsElementDefined (element)) {
45                                 base.DrawBackground (dc, area, tab);
46                                 return;
47                         }
48                         Rectangle panel_rectangle = GetTabPanelRect (tab);
49                         if (panel_rectangle.IntersectsWith (area))
50                                 new VisualStyleRenderer (element).DrawBackground (dc, panel_rectangle, area);
51                 }
52                 protected override int DrawTab (Graphics dc, TabPage page, TabControl tab, Rectangle bounds, bool is_selected)
53                 {
54                         if (!ShouldPaint (tab))
55                                 return base.DrawTab (dc, page, tab, bounds, is_selected);
56                         VisualStyleElement element = GetVisualStyleElement (tab, page, is_selected);
57                         if (!VisualStyleRenderer.IsElementDefined (element))
58                                 return base.DrawTab (dc, page, tab, bounds, is_selected);
59                         new VisualStyleRenderer (element).DrawBackground (dc, bounds);
60                         bounds.Inflate (
61                                 -(tab.Padding.X),
62                                 -(tab.Padding.Y));
63                         Rectangle text_area = bounds;
64                         if (tab.ImageList != null && page.ImageIndex >= 0 && page.ImageIndex < tab.ImageList.Images.Count) {
65                                 int image_y = bounds.Y + (bounds.Height - tab.ImageList.ImageSize.Height) / 2;
66                                 tab.ImageList.Draw (dc, new Point (bounds.X, image_y), page.ImageIndex);
67                                 int image_occupied_space = tab.ImageList.ImageSize.Width + 2;
68                                 text_area.X += image_occupied_space;
69                                 text_area.Width -= image_occupied_space;
70                         }
71                         if (page.Text != null)
72                                 dc.DrawString (page.Text, tab.Font, SystemBrushes.ControlText, text_area, DefaultFormatting);
73                         if (tab.Focused && is_selected && tab.ShowFocusCues)
74                                 ControlPaint.DrawFocusRectangle (dc, bounds);
75                         return 0;
76                 }
77                 static VisualStyleElement GetVisualStyleElement (TabControl tabControl, TabPage tabPage, bool selected)
78                 {
79                         bool top_edge = tabPage.Row == tabControl.RowCount;
80                         int tab_page_index = tabControl.TabPages.IndexOf (tabPage);
81                         bool left_edge = true;
82                         int index;
83                         for (index = tabControl.SliderPos; index < tab_page_index; index++)
84                                 if (tabControl.TabPages [index].Row == tabPage.Row) {
85                                         left_edge = false;
86                                         break;
87                                 }
88                         bool right_edge = true;
89                         for (index = tab_page_index; index < tabControl.TabCount; index++)
90                                 if (tabControl.TabPages [index].Row == tabPage.Row) {
91                                         right_edge = false;
92                                         break;
93                                 }
94                         if (!tabPage.Enabled)
95                                 #region Disabled
96                                 if (top_edge)
97                                         if (left_edge)
98                                                 if (right_edge)
99                                                         return VisualStyleElement.Tab.TopTabItem.Disabled;
100                                                 else
101                                                         return VisualStyleElement.Tab.TopTabItemLeftEdge.Disabled;
102                                         else
103                                                 if (right_edge)
104                                                         return VisualStyleElement.Tab.TopTabItemRightEdge.Disabled;
105                                                 else
106                                                         return VisualStyleElement.Tab.TopTabItem.Disabled;
107                                 else
108                                         if (left_edge)
109                                                 if (right_edge)
110                                                         return VisualStyleElement.Tab.TabItem.Disabled;
111                                                 else
112                                                         return VisualStyleElement.Tab.TabItemLeftEdge.Disabled;
113                                         else
114                                                 if (right_edge)
115                                                         return VisualStyleElement.Tab.TabItemRightEdge.Disabled;
116                                                 else
117                                                         return VisualStyleElement.Tab.TabItem.Disabled;
118                                 #endregion
119                         else if (selected)
120                                 #region Pressed
121                                 if (top_edge)
122                                         if (left_edge)
123                                                 if (right_edge)
124                                                         return VisualStyleElement.Tab.TopTabItem.Pressed;
125                                                 else
126                                                         return VisualStyleElement.Tab.TopTabItemLeftEdge.Pressed;
127                                         else
128                                                 if (right_edge)
129                                                         return VisualStyleElement.Tab.TopTabItemRightEdge.Pressed;
130                                                 else
131                                                         return VisualStyleElement.Tab.TopTabItem.Pressed;
132                                 else
133                                         if (left_edge)
134                                                 if (right_edge)
135                                                         return VisualStyleElement.Tab.TabItem.Pressed;
136                                                 else
137                                                         return VisualStyleElement.Tab.TabItemLeftEdge.Pressed;
138                                         else
139                                                 if (right_edge)
140                                                         return VisualStyleElement.Tab.TabItemRightEdge.Pressed;
141                                                 else
142                                                         return VisualStyleElement.Tab.TabItem.Pressed;
143                                 #endregion
144                         else if (tabControl.EnteredTabPage == tabPage)
145                                 #region Hot
146                                 if (top_edge)
147                                         if (left_edge)
148                                                 if (right_edge)
149                                                         return VisualStyleElement.Tab.TopTabItem.Hot;
150                                                 else
151                                                         return VisualStyleElement.Tab.TopTabItemLeftEdge.Hot;
152                                         else
153                                                 if (right_edge)
154                                                         return VisualStyleElement.Tab.TopTabItemRightEdge.Hot;
155                                                 else
156                                                         return VisualStyleElement.Tab.TopTabItem.Hot;
157                                 else
158                                         if (left_edge)
159                                                 if (right_edge)
160                                                         return VisualStyleElement.Tab.TabItem.Hot;
161                                                 else
162                                                         return VisualStyleElement.Tab.TabItemLeftEdge.Hot;
163                                         else
164                                                 if (right_edge)
165                                                         return VisualStyleElement.Tab.TabItemRightEdge.Hot;
166                                                 else
167                                                         return VisualStyleElement.Tab.TabItem.Hot;
168                                 #endregion
169                         else
170                                 #region Normal
171                                 if (top_edge)
172                                         if (left_edge)
173                                                 if (right_edge)
174                                                         return VisualStyleElement.Tab.TopTabItemBothEdges.Normal;
175                                                 else
176                                                         return VisualStyleElement.Tab.TopTabItemLeftEdge.Normal;
177                                         else
178                                                 if (right_edge)
179                                                         return VisualStyleElement.Tab.TopTabItemRightEdge.Normal;
180                                                 else
181                                                         return VisualStyleElement.Tab.TopTabItem.Normal;
182                                 else
183                                         if (left_edge)
184                                                 if (right_edge)
185                                                         return VisualStyleElement.Tab.TabItemBothEdges.Normal;
186                                                 else
187                                                         return VisualStyleElement.Tab.TabItemLeftEdge.Normal;
188                                         else
189                                                 if (right_edge)
190                                                         return VisualStyleElement.Tab.TabItemRightEdge.Normal;
191                                                 else
192                                                         return VisualStyleElement.Tab.TabItem.Normal;
193                                 #endregion
194                 }
195                 public override bool HasHotElementStyles (TabControl tabControl)
196                 {
197                         if (!ShouldPaint (tabControl))
198                                 return base.HasHotElementStyles (tabControl);
199                         return true;
200                 }
201                 protected override void DrawScrollButton (Graphics dc, Rectangle bounds, Rectangle clippingArea, ScrollButton button, PushButtonState state)
202                 {
203                         if (!ThemeVisualStyles.RenderClientAreas) {
204                                 base.DrawScrollButton (dc, bounds, clippingArea, button, state);
205                                 return;
206                         }
207                         VisualStyleElement element;
208                         if (button == ScrollButton.Left)
209                                 switch (state) {
210                                 case PushButtonState.Hot:
211                                         element = VisualStyleElement.Spin.DownHorizontal.Hot;
212                                         break;
213                                 case PushButtonState.Pressed:
214                                         element = VisualStyleElement.Spin.DownHorizontal.Pressed;
215                                         break;
216                                 default:
217                                         element = VisualStyleElement.Spin.DownHorizontal.Normal;
218                                         break;
219                                 }
220                         else
221                                 switch (state) {
222                                 case PushButtonState.Hot:
223                                         element = VisualStyleElement.Spin.UpHorizontal.Hot;
224                                         break;
225                                 case PushButtonState.Pressed:
226                                         element = VisualStyleElement.Spin.UpHorizontal.Pressed;
227                                         break;
228                                 default:
229                                         element = VisualStyleElement.Spin.UpHorizontal.Normal;
230                                         break;
231                                 }
232                         if (!VisualStyleRenderer.IsElementDefined (element)) {
233                                 if (button == ScrollButton.Left)
234                                         switch (state) {
235                                         case PushButtonState.Hot:
236                                                 element = VisualStyleElement.ScrollBar.ArrowButton.LeftHot;
237                                                 break;
238                                         case PushButtonState.Pressed:
239                                                 element = VisualStyleElement.ScrollBar.ArrowButton.LeftPressed;
240                                                 break;
241                                         default:
242                                                 element = VisualStyleElement.ScrollBar.ArrowButton.LeftNormal;
243                                                 break;
244                                         }
245                                 else
246                                         switch (state) {
247                                         case PushButtonState.Hot:
248                                                 element = VisualStyleElement.ScrollBar.ArrowButton.RightHot;
249                                                 break;
250                                         case PushButtonState.Pressed:
251                                                 element = VisualStyleElement.ScrollBar.ArrowButton.RightPressed;
252                                                 break;
253                                         default:
254                                                 element = VisualStyleElement.ScrollBar.ArrowButton.RightNormal;
255                                                 break;
256                                         }
257                                 if (!VisualStyleRenderer.IsElementDefined (element)) {
258                                         base.DrawScrollButton (dc, bounds, clippingArea, button, state);
259                                         return;
260                                 }
261                         }
262                         new VisualStyleRenderer (element).DrawBackground (dc, bounds, clippingArea);
263                 }
264         }
265 }