public DockNotebookTab InsertTab(int index) { var tab = new DockNotebookTab(this, tabStrip); if (index == -1) { pages.Add(tab); tab.Index = pages.Count - 1; } else { pages.Insert(index, tab); tab.Index = index; UpdateIndexes(index + 1); } pagesHistory.Add(tab); if (pages.Count == 1) { CurrentTab = tab; } tabStrip.StartOpenAnimation((DockNotebookTab)tab); tabStrip.Update(); tabStrip.DropDownButton.Sensitive = pages.Count > 0; if (PageAdded != null) { PageAdded(this, EventArgs.Empty); } return(tab); }
public void StartOpenAnimation(DockNotebookTab tab) { tab.WidthModifier = 0; new Animation(f => tab.WidthModifier = f) .AddConcurrent(new Animation(f => tab.Opacity = f), 0.0d, 0.2d) .Commit(tab, "Open", easing: Easing.CubicInOut); }
void SetHighlightedTab(DockNotebookTab tab) { if (highlightedTab == tab) { return; } if (highlightedTab != null) { var tmp = highlightedTab; tmp.Animate("Glow", f => tmp.GlowStrength = f, start: tmp.GlowStrength, end: 0); } if (tab != null) { tab.Animate("Glow", f => tab.GlowStrength = f, start: tab.GlowStrength, end: 1); } highlightedTab = tab; QueueDraw(); }
void OnTabPinned(DockNotebookTab sender, bool value) { if (pages.Count == 1) { return; } var stickedPages = pages.Where(p => p.IsPinned); var normalPages = pages.Where(p => !p.IsPinned); if (value) { if (stickedPages.Any()) { ReorderTab(sender, normalPages.MinValueOrDefault(s => s.Index) ?? stickedPages.MaxValueOrDefault(s => s.Index), false); } else { ReorderTab(sender, pages.FirstOrDefault(), false); } } else { ReorderTab(sender, stickedPages.MaxValueOrDefault(s => s.Index) ?? normalPages.MinValueOrDefault(s => s.Index), false); } }
internal void ReorderTab(DockNotebookTab tab, DockNotebookTab targetTab) { if (tab == targetTab) { return; } int targetPos = targetTab.Index; if (tab.Index > targetTab.Index) { pages.RemoveAt(tab.Index); pages.Insert(targetPos, tab); } else { pages.Insert(targetPos + 1, tab); pages.RemoveAt(tab.Index); } if (TabsReordered != null) { TabsReordered(tab, tab.Index, targetPos); } UpdateIndexes(Math.Min(tab.Index, targetPos)); tabStrip.Update(); }
internal void ShowContent(DockNotebookTab tab) { if (tab == currentTab) { contentBox.Child = tab.Content; } }
void PlaceInHoverNotebook(DockNotebook notebook, DockNotebookTab tab, Rectangle allocation, int ox, int oy) { var window = (SdiWorkspaceWindow)tab.Content; var newTab = hoverNotebook.AddTab(window); window.SetDockNotebook(hoverNotebook, newTab); window.SelectWindow(); }
internal void OnPinTab(DockNotebookTab tab) { if (TabPinned != null) { TabPinned(this, new TabEventArgs() { Tab = tab }); } }
internal void OnCloseTab(DockNotebookTab tab) { if (TabClosed != null) { TabClosed(this, new TabEventArgs() { Tab = tab }); } }
internal void OnActivateTab(DockNotebookTab tab) { if (TabActivated != null) { TabActivated(this, new TabEventArgs() { Tab = tab }); } }
Action <Context> DrawClosingTab(int index, Gdk.Rectangle region, out int width) { width = 0; if (closingTabs.ContainsKey(index)) { DockNotebookTab closingTab = closingTabs [index]; width = (int)(closingTab.WidthModifier * TabWidth); int tmp = width; return(c => DrawTab(c, closingTab, Allocation, new Gdk.Rectangle(region.X, region.Y, tmp, region.Height), false, false, false, CreateTabLayout(closingTab))); } return(c => { }); }
Pango.Layout CreateTabLayout(DockNotebookTab tab, bool active = false) { Pango.Layout la = CreateSizedLayout(active); if (!string.IsNullOrEmpty(tab.Markup)) { la.SetMarkup(tab.Markup); } else if (!string.IsNullOrEmpty(tab.Text)) { la.SetText(tab.Text); } return(la); }
public void StartCloseAnimation(DockNotebookTab tab) { closingTabs [tab.Index] = tab; new Animation(f => tab.WidthModifier = f, tab.WidthModifier, 0) .AddConcurrent(new Animation(f => tab.Opacity = f, tab.Opacity, 0), 0.8d) .Commit(tab, "Closing", easing: Easing.CubicOut, finished: (f, a) => { if (!a) { closingTabs.Remove(tab.Index); } }); }
public DockNotebook() { pagesCol = new ReadOnlyCollection <DockNotebookTab> (pages); AddEvents((Int32)(EventMask.AllEventsMask)); tabStrip = new TabStrip(this); PackStart(tabStrip, false, false, 0); contentBox = new EventBox(); PackStart(contentBox, true, true, 0); ShowAll(); contentBox.NoShowAll = true; tabStrip.DropDownButton.Sensitive = false; tabStrip.DropDownButton.ContextMenuRequested = delegate { ContextMenu menu = new ContextMenu(); foreach (var tab in pages) { var item = new ContextMenuItem(tab.Markup ?? tab.Text); var locTab = tab; item.Clicked += (object sender, ContextMenuItemClickedEventArgs e) => { currentTab = locTab; }; menu.Items.Add(item); } return(menu); }; Gtk.Drag.DestSet(this, Gtk.DestDefaults.Motion | Gtk.DestDefaults.Highlight | Gtk.DestDefaults.Drop, targetEntryTypes, Gdk.DragAction.Copy); DragDataReceived += new Gtk.DragDataReceivedHandler(OnDragDataReceived); DragMotion += delegate { // Bring this window to the front. Otherwise, the drop may end being done in another window that overlaps this one if (!Platform.IsWindows) { var window = ((Gtk.Window)Toplevel); if (window is DockWindow) { window.Present(); } } }; allNotebooks.Add(this); }
static void PlaceInFloatingFrame(DockNotebook notebook, DockNotebookTab tab, Rectangle allocation, int ox, int oy) { var newWindow = new DockWindow(); var newNotebook = newWindow.Container.GetFirstNotebook(); var newTab = newNotebook.AddTab(); var workspaceWindow = (SdiWorkspaceWindow)tab.Content; newTab.Content = workspaceWindow; newWindow.Title = DefaultWorkbench.GetTitle(workspaceWindow); workspaceWindow.SetDockNotebook(newNotebook, newTab); newWindow.Move(ox - w / 2, oy - h / 2); newWindow.Resize(w, h); newWindow.ShowAll(); DockNotebook.ActiveNotebook = newNotebook; }
public DocumentTitleWindow(PlaceholderWindow placeholder, DockNotebookTab draggedItem) : base(Gtk.WindowType.Toplevel) { this.placeholder = placeholder; SkipTaskbarHint = true; Decorated = false; //TransientFor = parent; TypeHint = WindowTypeHint.Utility; VBox mainBox = new VBox(); mainBox.Spacing = 3; titleBox = new HBox(false, 3); if (draggedItem.Icon != null) { var img = new Xwt.ImageView(draggedItem.Icon); titleBox.PackStart(img.ToGtkWidget(), false, false, 0); } Gtk.Label la = new Label(); la.Markup = draggedItem.Text; titleBox.PackStart(la, false, false, 0); mainBox.PackStart(titleBox, false, false, 0); var wi = RenderWidget(draggedItem.Content); if (wi != null) { wi = wi.WithBoxSize(200); mainBox.PackStart(new ImageView(wi), false, false, 0); } CustomFrame f = new CustomFrame(); f.SetPadding(2, 2, 2, 2); f.SetMargins(1, 1, 1, 1); f.Add(mainBox); Add(f); mainBox.CanFocus = true; Child.ShowAll(); }
public PlaceholderWindow(DockNotebookTab tab) : base(Gtk.WindowType.Toplevel) { this.frame = tab; SkipTaskbarHint = true; Decorated = false; TypeHint = WindowTypeHint.Utility; titleWindow = new DocumentTitleWindow(this, tab); IdeApp.Workbench.LockActiveWindowChangeEvent(); titleWindow.FocusInEvent += delegate { if (timeout != 0) { GLib.Source.Remove(timeout); timeout = 0; } }; titleWindow.FocusOutEvent += delegate { timeout = GLib.Timeout.Add(100, () => { timeout = 0; titleWindow.Close(); return(false); }); }; var windowStack = IdeApp.CommandService.TopLevelWindowStack.ToArray(); allNotebooks = DockNotebook.AllNotebooks.ToList(); allNotebooks.Sort(delegate(DockNotebook x, DockNotebook y) { var ix = Array.IndexOf(windowStack, (Gtk.Window)x.Toplevel); var iy = Array.IndexOf(windowStack, (Gtk.Window)y.Toplevel); if (ix == -1) { ix = int.MaxValue; } if (iy == -1) { iy = int.MaxValue; } return(ix.CompareTo(iy)); }); }
internal void ReorderTab(DockNotebookTab tab, DockNotebookTab targetTab) { if (tab == targetTab) { return; } int targetPos = targetTab.Index; if (tab.Index > targetTab.Index) { pages.RemoveAt(tab.Index); pages.Insert(targetPos, tab); } else { pages.Insert(targetPos + 1, tab); pages.RemoveAt(tab.Index); } IdeApp.Workbench.ReorderDocuments(tab.Index, targetPos); UpdateIndexes(Math.Min(tab.Index, targetPos)); tabStrip.Update(); }
public DockNotebookTab InsertTab(int index) { var tab = new DockNotebookTab(this, tabStrip); if (index == -1) { pages.Add(tab); tab.Index = pages.Count - 1; } else { pages.Insert(index, tab); tab.Index = index; UpdateIndexes(index + 1); } pagesHistory.Add(tab); if (pages.Count == 1) { CurrentTab = tab; } tabStrip.StartOpenAnimation((DockNotebookTab)tab); tabStrip.Update(); tabStrip.DropDownButton.Sensitive = pages.Count > 0; PageAdded?.Invoke(this, new TabEventArgs { Tab = tab, }); tab.OnChangingPinned = OnTabPinned; NotebookChanged?.Invoke(this, EventArgs.Empty); return(tab); }
void DrawTab(Context ctx, DockNotebookTab tab, Gdk.Rectangle allocation, Gdk.Rectangle tabBounds, bool highlight, bool active, bool dragging, Pango.Layout la) { // This logic is stupid to have here, should be in the caller! if (dragging) { tabBounds.X = (int)(tabBounds.X + (dragX - tabBounds.X) * dragXProgress); tabBounds.X = Clamp(tabBounds.X, tabStartX, tabEndX - tabBounds.Width); } double rightPadding = (active ? TabActivePadding.Right : TabPadding.Right) - (LeanWidth / 2); rightPadding = (rightPadding * Math.Min(1.0, Math.Max(0.5, (tabBounds.Width - 30) / 70.0))); double leftPadding = (active ? TabActivePadding.Left : TabPadding.Left) - (LeanWidth / 2); leftPadding = (leftPadding * Math.Min(1.0, Math.Max(0.5, (tabBounds.Width - 30) / 70.0))); double bottomPadding = active ? TabActivePadding.Bottom : TabPadding.Bottom; DrawTabBackground(this, ctx, allocation, tabBounds.Width, tabBounds.X, active); ctx.LineWidth = 1; ctx.NewPath(); // Render Close Button (do this first so we can tell how much text to render) var closeButtonAlloation = new Cairo.Rectangle(tabBounds.Right - rightPadding - (tabCloseImage.Width / 2) - CloseButtonMarginRight, tabBounds.Height - bottomPadding - tabCloseImage.Height - CloseButtonMarginBottom, tabCloseImage.Width, tabCloseImage.Height); tab.CloseButtonActiveArea = closeButtonAlloation.Inflate(2, 2); bool closeButtonHovered = tracker.Hovered && tab.CloseButtonActiveArea.Contains(tracker.MousePosition); bool tabHovered = tracker.Hovered && tab.Allocation.Contains(tracker.MousePosition); bool drawCloseButton = active || tabHovered; if (!closeButtonHovered && tab.DirtyStrength > 0.5) { ctx.DrawImage(this, tabDirtyImage, closeButtonAlloation.X, closeButtonAlloation.Y); drawCloseButton = false; } if (drawCloseButton) { ctx.DrawImage(this, tabCloseImage.WithAlpha((closeButtonHovered ? 1.0 : 0.5) * tab.Opacity), closeButtonAlloation.X, closeButtonAlloation.Y); } // Render Text double tw = tabBounds.Width - (leftPadding + rightPadding); if (drawCloseButton || tab.DirtyStrength > 0.5) { tw -= closeButtonAlloation.Width / 2; } double tx = tabBounds.X + leftPadding; var baseline = la.GetLine(0).Layout.GetPixelBaseline(); double ty = tabBounds.Height - bottomPadding - baseline; ctx.MoveTo(tx, ty); if (!MonoDevelop.Core.Platform.IsMac && !MonoDevelop.Core.Platform.IsWindows) { // This is a work around for a linux specific problem. // A bug in the proprietary ATI driver caused TAB text not to draw. // If that bug get's fixed remove this HACK asap. la.Ellipsize = Pango.EllipsizeMode.End; la.Width = (int)(tw * Pango.Scale.PangoScale); ctx.SetSourceColor((tab.Notify ? Styles.TabBarNotifyTextColor : (active ? Styles.TabBarActiveTextColor : Styles.TabBarInactiveTextColor)).ToCairoColor()); Pango.CairoHelper.ShowLayout(ctx, la.GetLine(0).Layout); } else { // ellipses are for space wasting ..., we cant afford that using (var lg = new LinearGradient(tx + tw - 10, 0, tx + tw, 0)) { var color = (tab.Notify ? Styles.TabBarNotifyTextColor : (active ? Styles.TabBarActiveTextColor : Styles.TabBarInactiveTextColor)).ToCairoColor(); color = color.MultiplyAlpha(tab.Opacity); lg.AddColorStop(0, color); color.A = 0; lg.AddColorStop(1, color); ctx.SetSource(lg); Pango.CairoHelper.ShowLayout(ctx, la.GetLine(0).Layout); } } la.Dispose(); }
static bool IsOverCloseButton(DockNotebookTab tab, int x, int y) { return(tab != null && tab.CloseButtonActiveArea.Contains(x, y)); }
internal void ReorderTab (DockNotebookTab tab, DockNotebookTab targetTab) { if (tab == targetTab) return; int targetPos = targetTab.Index; if (tab.Index > targetTab.Index) { pages.RemoveAt (tab.Index); pages.Insert (targetPos, tab); } else { pages.Insert (targetPos + 1, tab); pages.RemoveAt (tab.Index); } IdeApp.Workbench.ReorderDocuments (tab.Index, targetPos); UpdateIndexes (Math.Min (tab.Index, targetPos)); tabStrip.Update (); }
void PageReorderedHandler(DockNotebookTab tab, int oldPlacement, int newPlacement) { QueueResize(); UpdateAccessibilityTabs(); }
internal void OnActivateTab (DockNotebookTab tab) { if (TabActivated != null) TabActivated (this, new TabEventArgs () { Tab = tab }); }
internal void OnCloseTab (DockNotebookTab tab) { if (TabClosed != null) TabClosed (this, new TabEventArgs () { Tab = tab }); }
internal void ShowContent (DockNotebookTab tab) { if (tab == currentTab) contentBox.Child = tab.Content; }
public DockNotebookTab InsertTab (int index) { var tab = new DockNotebookTab (this, tabStrip); if (index == -1) { pages.Add (tab); tab.Index = pages.Count - 1; } else { pages.Insert (index, tab); tab.Index = index; UpdateIndexes (index + 1); } pagesHistory.Add (tab); if (pages.Count == 1) CurrentTab = tab; tabStrip.StartOpenAnimation ((DockNotebookTab)tab); tabStrip.Update (); tabStrip.DropDownButton.Sensitive = pages.Count > 0; if (PageAdded != null) PageAdded (this, EventArgs.Empty); return tab; }
void DrawTab(Context ctx, DockNotebookTab tab, Gdk.Rectangle allocation, Gdk.Rectangle tabBounds, bool highlight, bool active, bool dragging, Pango.Layout la) { // This logic is stupid to have here, should be in the caller! if (dragging) { tabBounds.X = (int)(tabBounds.X + (dragX - tabBounds.X) * dragXProgress); tabBounds.X = Clamp(tabBounds.X, tabStartX, tabEndX - tabBounds.Width); } int padding = LeftRightPadding; padding = (int)(padding * Math.Min(1.0, Math.Max(0.5, (tabBounds.Width - 30) / 70.0))); ctx.LineWidth = 1; LayoutTabBorder(ctx, allocation, tabBounds.Width, tabBounds.X, 0, active); ctx.ClosePath(); using (var gr = new LinearGradient(tabBounds.X, TopBarPadding, tabBounds.X, allocation.Bottom)) { if (active) { gr.AddColorStop(0, Styles.BreadcrumbGradientStartColor.MultiplyAlpha(tab.Opacity)); gr.AddColorStop(1, Styles.BreadcrumbBackgroundColor.MultiplyAlpha(tab.Opacity)); } else { gr.AddColorStop(0, CairoExtensions.ParseColor("f4f4f4").MultiplyAlpha(tab.Opacity)); gr.AddColorStop(1, CairoExtensions.ParseColor("cecece").MultiplyAlpha(tab.Opacity)); } ctx.SetSource(gr); } ctx.Fill(); ctx.SetSourceColor(new Cairo.Color(1, 1, 1, .5).MultiplyAlpha(tab.Opacity)); LayoutTabBorder(ctx, allocation, tabBounds.Width, tabBounds.X, 1, active); ctx.Stroke(); ctx.SetSourceColor(Styles.BreadcrumbBorderColor.MultiplyAlpha(tab.Opacity)); LayoutTabBorder(ctx, allocation, tabBounds.Width, tabBounds.X, 0, active); ctx.StrokePreserve(); if (tab.GlowStrength > 0) { Gdk.Point mouse = tracker.MousePosition; using (var rg = new RadialGradient(mouse.X, tabBounds.Bottom, 0, mouse.X, tabBounds.Bottom, 100)) { rg.AddColorStop(0, new Cairo.Color(1, 1, 1, 0.4 * tab.Opacity * tab.GlowStrength)); rg.AddColorStop(1, new Cairo.Color(1, 1, 1, 0)); ctx.SetSource(rg); ctx.Fill(); } } else { ctx.NewPath(); } // Render Close Button (do this first so we can tell how much text to render) var ch = allocation.Height - TopBarPadding - BottomBarPadding + CloseImageTopOffset; var crect = new Gdk.Rectangle(tabBounds.Right - padding - CloseButtonSize + 3, tabBounds.Y + TopBarPadding + (ch - CloseButtonSize) / 2, CloseButtonSize, CloseButtonSize); tab.CloseButtonAllocation = crect; tab.CloseButtonAllocation.Inflate(2, 2); bool closeButtonHovered = tracker.Hovered && tab.CloseButtonAllocation.Contains(tracker.MousePosition) && tab.WidthModifier >= 1.0f; bool drawCloseButton = tabBounds.Width > 60 || highlight || closeButtonHovered; if (drawCloseButton) { DrawCloseButton(ctx, new Gdk.Point(crect.X + crect.Width / 2, crect.Y + crect.Height / 2), closeButtonHovered, tab.Opacity, tab.DirtyStrength); } // Render Text int w = tabBounds.Width - (padding * 2 + CloseButtonSize); if (!drawCloseButton) { w += CloseButtonSize; } int textStart = tabBounds.X + padding; ctx.MoveTo(textStart, tabBounds.Y + TopPadding + TextOffset + VerticalTextSize); if (!MonoDevelop.Core.Platform.IsMac && !MonoDevelop.Core.Platform.IsWindows) { // This is a work around for a linux specific problem. // A bug in the proprietary ATI driver caused TAB text not to draw. // If that bug get's fixed remove this HACK asap. la.Ellipsize = Pango.EllipsizeMode.End; la.Width = (int)(w * Pango.Scale.PangoScale); ctx.SetSourceColor(tab.Notify ? new Cairo.Color(0, 0, 1) : Styles.TabBarActiveTextColor); Pango.CairoHelper.ShowLayoutLine(ctx, la.GetLine(0)); } else { // ellipses are for space wasting ..., we cant afford that using (var lg = new LinearGradient(textStart + w - 5, 0, textStart + w + 3, 0)) { var color = tab.Notify ? new Cairo.Color(0, 0, 1) : Styles.TabBarActiveTextColor; color = color.MultiplyAlpha(tab.Opacity); lg.AddColorStop(0, color); color.A = 0; lg.AddColorStop(1, color); ctx.SetSource(lg); Pango.CairoHelper.ShowLayoutLine(ctx, la.GetLine(0)); } } la.Dispose(); }
public DockNotebook () { pagesCol = new ReadOnlyCollection<DockNotebookTab> (pages); AddEvents ((Int32)(EventMask.AllEventsMask)); tabStrip = new TabStrip (this); PackStart (tabStrip, false, false, 0); contentBox = new EventBox (); PackStart (contentBox, true, true, 0); ShowAll (); contentBox.NoShowAll = true; tabStrip.DropDownButton.Sensitive = false; tabStrip.DropDownButton.ContextMenuRequested = delegate { ContextMenu menu = new ContextMenu (); foreach (var tab in pages) { var item = new ContextMenuItem (tab.Markup ?? tab.Text); var locTab = tab; item.Clicked += (object sender, ContextMenuItemClickedEventArgs e) => { currentTab = locTab; }; menu.Items.Add (item); } return menu; }; Gtk.Drag.DestSet (this, Gtk.DestDefaults.Motion | Gtk.DestDefaults.Highlight | Gtk.DestDefaults.Drop, targetEntryTypes, Gdk.DragAction.Copy); DragDataReceived += new Gtk.DragDataReceivedHandler (OnDragDataReceived); DragMotion += delegate { // Bring this window to the front. Otherwise, the drop may end being done in another window that overlaps this one if (!Platform.IsWindows) { var window = ((Gtk.Window)Toplevel); if (window is DockWindow) window.Present (); } }; allNotebooks.Add (this); }