четверг, 11 декабря 2008 г.

Folding Panel (Opera style) Схлопывающаяся панель

Как-то недавно встала проблемма отображения нескольких панелек на одной ВинФорме и не известно какой панелью будет пользователь чаще а какая ему в большенстве случаев не понядобится. И тут я обратил внимание на букмарки в опере. Собственно и решил написать свою реализацию. Честно говоря наткнулся на несколько полезных советов на блоге одного иностранца, но потерял ссылку=\ Щас выложу черновой вариант, позженадеюсь дописать контрол и менеджер к нему.



  public class AdvancedPanel : Panel {
    protected Rectangle upperRect;
    protected Rectangle UpperRect {
      get {
        if (upperRect.Height != this.Height || upperRect.Width != this.Width) {
          this.upperRect = new Rectangle(0, 0, this.Width - 1, height);
        }
        return this.upperRect;
      }
    }
    protected int height = 5;
    public Size MaximaizedSize;
    public Size minimaizedSize;
    public Size MinimaizedSize {
      get {
        if (this.minimaizedSize.Width != this.Width) {
          this.minimaizedSize = new Size(this.Size.Width, this.height);
        }
        return this.minimaizedSize;
      }
    }
    public AdvancedPanel() {
      this.MaximaizedSize = new Size(100, 100);
      this.minimaizedSize = new Size(this.Size.Width, this.height);
      this.upperRect = new Rectangle(0, 0, this.Width - 1, height);
      this.MouseDown += new MouseEventHandler(AdvancedPanel_MouseDown);
      this.SetStyle(ControlStyles.ResizeRedraw, true);
    }

    void AdvancedPanel_MouseDown(object sender, MouseEventArgs e) {
      if (e.X <= this.upperRect.Width && e.Y <= this.upperRect.Height) {
        if (!this.IsMinimaized) {
          this.MaximaizedSize = this.Size;
        }
        this.Size = this.IsMinimaized ? this.MaximaizedSize : this.MinimaizedSize;
        this.IsMinimaized = !this.IsMinimaized;

      }
    }
    protected bool IsMinimaized;
    protected override void OnPaint(PaintEventArgs e) {
      base.OnPaint(e);
      Point[] downTriangle = new[] { new Point(this.Width / 2 - 4, 0), new Point(this.Width / 2 + 5, 0), new Point(this.Width / 2, 5) };
      Point[] upTriangle = new[] { new Point(this.Width / 2 - 4, this.height - 1), new Point(this.Width / 2 + 5, this.height - 1), new Point(this.Width / 2, -1) };
      Brush rectAngleColor = this.MouseIsOver ? Brushes.LightBlue : Brushes.LightGray;
      Point[] points = this.IsMinimaized ? downTriangle : upTriangle;
      e.Graphics.FillRectangle(rectAngleColor, this.UpperRect);
      e.Graphics.FillPolygon(Brushes.Black, points);
      // herre text
      e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), new PointF(0, this.height));
    }
    private bool mouseIsOver;
    private bool MouseIsOver {
      get {
        return mouseIsOver;
      }
      set {
        mouseIsOver = value;
        this.Invalidate();
      }
    }
    protected override void OnMouseEnter(EventArgs e) {
      base.OnMouseEnter(e);
      MouseIsOver = true;
    }
    protected override void OnMouseLeave(EventArgs e) {
      base.OnMouseLeave(e);
      MouseIsOver = false;
    }

  }


* This source code was highlighted with Source Code Highlighter.


Сегодня код без каметов (надеюсь сообщения в блоге можно редактировать ...)

Первый эксперимент с блогом

тест-тест