/// <summary> /// Draw the contents of a given tab. If the tab contains a scene, /// this scene is drawn. If the tab is in loading or failed state, /// the corresponding info screen will be drawn. /// </summary> /// <param name="activeTab">Tab containing the scene to be drawn</param> public void Draw(Tab activeTab) { GL.DepthMask(true); GL.ClearColor(BackgroundColor); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); var ui = Window.UiState.ActiveTab; // draw viewport 3D contents if (ui.ActiveScene != null) { var index = Tab.ViewIndex.Index0; foreach (var viewport in ui.ActiveViews) { // always draw the active viewport last if (viewport == null || ui.ActiveViewIndex == index) { ++index; continue; } var view = viewport.Bounds; var cam = viewport.ActiveCameraControllerForView(); DrawViewport(cam, activeTab, view.X, view.Y, view.Z, view.W, ui.ActiveViewIndex == index); ++index; } var activeVp = ui.ActiveViews[(int)ui.ActiveViewIndex]; Debug.Assert(activeVp != null); var activeVpBounds = activeVp.Bounds; DrawViewport(activeVp.ActiveCameraControllerForView(), activeTab, activeVpBounds.X, activeVpBounds.Y, activeVpBounds.Z, activeVpBounds.W, true); if (ui.ActiveViewMode != Tab.ViewMode.Single) { SetFullViewport(); } if (Window.UiState.ShowFps) { DrawFps(); } if (!_window.IsDraggingViewportSeparator) { if (!_hudHidden) { DrawHud(); } } else { _textOverlay.WantRedrawNextFrame = true; _hudHidden = true; } } else { SetFullViewport(); if (activeTab.State == Tab.TabState.Failed) { DrawFailureSplash(activeTab.ErrorMessage); } else if (activeTab.State == Tab.TabState.Loading) { DrawLoadingSplash(); } else { Debug.Assert(activeTab.State == Tab.TabState.Empty); DrawNoSceneSplash(); } } _textOverlay.Draw(); // draw viewport finishing (i.e. contours) if (ui.ActiveScene != null && ui.ActiveViewMode != Tab.ViewMode.Single) { var index = Tab.ViewIndex.Index0; foreach (var viewport in ui.ActiveViews) { // always draw the active viewport last if (viewport == null || ui.ActiveViewIndex == index) { ++index; continue; } var view = viewport.Bounds; DrawViewportPost(view.X, view.Y, view.Z, view.W, false); ++index; } var activeVp = ui.ActiveViews[(int)ui.ActiveViewIndex]; Debug.Assert(activeVp != null); var activeVpBounds = activeVp.Bounds; DrawViewportPost(activeVpBounds.X, activeVpBounds.Y, activeVpBounds.Z, activeVpBounds.W, true); } // handle other Gl jobs such as drawing preview images - components // use this event to register their jobs. OnGlExtraDrawJob(); }
public UiState(Tab defaultTab) { DefaultFont10 = new Font("Segoe UI", 8); DefaultFont12 = new Font("Segoe UI", 12); DefaultFont16 = new Font("Segoe UI", 18); Tabs = new List<Tab> { defaultTab }; ActiveTab = defaultTab; }
public void OnMouseClick(MouseEventArgs mouseEventArgs, Vector4 viewport, Tab.ViewIndex viewIndex) { // a bit hacky - the click is processed by the render routine. But this is by // far the simplest way to get this done without duplicating code. if (_mousePos.X > _hoverRegion.Left && _mousePos.X <= _hoverRegion.Right && _mousePos.Y > _hoverRegion.Top && _mousePos.Y <= _hoverRegion.Bottom) { _mouseClickPos = mouseEventArgs.Location; _processHudClick = true; _hudDirty = true; } }
/// <summary> /// Draw a scene to a viewport using an ICameraController to specify the camera. /// </summary> /// <param name="view">Active cam controller for this viewport</param> /// <param name="activeTab">Scene to be drawn</param> /// <param name="xs">X-axis starting point of the viewport in range [0,1]</param> /// <param name="ys">Y-axis starting point of the viewport in range [0,1]</param> /// <param name="xe">X-axis end point of the viewport in range [0,1]</param> /// <param name="ye">X-axis end point of the viewport in range [0,1]</param> /// <param name="active"></param> private void DrawViewport(ICameraController view, Tab activeTab, double xs, double ys, double xe, double ye, bool active = false) { // update viewport var w = (double) RenderResolution.Width; var h = (double) RenderResolution.Height; var vw = (int) ((xe - xs)*w); var vh = (int) ((ye - ys)*h); GL.Viewport((int) (xs*w), (int) (ys*h), (int) ((xe - xs)*w), (int) ((ye - ys)*h)); DrawViewportColorsPre(active); var aspectRatio = (float)vw/vh; // set a proper perspective matrix for rendering Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 0.001f, 100.0f); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref perspective); if (activeTab.ActiveScene != null) { DrawScene(activeTab.ActiveScene, view); } }
public TabPage TabPageForTab(Tab tab) { return((TabPage)tab.Id); }
public void RemoveTab(Tab tab) { RemoveTab(tab.Id); }
public TabPage TabPageForTab(Tab tab) { return (TabPage) tab.Id; }
/// <summary> /// Opens a particular 3D model and assigns it to a particular tab. /// May be called on a non-GUI-thread. /// </summary> private void OpenFile(Tab tab, bool setActive) { try { tab.ActiveScene = new Scene(tab.File); CoreSettings.CoreSettings.Default.CountFilesOpened++; } catch(Exception ex) { tab.SetFailed(ex.Message); } var updateTitle = new MethodInvoker(() => { var t = (TabPage)tab.Id; if (!t.Text.EndsWith(LoadingTitlePostfix)) { return; } t.Text = t.Text.Substring(0,t.Text.Length - LoadingTitlePostfix.Length); if (tab.State == Tab.TabState.Failed) { t.Text = t.Text + FailedTitlePostfix; } }); // Must use BeginInvoke() here to make sure it gets executed // on the thread hosting the GUI message pump. An exception // are potential calls coming from our own c'tor: at this // time the window handle is not ready yet and BeginInvoke() // is thus not available. if (!_initialized) { if (setActive) { SelectTab((TabPage) tab.Id); } PopulateInspector(tab); updateTitle(); } else { if (setActive) { BeginInvoke(_delegateSelectTab, new[] {tab.Id}); } BeginInvoke(_delegatePopulateInspector, new object[] { tab }); BeginInvoke(updateTitle); } }
/// <summary> /// Populate the inspector view for a given tab. This can be called /// as soon as the scene to be displayed is loaded, i.e. tab.ActiveScene is non-null. /// </summary> /// <param name="tab"></param> public void PopulateInspector(Tab tab) { var ui = UiForTab(tab); Debug.Assert(ui != null); var inspector = ui.GetInspector(); inspector.SetSceneSource(tab.ActiveScene); }
/// <summary> /// Open a new tab given a scene file to load. If the specified scene is /// already open in a tab, the existing /// tab is selected in the UI (if requested) and no tab is added. /// </summary> /// <param name="file">Source file</param> /// <param name="async">Specifies whether the data is loaded asynchr.</param> /// <param name="setActive">Specifies whether the newly added tab will /// be selected when the loading process is complete.</param> public void AddTab(string file, bool async = true, bool setActive = true) { AddRecentItem(file); // check whether the scene is already loaded for (int j = 0; j < tabControl1.TabPages.Count; ++j) { var tab = UiState.TabForId(tabControl1.TabPages[j]); Debug.Assert(tab != null); if(tab.File == file) { // if so, activate its tab and return if(setActive) { SelectTab(tabControl1.TabPages[j]); } return; } } var key = GenerateTabKey(); tabControl1.TabPages.Add(key, GenerateTabCaption(file) + LoadingTitlePostfix); var ui = tabControl1.TabPages[key]; ui.ToolTipText = file; tabControl1.ShowToolTips = true; PopulateUITab(ui); var t = new Tab(ui, file); UiState.AddTab(t); if (TabChanged != null) { TabChanged(t, true); } if (async) { var th = new Thread(() => OpenFile(t, setActive)); th.Start(); } else { OpenFile(t, setActive); } if (_emptyTab != null) { CloseTab(_emptyTab); } }
private void SetViewportDragCursor(Tab.ViewSeparator sep) { switch (sep) { case Tab.ViewSeparator.Horizontal: Cursor = Cursors.HSplit; break; case Tab.ViewSeparator.Vertical: Cursor = Cursors.VSplit; break; case Tab.ViewSeparator.Both: Cursor = Cursors.SizeAll; break; default: throw new ArgumentOutOfRangeException(); } }
public TabUiSkeleton UiForTab(Tab tab) { return ((TabUiSkeleton) ((TabPage) tab.Id).Controls[0]); }
/// <summary> /// Set a particular tab as selected. This sets the "ActiveTab" /// property to the tab object. This does *not* update the UI. /// </summary> /// <param name="id">Unique id of the tab to be selected</param> public void SelectTab(object id) { foreach (var ts in Tabs.Where(ts => ts.Id == id)) { ActiveTab = ts; return; } Debug.Assert(false, "tab with id not found: " + id.ToString()); }
public TabUiSkeleton UiForTab(Tab tab) { return ((TabUiSkeleton) TabPageForTab(tab).Controls[0]); }
public void SelectTab(Tab tab) { SelectTab(tab.Id); }
/// <summary> /// Draw the contents of a given tab. If the tab contains a scene, /// this scene is drawn. If the tab is in loading or failed state, /// the corresponding info screen will be drawn. /// </summary> /// <param name="activeTab">Tab containing the scene to be drawn</param> public void Draw(Tab activeTab) { GL.DepthMask(true); GL.ClearColor(BackgroundColor); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); var ui = Window.UiState.ActiveTab; // draw viewport 3D contents if (ui.ActiveScene != null) { var index = Tab.ViewIndex.Index0; foreach (var viewport in ui.ActiveViews) { // always draw the active viewport last if (viewport == null || ui.ActiveViewIndex == index) { ++index; continue; } var view = viewport.Bounds; var cam = viewport.ActiveCameraControllerForView(); DrawViewport(cam, activeTab, view.X, view.Y, view.Z, view.W, ui.ActiveViewIndex == index); ++index; } var activeVp = ui.ActiveViews[(int)ui.ActiveViewIndex]; Debug.Assert(activeVp != null); var activeVpBounds = activeVp.Bounds; DrawViewport(activeVp.ActiveCameraControllerForView(), activeTab, activeVpBounds.X, activeVpBounds.Y, activeVpBounds.Z, activeVpBounds.W, true); if (ui.ActiveViewMode != Tab.ViewMode.Single) { SetFullViewport(); } if (Window.UiState.ShowFps) { DrawFps(); } if (!_window.IsDraggingViewportSeparator) { if (!_hudHidden) { DrawHud(); } } else { _textOverlay.WantRedrawNextFrame = true; _hudHidden = true; } } else { SetFullViewport(); if (activeTab.State == Tab.TabState.Failed) { DrawFailureSplash(activeTab.ErrorMessage); } else if (activeTab.State == Tab.TabState.Loading) { DrawLoadingSplash(); } else { Debug.Assert(activeTab.State == Tab.TabState.Empty); DrawNoSceneSplash(); } } _textOverlay.Draw(); // draw viewport finishing (i.e. contours) if (ui.ActiveScene != null && ui.ActiveViewMode != Tab.ViewMode.Single) { var index = Tab.ViewIndex.Index0; foreach (var viewport in ui.ActiveViews) { // always draw the active viewport last if (viewport == null || ui.ActiveViewIndex == index) { ++index; continue; } var view = viewport.Bounds; DrawViewportPost(view.X, view.Y, view.Z, view.W, false); ++index; } var activeVp = ui.ActiveViews[(int) ui.ActiveViewIndex]; Debug.Assert(activeVp != null); var activeVpBounds = activeVp.Bounds; DrawViewportPost(activeVpBounds.X, activeVpBounds.Y,activeVpBounds.Z, activeVpBounds.W, true); } // handle other Gl jobs such as drawing preview images - components // use this event to register their jobs. OnGlExtraDrawJob(); }
/// <summary> /// Add a tab with a given ID. The selected tab is not changed by this /// operation. /// </summary> /// <param name="id">Tag object. The ID member of this tab must be /// unique for all tabs (during the entire lifetime of the tab).</param> public void AddTab(Tab tab) { #if DEBUG Debug.Assert(!Tabs.Contains(tab), "tab exists already:" + tab.Id.ToString()); foreach (Tab ts in Tabs) { Debug.Assert(ts.Id != tab.Id, "tab id exists already: " + tab.Id.ToString()); } #endif Tabs.Add(tab); }
public void OnMouseMove(MouseEventArgs mouseEventArgs, Vector4 viewport, Tab.ViewIndex viewIndex) { _mousePos = mouseEventArgs.Location; if (_mousePos.X > _hoverRegion.Left && _mousePos.X <= _hoverRegion.Right && _mousePos.Y > _hoverRegion.Top && _mousePos.Y <= _hoverRegion.Bottom) { _hudDirty = true; } if (viewport == _hoverViewport) { return; } _hudDirty = true; _hoverViewport = viewport; _hoverViewIndex = viewIndex; _hoverFadeInTime = HudHoverTime; _hudHidden = false; }
public TabUiSkeleton UiForTab(Tab tab) { return((TabUiSkeleton)TabPageForTab(tab).Controls[0]); }