internal void UpdateTabText(uint identifier)
        {
            GraphTabItem item = FindGraphTabItem(identifier);

            if (item == null)
            {
                return;
            }
            if (item.Canvas.Controller.IsModified)
            {
                if (!item.Header.EndsWith(" *"))
                {
                    item.Header = item.Header + " *";
                }
            }
            else
            {
                if (item.Header.EndsWith(" *"))
                {
                    item.Header = item.Header.Substring(0, item.Header.Length - 2);
                }
            }

            UpdateVisual(item);
        }
        private bool CloseTabCanvas(GraphTabItem item)
        {
            if (item.Canvas.Controller.IsModified)
            {
                TabControl.SelectedIndex = tabs.IndexOf(item);

                string tabName = item.Header;
                if (tabName.EndsWith(" *"))
                {
                    tabName = tabName.Substring(0, tabName.Length - 2);
                }

                MessageBoxResult saveReminderResult
                    = MessageBox.Show("Save changes to the document \"" + tabName + "\" before closing? ",
                                      "DesignScript Studio", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
                if (saveReminderResult == MessageBoxResult.Yes)
                {
                    if (!item.Canvas.VisualHost.HandleShortcutSave())
                    {
                        return(false);
                    }
                }
                else if (saveReminderResult == MessageBoxResult.Cancel)
                {
                    return(false);
                }
            }

            item.Canvas.Controller.CleanUp();
            graphControl.RemoveCanvas(item.Canvas.Controller.Identifier);
            item.Canvas = null;
            return(true);
        }
        private void UpdateVisual(GraphTabItem item)
        {
            // force the tab item to update the text
            TabItem           tabItem    = FindTabItem(item);
            TextBlock         content    = FindVisualChild(tabItem, "Header") as TextBlock;
            BindingExpression expression = content.GetBindingExpression(TextBlock.TextProperty);

            expression.UpdateTarget();

            // update the menu
            MenuItem menuItem = FindMenuItem(item);

            if (menuItem != null)
            {
                content = FindVisualChild(menuItem, "Header") as TextBlock;
                if (content != null)
                {
                    expression = content.GetBindingExpression(TextBlock.TextProperty);
                    expression.UpdateTarget();
                }
                Button saveButton = FindVisualChild(menuItem, "SaveTab") as Button;
                if (saveButton != null)
                {
                    if (item.Canvas.Controller.IsModified)
                    {
                        saveButton.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        saveButton.Visibility = Visibility.Hidden;
                    }
                }
            }
        }
        private void OnAllTabSaveTabMouseUp(object sender, MouseButtonEventArgs e)
        {
            GraphTabItem item = ((MenuItem)((Button)sender).TemplatedParent).Header as GraphTabItem;

            if (item != null)
            {
                item.Canvas.VisualHost.HandleShortcutSave();
            }
        }
        private void OnAllTabMenuItemMouseUp(object sender, MouseButtonEventArgs e)
        {
            GraphTabItem item = ((MenuItem)((Border)sender).TemplatedParent).Header as GraphTabItem;

            if (item != null)
            {
                TabControl.SelectedIndex = tabs.IndexOf(item);
            }
        }
        private void OnAllTabCloseTabMouseUp(object sender, MouseButtonEventArgs e)
        {
            GraphTabItem item = ((MenuItem)((Button)sender).TemplatedParent).Header as GraphTabItem;

            if (item != null)
            {
                CloseTab(FindTabItem(item));
            }
        }
        internal void AddTab(string tabName, GraphCanvas canvas)
        {
            GraphTabItem newTab = new GraphTabItem(this, this.graphControl);

            newTab.Header       = tabName;
            newTab.Canvas       = canvas;
            newTab.IsInEditMode = false;
            tabs.Add(newTab);
            TabControl.SelectedIndex = tabs.Count() - 1;
        }
        internal void UpdateTabText(uint identifier, string filePath)
        {
            GraphTabItem item = FindGraphTabItem(identifier);

            if (item == null)
            {
                return;
            }
            item.Header = (new FileInfo(filePath)).Name;

            UpdateVisual(item);
        }
        private TabItem FindTabItem(GraphTabItem key)
        {
            if (tabPanel != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(tabPanel); i++)
                {
                    TabItem child = VisualTreeHelper.GetChild(tabPanel, i) as TabItem;

                    if (child.Header == key)
                    {
                        return(child);
                    }
                }
            }
            return(null);
        }
        internal bool CloseAllRightTabCanExecute(object tabItem)
        {
            GraphTabItem item = tabItem as GraphTabItem;

            if (item == null)
            {
                return(false);
            }

            if (tabs.IndexOf(item) == tabs.Count() - 1)
            {
                return(false);
            }

            return(true);
        }
        private void BeginDrag()
        {
            double lastMouseX = Mouse.GetPosition(tabPanel).X;

            TabControl.CaptureMouse();
            draggedTab   = FindTabItemOn(lastMouseX);
            selectedItem = tabs[TabControl.SelectedIndex];
            if (draggedTab != null)
            {
                draggedTabDeltaX = lastMouseX - draggedTab.RenderTransform.Value.OffsetX;
                if (!draggedTab.IsSelected)
                {                                                  // if draggedTab is not the selected one,
                    draggedTab.SetValue(Panel.ZIndexProperty, 50); // rearrange it to the top of unselected tab
                    TabControl.UpdateLayout();
                }
            }
        }
        internal bool CloseAllRightTab(object tabItem)
        {
            GraphTabItem item = tabItem as GraphTabItem;

            if (item == null)
            {
                return(false);
            }

            List <GraphTabItem> tabsToRemove = new List <GraphTabItem>();

            for (int i = tabs.IndexOf(item) + 1; i < tabs.Count(); i++)
            {
                tabsToRemove.Add(tabs[i]);
            }

            return(CloseTabs(tabsToRemove));
        }
        private MenuItem FindMenuItem(GraphTabItem key)
        {
            Popup      popup      = FindVisualChild <Popup>(AllTabsMenu);
            StackPanel stackPanel = (StackPanel)((Decorator)(popup.Child)).Child;

            if (stackPanel != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(stackPanel); i++)
                {
                    MenuItem child = VisualTreeHelper.GetChild(stackPanel, i) as MenuItem;

                    if (child.Header == key)
                    {
                        return(child);
                    }
                }
            }
            return(null);
        }
 private childItem FindVisualChild <childItem>(DependencyObject obj, GraphTabItem item)
     where childItem : DependencyObject
 {
     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
     {
         DependencyObject child = VisualTreeHelper.GetChild(obj, i);
         if (child != null && child is childItem)
         {
             return((childItem)child);
         }
         else
         {
             childItem childOfChild = FindVisualChild <childItem>(child);
             if (childOfChild != null)
             {
                 return(childOfChild);
             }
         }
     }
     return(null);
 }
        internal bool CloseAllButTab(object tabItem)
        {
            GraphTabItem item = tabItem as GraphTabItem;

            if (item == null)
            {
                return(false);
            }

            List <GraphTabItem> tabsToRemove = new List <GraphTabItem>();

            foreach (GraphTabItem clearItem in tabs)
            {
                if (clearItem != item)
                {
                    tabsToRemove.Add(clearItem);
                }
            }

            return(CloseTabs(tabsToRemove));
        }
        private void ShiftTab(int direction, double offsetX)
        {
            int i = tabs.IndexOf((GraphTabItem)draggedTab.Header) + direction;

            if (i < 0 || i >= tabs.Count())
            {
                return;
            }
            if (animationOn)
            {
                return;
            }

            TabItem tabToMove = FindTabItem(tabs[i]);

            if (tabToMove.ActualWidth / 2 + tabToMove.RenderTransform.Value.OffsetX < Math.Abs(offsetX))
            {
                GraphTabItem targetItem = tabToMove.Header as GraphTabItem;
                GraphTabItem sourceItem = draggedTab.Header as GraphTabItem;

                int targetIndex = tabs.IndexOf(targetItem);
                int sourceIndex = tabs.IndexOf(sourceItem);

                tabs[sourceIndex] = targetItem;
                tabs[targetIndex] = sourceItem;

                TabControl.UpdateLayout();
                TabControl.SelectedIndex = tabs.IndexOf(selectedItem);

                TabItem targetTabItem = FindTabItem(targetItem);  // after the update, the tabToMove and draggedTab
                TabItem sourceTabItem = FindTabItem(sourceItem);  // are changed

                targetTabItem.RenderTransform = new MatrixTransform(Matrix.Identity);
                sourceTabItem.RenderTransform = new MatrixTransform(Matrix.Identity);

                // translate the offset of the dragged tab
                Matrix transformMatrix = sourceTabItem.RenderTransform.Value;
                transformMatrix.OffsetX       = -(targetTabItem.ActualWidth - Math.Abs(offsetX)) * direction;
                sourceTabItem.RenderTransform = new MatrixTransform(transformMatrix);
                if (sourceTabItem.IsSelected)
                {
                    sourceTabItem.SetValue(Panel.ZIndexProperty, 100);
                }
                else
                {
                    sourceTabItem.SetValue(Panel.ZIndexProperty, 50);
                }

                // for the animation of the target tab
                transformMatrix               = targetTabItem.RenderTransform.Value;
                transformMatrix.OffsetX       = targetTabItem.ActualWidth * direction;
                targetTabItem.RenderTransform = new MatrixTransform(transformMatrix);
                if (targetTabItem.IsSelected)
                {
                    targetTabItem.SetValue(Panel.ZIndexProperty, 100);
                }
                else
                {
                    targetTabItem.SetValue(Panel.ZIndexProperty, 20);
                }
                AnimationHelper(targetTabItem, targetTabItem.ActualWidth * direction);

                draggedTab        = sourceTabItem;
                draggedTabDeltaX += (targetTabItem.ActualWidth) * direction;
            }
        }
        private void OnTabItemRightClick(object sender, RoutedEventArgs e)
        {
            GraphTabItem item = ((TabItem)e.Source).Header as GraphTabItem;

            TabControl.SelectedIndex = tabs.IndexOf(item);
        }