+2006-12-27 Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+ * ListView.cs:
+ * ListViewItem.cs:
+ * ThemeWin32Classic.cs:
+ * Theme.cs: Initial support for Tile view in ListView,
+ as well as the implementation of the required bits for it (Item
+ and Subitem).
+
2006-12-27 Gert Driesen <drieseng@users.sourceforge.net>
* MonthCalendar.cs: On 2.0, throw ArgumentOutOfRangeException instead
private string keysearch_text;
static private readonly int keysearch_keydelay = 1000;
private int[] reordered_column_indices;
+#if NET_2_0
+ private Size tile_size;
+#endif
// internal variables
internal ImageList large_image_list;
}
}
+#if NET_2_0
+ public Size TileSize {
+ get {
+ return tile_size;
+ }
+ set {
+ if (value.Width <= 0 || value.Height <= 0)
+ throw new ArgumentOutOfRangeException ("value");
+
+ tile_size = value;
+ Redraw (true);
+ }
+ }
+#endif
+
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public ListViewItem TopItem {
}
}
+#if NET_2_0
+ Size TileItemSize {
+ get {
+ // Calculate tile size if needed
+ // It appears that using Font.Size instead of a SizeF value can give us
+ // a slightly better approach to the proportions defined in .Net
+ if (tile_size == Size.Empty) {
+ int image_w = LargeImageList == null ? 0 : LargeImageList.ImageSize.Width;
+ int image_h = LargeImageList == null ? 0 : LargeImageList.ImageSize.Height;
+ int w = (int)Font.Size * ThemeEngine.Current.ListViewTileWidthFactor + image_w + 4;
+ int h = Math.Max ((int)Font.Size * ThemeEngine.Current.ListViewTileHeightFactor, image_h);
+
+ tile_size = new Size (w, h);
+ }
+
+ return tile_size;
+ }
+ }
+#endif
+
int rows;
int cols;
ListViewItem[,] item_matrix;
- void LayoutIcons (bool large_icons, bool left_aligned, int x_spacing, int y_spacing)
+ void LayoutIcons (Size item_size, bool left_aligned, int x_spacing, int y_spacing)
{
header_control.Visible = false;
header_control.Size = Size.Empty;
if (items.Count == 0)
return;
- Size sz = large_icons ? LargeIconItemSize : SmallIconItemSize;
-
+ Size sz = item_size;
Rectangle area = ClientRectangle;
if (left_aligned) {
break;
case View.SmallIcon:
- LayoutIcons (false, alignment == ListViewAlignment.Left, 4, 2);
+ LayoutIcons (SmallIconItemSize, alignment == ListViewAlignment.Left, 4, 2);
break;
case View.LargeIcon:
- LayoutIcons (true, alignment == ListViewAlignment.Left,
+ LayoutIcons (LargeIconItemSize, alignment == ListViewAlignment.Left,
ThemeEngine.Current.ListViewHorizontalSpacing,
ThemeEngine.Current.ListViewVerticalSpacing);
break;
case View.List:
- LayoutIcons (false, true, 4, 2);
+ LayoutIcons (SmallIconItemSize, true, 4, 2);
break;
+#if NET_2_0
+ case View.Tile:
+ LayoutIcons (TileItemSize, alignment == ListViewAlignment.Left,
+ ThemeEngine.Current.ListViewHorizontalSpacing,
+ ThemeEngine.Current.ListViewVerticalSpacing);
+ break;
+#endif
}
CalculateScrollBars ();
total = Rectangle.Union (item_rect, checkbox_rect);
bounds.Size = total.Size;
break;
+#if NET_2_0
+ case View.Tile:
+ label_rect = icon_rect = Rectangle.Empty;
+
+ if (owner.LargeImageList != null) {
+ icon_rect.Width = owner.LargeImageList.ImageSize.Width;
+ icon_rect.Height = owner.LargeImageList.ImageSize.Height;
+ }
+
+ int separation = 2;
+ SizeF tsize = owner.DeviceContext.MeasureString (Text, Font);
+
+ // Set initial values for subitem's layout
+ int total_height = (int)Math.Ceiling (tsize.Height);
+ int max_subitem_width = (int)Math.Ceiling (tsize.Width);
+ SubItems [0].bounds.Height = total_height;
+
+ int count = Math.Min (owner.Columns.Count, SubItems.Count);
+ for (int i = 1; i < count; i++) { // Ignore first column and first subitem
+ ListViewSubItem sub_item = SubItems [i];
+ if (sub_item.Text == null || sub_item.Text.Length == 0)
+ continue;
+
+ tsize = owner.DeviceContext.MeasureString (sub_item.Text, sub_item.Font);
+
+ int width = (int)Math.Ceiling (tsize.Width);
+
+ if (width > max_subitem_width)
+ max_subitem_width = width;
+
+ int height = (int)Math.Ceiling (tsize.Height);
+ total_height += height + separation;
+
+ sub_item.bounds.Height = height;
+
+ }
+
+ label_rect.X = icon_rect.Right + 4;
+ label_rect.Y = owner.TileSize.Height / 2 - total_height / 2;
+ label_rect.Width = max_subitem_width;
+ label_rect.Height = total_height;
+
+ // Second pass for assigning bounds. This time take first subitem into account.
+ int current_y = label_rect.Y;
+ for (int j = 0; j < count; j++) {
+ ListViewSubItem sub_item = SubItems [j];
+ if (sub_item.Text == null || sub_item.Text.Length == 0)
+ continue;
+
+ sub_item.SetBounds (label_rect.X, current_y, max_subitem_width, sub_item.bounds.Height);
+ current_y += sub_item.Bounds.Height + separation;
+ }
+
+ item_rect = Rectangle.Union (icon_rect, label_rect);
+ bounds.Size = item_rect.Size;
+ break;
+#endif
}
}
#if NET_2_0
private string name = String.Empty;
private object tag;
+ internal Rectangle bounds;
#endif
#region Public Constructors
}
}
+#if NET_2_0
+ public Rectangle Bounds {
+ get {
+ Rectangle retval = bounds;
+ if (owner != null) {
+ retval.X += owner.Bounds.X;
+ retval.Y += owner.Bounds.Y;
+ }
+
+ return retval;
+ }
+ }
+#endif
+
[Localizable (true)]
public Font Font {
get {
owner.owner.Invalidate ();
}
+
+#if NET_2_0
+ internal void SetBounds (int x, int y, int width, int height)
+ {
+ bounds = new Rectangle (x, y, width, height);
+ }
+#endif
#endregion // Private Methods
}
public abstract int ListViewHorizontalSpacing { get; }
public abstract Size ListViewDefaultSize { get; }
public abstract int ListViewGroupHeight { get; }
+ public abstract int ListViewTileWidthFactor { get; }
+ public abstract int ListViewTileHeightFactor { get; }
#endregion // ListView
#region Menus
}
// Draw corner between the two scrollbars
- if (control.h_scroll.Visible == true && control.h_scroll.Visible == true) {
+ if (control.h_scroll.Visible == true && control.v_scroll.Visible == true) {
Rectangle rect = new Rectangle ();
rect.X = control.h_scroll.Location.X + control.h_scroll.Width;
rect.Width = control.v_scroll.Width;
Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label);
text_rect.X += col_offset;
+#if NET_2_0
+ // Tile view doesn't support CheckBoxes
+ if (control.CheckBoxes && control.View != View.Tile) {
+#else
if (control.CheckBoxes) {
+#endif
if (control.StateImageList == null) {
// Make sure we've got at least a line width of 1
int check_wd = Math.Max (3, rect_checkrect.Width / 6);
}
}
- ImageList image_list = control.View == View.LargeIcon ? control.LargeImageList :
- control.SmallImageList;
+ ImageList image_list = control.View == View.LargeIcon
+#if NET_2_0
+ || control.View == View.Tile
+#endif
+ ? control.LargeImageList : control.SmallImageList;
if (image_list != null) {
int idx;
(item.Selected && control.Focused) ? SystemBrushes.HighlightText :
this.ResPool.GetSolidBrush (item.ForeColor);
+#if NET_2_0
+ // Tile view renders its Text in a different fashion
+ if (control.View == View.Tile) {
+ // Item.Text is drawn using its first subitem's bounds
+ dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format);
+
+ int count = Math.Min (control.Columns.Count, item.SubItems.Count);
+ for (int i = 1; i < count; i++) {
+ ListViewItem.ListViewSubItem sub_item = item.SubItems [i];
+ if (sub_item.Text == null || sub_item.Text.Length == 0)
+ continue;
+
+ Brush itemBrush = item.Selected && control.Focused ?
+ SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor);
+ dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format);
+ }
+ } else
+#endif
+
if (item.Text != null && item.Text.Length > 0) {
if (item.Selected && control.Focused)
dc.DrawString (item.Text, item.Font, textBrush, highlight_rect, format);
}
}
}
-
+
if (item.Focused && control.Focused) {
Rectangle focus_rect = highlight_rect;
if (control.FullRowSelect && control.View == View.Details) {
public override int ListViewGroupHeight {
get { return 20; }
}
+
+ public override int ListViewTileWidthFactor {
+ get { return 22; }
+ }
+
+ public override int ListViewTileHeightFactor {
+ get { return 3; }
+ }
#endregion // ListView
#region Menus