Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/TabStrip.cs')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/TabStrip.cs407
1 files changed, 407 insertions, 0 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/TabStrip.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/TabStrip.cs
new file mode 100644
index 0000000000..67976a6ee5
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/TabStrip.cs
@@ -0,0 +1,407 @@
+//
+// TabStrip.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using Gtk;
+
+using System;
+
+namespace MonoDevelop.Components.Docking
+{
+ class TabStrip: Notebook
+ {
+ int currentTab = -1;
+ bool ellipsized = true;
+ HBox box = new HBox ();
+ DockFrame frame;
+ Label bottomFiller = new Label ();
+
+ public TabStrip (DockFrame frame)
+ {
+ this.frame = frame;
+ frame.ShadedContainer.Add (this);
+ VBox vbox = new VBox ();
+ box = new HBox ();
+ vbox.PackStart (box, false, false, 0);
+ vbox.PackStart (bottomFiller, false, false, 0);
+ AppendPage (vbox, null);
+ ShowBorder = false;
+ ShowTabs = false;
+ ShowAll ();
+ bottomFiller.Hide ();
+ BottomPadding = 3;
+ }
+
+ public int BottomPadding {
+ get { return bottomFiller.HeightRequest; }
+ set {
+ bottomFiller.HeightRequest = value;
+ bottomFiller.Visible = value > 0;
+ }
+ }
+
+ public void AddTab (Gtk.Widget page, Gdk.Pixbuf icon, string label)
+ {
+ Tab tab = new Tab ();
+ tab.SetLabel (page, icon, label);
+ tab.ShowAll ();
+ box.PackStart (tab, true, true, 0);
+ if (currentTab == -1)
+ CurrentTab = box.Children.Length - 1;
+ else {
+ tab.Active = false;
+ page.Hide ();
+ }
+
+ tab.ButtonPressEvent += OnTabPress;
+ }
+
+ public void SetTabLabel (Gtk.Widget page, Gdk.Pixbuf icon, string label)
+ {
+ foreach (Tab tab in box.Children) {
+ if (tab.Page == page) {
+ tab.SetLabel (page, icon, label);
+ UpdateEllipsize (Allocation);
+ break;
+ }
+ }
+ }
+
+ public int TabCount {
+ get { return box.Children.Length; }
+ }
+
+ public int CurrentTab {
+ get { return currentTab; }
+ set {
+ if (currentTab == value)
+ return;
+ if (currentTab != -1) {
+ Tab t = (Tab) box.Children [currentTab];
+ t.Page.Hide ();
+ t.Active = false;
+ }
+ currentTab = value;
+ if (currentTab != -1) {
+ Tab t = (Tab) box.Children [currentTab];
+ t.Active = true;
+ t.Page.Show ();
+ }
+ }
+ }
+
+ new public Gtk.Widget CurrentPage {
+ get {
+ if (currentTab != -1) {
+ Tab t = (Tab) box.Children [currentTab];
+ return t.Page;
+ } else
+ return null;
+ }
+ set {
+ if (value != null) {
+ Gtk.Widget[] tabs = box.Children;
+ for (int n = 0; n < tabs.Length; n++) {
+ Tab tab = (Tab) tabs [n];
+ if (tab.Page == value) {
+ CurrentTab = n;
+ return;
+ }
+ }
+ }
+ CurrentTab = -1;
+ }
+ }
+
+ public void Clear ()
+ {
+ ellipsized = true;
+ currentTab = -1;
+ foreach (Widget w in box.Children) {
+ box.Remove (w);
+ w.Destroy ();
+ }
+ }
+
+ void OnTabPress (object s, Gtk.ButtonPressEventArgs args)
+ {
+ CurrentTab = Array.IndexOf (box.Children, s);
+ Tab t = (Tab) s;
+ DockItem.SetFocus (t.Page);
+ QueueDraw ();
+ }
+
+ protected override void OnSizeAllocated (Gdk.Rectangle allocation)
+ {
+ UpdateEllipsize (allocation);
+ base.OnSizeAllocated (allocation);
+ }
+
+ void UpdateEllipsize (Gdk.Rectangle allocation)
+ {
+ int tsize = 0;
+ foreach (Tab tab in box.Children)
+ tsize += tab.LabelWidth;
+
+ bool ellipsize = tsize > allocation.Width;
+ if (ellipsize != ellipsized) {
+ foreach (Tab tab in box.Children) {
+ tab.SetEllipsize (ellipsize);
+ Gtk.Box.BoxChild bc = (Gtk.Box.BoxChild) box [tab];
+ bc.Expand = bc.Fill = ellipsize;
+ }
+ ellipsized = ellipsize;
+ }
+ }
+
+ public Gdk.Rectangle GetTabArea (int ntab)
+ {
+ Gtk.Widget[] tabs = box.Children;
+ Tab tab = (Tab) tabs[ntab];
+ Gdk.Rectangle rect = GetTabArea (tab, ntab);
+ int x, y;
+ tab.GdkWindow.GetRootOrigin (out x, out y);
+ rect.X += x;
+ rect.Y += y;
+ return rect;
+ }
+
+ protected override bool OnExposeEvent (Gdk.EventExpose evnt)
+ {
+ frame.ShadedContainer.DrawBackground (this);
+
+ Gtk.Widget[] tabs = box.Children;
+ for (int n=tabs.Length - 1; n>=0; n--) {
+ Tab tab = (Tab) tabs [n];
+ if (n != currentTab)
+ DrawTab (evnt, tab, n);
+ }
+ if (currentTab != -1) {
+ Tab ctab = (Tab) tabs [currentTab];
+// GdkWindow.DrawLine (Style.DarkGC (Gtk.StateType.Normal), Allocation.X, Allocation.Y, Allocation.Right, Allocation.Y);
+ DrawTab (evnt, ctab, currentTab);
+ }
+ return base.OnExposeEvent (evnt);
+ }
+
+ public Gdk.Rectangle GetTabArea (Tab tab, int pos)
+ {
+ Gdk.Rectangle rect = tab.Allocation;
+
+ int xdif = 0;
+ if (pos > 0)
+ xdif = 2;
+
+ int reqh;
+// StateType st;
+
+ if (tab.Active) {
+// st = StateType.Normal;
+ reqh = tab.Allocation.Height;
+ }
+ else {
+ reqh = tab.Allocation.Height - 3;
+// st = StateType.Active;
+ }
+
+ if (DockFrame.IsWindows) {
+ rect.Height = reqh - 1;
+ rect.Width--;
+ if (pos > 0) {
+ rect.X--;
+ rect.Width++;
+ }
+ return rect;
+ }
+ else {
+ rect.X -= xdif;
+ rect.Width += xdif;
+ rect.Height = reqh;
+ return rect;
+ }
+ }
+
+ void DrawTab (Gdk.EventExpose evnt, Tab tab, int pos)
+ {
+ Gdk.Rectangle rect = GetTabArea (tab, pos);
+ StateType st;
+ if (tab.Active)
+ st = StateType.Normal;
+ else
+ st = StateType.Active;
+
+ if (DockFrame.IsWindows) {
+ GdkWindow.DrawRectangle (Style.DarkGC (Gtk.StateType.Normal), false, rect);
+ rect.X++;
+ rect.Width--;
+ if (tab.Active) {
+ GdkWindow.DrawRectangle (Style.LightGC (Gtk.StateType.Normal), true, rect);
+ }
+ else {
+ using (Cairo.Context cr = Gdk.CairoHelper.Create (evnt.Window)) {
+ cr.NewPath ();
+ cr.MoveTo (rect.X, rect.Y);
+ cr.RelLineTo (rect.Width, 0);
+ cr.RelLineTo (0, rect.Height);
+ cr.RelLineTo (-rect.Width, 0);
+ cr.RelLineTo (0, -rect.Height);
+ cr.ClosePath ();
+ Cairo.Gradient pat = new Cairo.LinearGradient (rect.X, rect.Y, rect.X, rect.Y + rect.Height);
+ Cairo.Color color1 = DockFrame.ToCairoColor (Style.Mid (Gtk.StateType.Normal));
+ pat.AddColorStop (0, color1);
+ color1.R *= 1.2;
+ color1.G *= 1.2;
+ color1.B *= 1.2;
+ pat.AddColorStop (1, color1);
+ cr.Pattern = pat;
+ cr.FillPreserve ();
+ }
+ }
+ }
+ else
+ Gtk.Style.PaintExtension (Style, GdkWindow, st, ShadowType.Out, evnt.Area, this, "tab", rect.X, rect.Y, rect.Width, rect.Height, Gtk.PositionType.Top);
+ }
+ }
+
+ class Tab: Gtk.EventBox
+ {
+ bool active;
+ Gtk.Widget page;
+ Gtk.Label labelWidget;
+ int labelWidth;
+
+ const int TopPadding = 2;
+ const int BottomPadding = 4;
+ const int TopPaddingActive = 3;
+ const int BottomPaddingActive = 5;
+ const int HorzPadding = 5;
+
+ public Tab ()
+ {
+ this.VisibleWindow = false;
+ }
+
+ public void SetLabel (Gtk.Widget page, Gdk.Pixbuf icon, string label)
+ {
+ Pango.EllipsizeMode oldMode = Pango.EllipsizeMode.End;
+
+ this.page = page;
+ if (Child != null) {
+ if (labelWidget != null)
+ oldMode = labelWidget.Ellipsize;
+ Gtk.Widget oc = Child;
+ Remove (oc);
+ oc.Destroy ();
+ }
+
+ Gtk.HBox box = new HBox ();
+ box.Spacing = 2;
+
+ if (icon != null)
+ box.PackStart (new Gtk.Image (icon), false, false, 0);
+
+ if (!string.IsNullOrEmpty (label)) {
+ labelWidget = new Gtk.Label (label);
+ labelWidget.UseMarkup = true;
+ box.PackStart (labelWidget, true, true, 0);
+ } else {
+ labelWidget = null;
+ }
+
+ Add (box);
+
+ // Get the required size before setting the ellipsize property, since ellipsized labels
+ // have a width request of 0
+ ShowAll ();
+ labelWidth = SizeRequest ().Width;
+
+ if (labelWidget != null)
+ labelWidget.Ellipsize = oldMode;
+ }
+
+ public void SetEllipsize (bool elipsize)
+ {
+ if (labelWidget != null) {
+ if (elipsize)
+ labelWidget.Ellipsize = Pango.EllipsizeMode.End;
+ else
+ labelWidget.Ellipsize = Pango.EllipsizeMode.None;
+ }
+ }
+
+ public int LabelWidth {
+ get { return labelWidth; }
+ }
+
+ public bool Active {
+ get {
+ return active;
+ }
+ set {
+ active = value;
+ this.QueueResize ();
+ QueueDraw ();
+ }
+ }
+
+ public Widget Page {
+ get {
+ return page;
+ }
+ }
+
+ protected override void OnSizeRequested (ref Gtk.Requisition req)
+ {
+ req = Child.SizeRequest ();
+ req.Width += HorzPadding * 2;
+ if (active)
+ req.Height += TopPaddingActive + BottomPaddingActive;
+ else
+ req.Height += TopPadding + BottomPadding;
+ }
+
+ protected override void OnSizeAllocated (Gdk.Rectangle rect)
+ {
+ base.OnSizeAllocated (rect);
+
+ rect.X += HorzPadding;
+ rect.Width -= HorzPadding * 2;
+
+ if (active) {
+ rect.Y += TopPaddingActive;
+ rect.Height = Child.SizeRequest ().Height;
+ }
+ else {
+ rect.Y += TopPadding;
+ rect.Height = Child.SizeRequest ().Height;
+ }
+ Child.SizeAllocate (rect);
+ }
+ }
+}