From c7034ac1e3a7cf616868c9df224a24b5625b7fe4 Mon Sep 17 00:00:00 2001 From: Anatoliy Bazko Date: Tue, 14 Aug 2018 10:42:11 +0300 Subject: [PATCH] Restyling debug panel Signed-off-by: Anatoliy Bazko --- packages/core/src/browser/shell/tab-bars.ts | 2 +- packages/debug/src/browser/style/index.css | 100 +++++++----------- .../browser/view/debug-breakpoints-widget.ts | 26 +++-- .../browser/view/debug-stack-frames-widget.ts | 36 ++++--- .../src/browser/view/debug-threads-widget.ts | 29 +++-- .../browser/view/debug-variables-widget.tsx | 22 ++-- .../browser/view/debug-view-contribution.ts | 10 +- 7 files changed, 118 insertions(+), 107 deletions(-) diff --git a/packages/core/src/browser/shell/tab-bars.ts b/packages/core/src/browser/shell/tab-bars.ts index 6c144d5d63ea8..51994bec6a1ec 100644 --- a/packages/core/src/browser/shell/tab-bars.ts +++ b/packages/core/src/browser/shell/tab-bars.ts @@ -104,7 +104,7 @@ export class TabBarRenderer extends TabBar.Renderer { const iconSize = data.iconSize; let height: string | undefined; if (labelSize || iconSize) { - const labelHeight = labelSize ? labelSize.width : 0; + const labelHeight = labelSize ? (this.tabBar && this.tabBar.orientation === 'horizontal' ? labelSize.height : labelSize.width) : 0; const iconHeight = iconSize ? iconSize.height : 0; let paddingTop = data.paddingTop || 0; if (labelHeight > 0 && iconHeight > 0) { diff --git a/packages/debug/src/browser/style/index.css b/packages/debug/src/browser/style/index.css index 8498ba4ba1a07..dd7cccff97742 100644 --- a/packages/debug/src/browser/style/index.css +++ b/packages/debug/src/browser/style/index.css @@ -14,9 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -.theia-debug-panel { - display: flex; -} +.theia-debug-panel { } .theia-debug-panel:focus { outline: 0; @@ -24,95 +22,67 @@ } .theia-debug-target { - display: flex; -} - -.theia-debug-threads-container { - overflow: auto; + display: inline-table; color: var(--theia-ui-font-color1); background: var(--theia-layout-color0); font-size: var(--theia-ui-font-size1); - max-height: calc(100% - var(--theia-border-width)); - position: relative; - width: 300px; + width: 100%; } -.theia-debug-threads-container:focus .theia-mod-selected { +.theia-debug-entry { } + +.theia-debug-entry:focus .theia-mod-selected { background: var(--theia-accent-color3); } -.theia-debug-threads-container:not(:focus) .theia-mod-selected { +.theia-debug-entry:not(:focus) .theia-mod-selected { background: var(--theia-accent-color4); } -.theia-debug-thread { +.theia-debug-threads { + overflow: auto; + height: 180px; +} + +.theia-debug-thread-item { line-height: var(--theia-private-horizontal-tab-height); align-items: baseline; padding-left: 5px; - display: flex; } -.theia-debug-thread:hover { +.theia-debug-thread-item:hover { background: var(--theia-accent-color4); cursor: pointer; } -.theia-debug-frames-container { +.theia-debug-frames { overflow: auto; - color: var(--theia-ui-font-color1); - background: var(--theia-layout-color0); - font-size: var(--theia-ui-font-size1); - max-height: calc(100% - var(--theia-border-width)); - position: relative; - width: 400px; -} - -.theia-debug-frames-container:focus .theia-mod-selected { - background: var(--theia-accent-color3); -} - -.theia-debug-frames-container:not(:focus) .theia-mod-selected { - background: var(--theia-accent-color4); + height: 200px; } -.theia-debug-frame { +.theia-debug-frame-item { line-height: var(--theia-private-horizontal-tab-height); align-items: baseline; padding-left: 5px; - display: flex; } -.theia-debug-frame:hover { +.theia-debug-frame-item:hover { background: var(--theia-accent-color4); cursor: pointer; } -.theia-debug-breakpoints-container { +.theia-debug-breakpoints { overflow: auto; - color: var(--theia-ui-font-color1); - background: var(--theia-layout-color0); - font-size: var(--theia-ui-font-size1); - max-height: calc(100% - var(--theia-border-width)); - position: relative; - width: 400px; -} - -.theia-debug-breakpoints-container:focus .theia-mod-selected { - background: var(--theia-accent-color3); -} - -.theia-debug-breakpoints-container:not(:focus) .theia-mod-selected { - background: var(--theia-accent-color4); + height: 150px; } -.theia-debug-breakpoint { +.theia-debug-breakpoint-item { line-height: var(--theia-private-horizontal-tab-height); align-items: baseline; padding-left: 5px; - display: flex; } -.theia-debug-breakpoint:hover { +.theia-debug-breakpoint-item:hover { background: var(--theia-accent-color4); cursor: pointer; } @@ -121,24 +91,36 @@ height: 400px; } -.theia-debug-variables-container { - overflow: auto; - color: var(--theia-ui-font-color1); +.theia-debug-breakpoint-dialog .theia-debug-breakpoints { background: var(--theia-layout-color0); - font-size: var(--theia-ui-font-size1); - max-height: calc(100% - var(--theia-border-width)); - position: relative; - width: 400px; + height: 380px +} + +.theia-debug-variables { + overflow: hidden; + height: 200px; + white-space: nowrap; } .theia-debug-active-line { background-color: rgba(255, 120, 100, 0.5); } +.theia-debug-header { + background: var(--theia-layout-color3); + text-transform: uppercase; + font-size: var(--theia-ui-font-size0); + font-weight: 800; + border: 4px solid; + border-color: var(--theia-layout-color3); +} + .theia-debug-inactive-breakpoint { + transform: scale(0.5); background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiICAgdmVyc2lvbj0iMS4xIiAgIGlkPSJicmVha3BvaW50X3g1Rl9pbmFjdGl2ZSIgICB4PSIwcHgiICAgeT0iMHB4IiAgIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiAgIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAyNTYgMjU2IDI1NjsiICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkxIHIxMzcyNSIgICBzb2RpcG9kaTpkb2NuYW1lPSJicmVha3BvaW50X2luYWN0aXZlLnN2ZyI+PG1ldGFkYXRhICAgICBpZD0ibWV0YWRhdGEzMzk3Ij48cmRmOlJERj48Y2M6V29yayAgICAgICAgIHJkZjphYm91dD0iIj48ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD48ZGM6dHlwZSAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48ZGM6dGl0bGU+PC9kYzp0aXRsZT48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMgICAgIGlkPSJkZWZzMzM5NSIgLz48c29kaXBvZGk6bmFtZWR2aWV3ICAgICBwYWdlY29sb3I9IiNmZmZmZmYiICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIgICAgIGJvcmRlcm9wYWNpdHk9IjEiICAgICBvYmplY3R0b2xlcmFuY2U9IjEwIiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiICAgICBndWlkZXRvbGVyYW5jZT0iMTAiICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIgICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE5MjAiICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDI3IiAgICAgaWQ9Im5hbWVkdmlldzMzOTMiICAgICBzaG93Z3JpZD0idHJ1ZSIgICAgIGlua3NjYXBlOnpvb209IjMuMjkyOTY4OCIgICAgIGlua3NjYXBlOmN4PSIxMjgiICAgICBpbmtzY2FwZTpjeT0iMTQwLjE0NzA5IiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMCIgICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJicmVha3BvaW50X3g1Rl9pbmFjdGl2ZSI+PGlua3NjYXBlOmdyaWQgICAgICAgdHlwZT0ieHlncmlkIiAgICAgICBpZD0iZ3JpZDMzOTkiIC8+PC9zb2RpcG9kaTpuYW1lZHZpZXc+PHBhdGggICAgIGlkPSJkb3R0ZWRfeDVGX3JpbmciICAgICBkPSJNODQuNSw0Mi4zbC05LDUuMmMtNS4yLDMtMTEuOCwxLjItMTQuOC00bC01LjItOWMtMy01LjItMS4yLTExLjgsNC0xNC44bDktNS4yYzUuMi0zLDExLjgtMS4yLDE0LjgsNCAgbDUuMiw5QzkxLjQsMzIuNiw4OS42LDM5LjMsODQuNSw0Mi4zeiBNMTk2LjUsMjM2LjNsLTksNS4yYy01LjIsMy0xMS44LDEuMi0xNC44LTRsLTUuMi05Yy0zLTUuMi0xLjItMTEuOCw0LTE0LjhsOS01LjIgIGM1LjItMywxMS44LTEuMiwxNC44LDRsNS4yLDlDMjAzLjQsMjI2LjYsMjAxLjYsMjMzLjMsMTk2LjUsMjM2LjN6IE00Ny41LDc1LjVsLTUuMiw5Yy0zLDUuMi05LjYsNi45LTE0LjgsNGwtOS01LjIgIGMtNS4yLTMtNi45LTkuNi00LTE0LjhsNS4yLTljMy01LjIsOS42LTYuOSwxNC44LTRsOSw1LjJDNDguNiw2My43LDUwLjQsNzAuNCw0Ny41LDc1LjV6IE0yNDEuNCwxODcuNWwtNS4yLDkgIGMtMyw1LjItOS42LDYuOS0xNC44LDRsLTktNS4yYy01LjItMy02LjktOS42LTQtMTQuOGw1LjItOWMzLTUuMiw5LjYtNi45LDE0LjgtNGw5LDUuMkMyNDIuNiwxNzUuNywyNDQuNCwxODIuNCwyNDEuNCwxODcuNXogICBNMzIsMTIyLjh2MTAuNGMwLDYtNC45LDEwLjgtMTAuOCwxMC44SDEwLjhjLTYsMC0xMC44LTQuOS0xMC44LTEwLjh2LTEwLjRjMC02LDQuOS0xMC44LDEwLjgtMTAuOGgxMC40ICBDMjcuMSwxMTIsMzIsMTE2LjksMzIsMTIyLjh6IE0yNTYsMTIyLjh2MTAuNGMwLDYtNC45LDEwLjgtMTAuOCwxMC44aC0xMC40Yy02LDAtMTAuOC00LjktMTAuOC0xMC44di0xMC40YzAtNiw0LjktMTAuOCwxMC44LTEwLjggIGgxMC40QzI1MS4xLDExMiwyNTYsMTE2LjksMjU2LDEyMi44eiBNNDIuMywxNzEuNWw1LjIsOWMzLDUuMiwxLjIsMTEuOC00LDE0LjhsLTksNS4yYy01LjIsMy0xMS44LDEuMi0xNC44LTRsLTUuMi05ICBjLTMtNS4yLTEuMi0xMS44LDQtMTQuOGw5LTUuMkMzMi42LDE2NC42LDM5LjMsMTY2LjQsNDIuMywxNzEuNXogTTIzNi4zLDU5LjVsNS4yLDljMyw1LjIsMS4yLDExLjgtNCwxNC44bC05LDUuMiAgYy01LjIsMy0xMS44LDEuMi0xNC44LTRsLTUuMi05Yy0zLTUuMi0xLjItMTEuOCw0LTE0LjhsOS01LjJDMjI2LjYsNTIuNiwyMzMuMyw1NC40LDIzNi4zLDU5LjV6IE03NS41LDIwOC41bDksNS4yICBjNS4yLDMsNi45LDkuNiw0LDE0LjhsLTUuMiw5Yy0zLDUuMi05LjYsNi45LTE0LjgsNGwtOS01LjJjLTUuMi0zLTYuOS05LjYtNC0xNC44bDUuMi05QzYzLjcsMjA3LjQsNzAuNCwyMDUuNiw3NS41LDIwOC41eiAgIE0xODcuNSwxNC42bDksNS4yYzUuMiwzLDYuOSw5LjYsNCwxNC44bC01LjIsOWMtMyw1LjItOS42LDYuOS0xNC44LDRsLTktNS4yYy01LjItMy02LjktOS42LTQtMTQuOGw1LjItOSAgQzE3NS43LDEzLjQsMTgyLjQsMTEuNiwxODcuNSwxNC42eiBNMTIyLjgsMjI0aDEwLjRjNiwwLDEwLjgsNC45LDEwLjgsMTAuOHYxMC40YzAsNi00LjksMTAuOC0xMC44LDEwLjhoLTEwLjQgIGMtNiwwLTEwLjgtNC45LTEwLjgtMTAuOHYtMTAuNEMxMTIsMjI4LjksMTE2LjksMjI0LDEyMi44LDIyNHogTTEyMi44LDBoMTAuNGM2LDAsMTAuOCw0LjksMTAuOCwxMC44djEwLjRjMCw2LTQuOSwxMC44LTEwLjgsMTAuOCAgaC0xMC40Yy02LDAtMTAuOC00LjktMTAuOC0xMC44VjEwLjhDMTEyLDQuOSwxMTYuOSwwLDEyMi44LDB6IiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIgLz48L3N2Zz4=); } .theia-debug-active-breakpoint { + transform: scale(0.5); background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiICAgdmVyc2lvbj0iMS4xIiAgIGlkPSJicmVha3BvaW50X3g1Rl9lbmFibGVkIiAgIHg9IjBweCIgICB5PSIwcHgiICAgdmlld0JveD0iMCAwIDI1NiAyNTYiICAgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjU2IDI1NjsiICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkxIHIxMzcyNSIgICBzb2RpcG9kaTpkb2NuYW1lPSJicmVha3BvaW50X2VuYWJsZWQuc3ZnIj48bWV0YWRhdGEgICAgIGlkPSJtZXRhZGF0YTMzODIiPjxyZGY6UkRGPjxjYzpXb3JrICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZGVmcyAgICAgaWQ9ImRlZnMzMzgwIiAvPjxzb2RpcG9kaTpuYW1lZHZpZXcgICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIgICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IiAgICAgYm9yZGVyb3BhY2l0eT0iMSIgICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiICAgICBncmlkdG9sZXJhbmNlPSIxMCIgICAgIGd1aWRldG9sZXJhbmNlPSIxMCIgICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIgICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTkyMCIgICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwMjciICAgICBpZD0ibmFtZWR2aWV3MzM3OCIgICAgIHNob3dncmlkPSJmYWxzZSIgICAgIGlua3NjYXBlOnpvb209IjEuNjQ2NDg0NCIgICAgIGlua3NjYXBlOmN4PSI2OS4zOTMzMTgiICAgICBpbmtzY2FwZTpjeT0iMTI1LjQyODY5IiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiICAgICBpbmtzY2FwZTp3aW5kb3cteT0iMCIgICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJicmVha3BvaW50X3g1Rl9lbmFibGVkIiAvPjxzdHlsZSAgICAgdHlwZT0idGV4dC9jc3MiICAgICBpZD0ic3R5bGUzMzc1Ij4uc3Qwe2ZpbGw6IzIzMUYyMDt9PC9zdHlsZT48Y2lyY2xlICAgICBpZD0iY2lyY2xlIiAgICAgY2xhc3M9InN0MCIgICAgIGN4PSIxMjgiICAgICBjeT0iMTI4IiAgICAgcj0iMTI4IiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIgLz48L3N2Zz4=); } diff --git a/packages/debug/src/browser/view/debug-breakpoints-widget.ts b/packages/debug/src/browser/view/debug-breakpoints-widget.ts index 8a90896be6a3e..3ab0f1005b854 100644 --- a/packages/debug/src/browser/view/debug-breakpoints-widget.ts +++ b/packages/debug/src/browser/view/debug-breakpoints-widget.ts @@ -25,6 +25,7 @@ import { injectable, inject, postConstruct } from "inversify"; import { BreakpointsManager } from "../breakpoint/breakpoint-manager"; import { ExtDebugProtocol } from "../../common/debug-common"; import { DebugUtils } from "../debug-utils"; +import { Disposable } from "@theia/core"; /** * Is it used to display breakpoints. @@ -41,16 +42,19 @@ export class DebugBreakpointsWidget extends VirtualWidget { super(); this.id = 'debug-breakpoints' + (debugSession ? `-${debugSession.sessionId}` : ''); - this.addClass(Styles.BREAKPOINTS_CONTAINER); + this.addClass('theia-debug-entry'); this.node.setAttribute("tabIndex", "0"); } @postConstruct() protected init() { - this.breakpointManager.onDidChangeBreakpoints(() => this.refreshBreakpoints()); + this.toDisposeOnDetach.push(this.breakpointManager.onDidChangeBreakpoints(() => this.refreshBreakpoints())); if (this.debugSession) { - this.debugSession.on('configurationDone', () => this.refreshBreakpoints()); + const configurationDoneListener = () => this.refreshBreakpoints(); + + this.debugSession.on('configurationDone', configurationDoneListener); + this.toDisposeOnDetach.push(Disposable.create(() => this.debugSession!.removeListener('configurationDone', configurationDoneListener))); } } @@ -68,24 +72,26 @@ export class DebugBreakpointsWidget extends VirtualWidget { } else { this.breakpoints = await this.breakpointManager.getAll(); } + this.breakpoints.sort(); + super.update(); } protected render(): h.Child { - const header = h.div({ className: "theia-header" }, "Breakpoints"); + const header = h.div({ className: "theia-debug-header" }, "Breakpoints"); const items: h.Child = []; for (const breakpoint of this.breakpoints) { const item = h.div({ id: DebugUtils.makeBreakpointId(breakpoint), - className: Styles.BREAKPOINT, + className: Styles.BREAKPOINT_ITEM, onclick: event => { const selected = this.node.getElementsByClassName(SELECTED_CLASS)[0]; if (selected) { - selected.className = Styles.BREAKPOINT; + selected.className = Styles.BREAKPOINT_ITEM; } - (event.target as HTMLDivElement).className = `${Styles.BREAKPOINT} ${SELECTED_CLASS}`; + (event.target as HTMLDivElement).className = `${Styles.BREAKPOINT_ITEM} ${SELECTED_CLASS}`; this.onDidClickBreakpointEmitter.fire(breakpoint); }, @@ -94,7 +100,7 @@ export class DebugBreakpointsWidget extends VirtualWidget { items.push(item); } - return [header, h.div(items)]; + return [header, h.div({ className: Styles.BREAKPOINTS }, items)]; } private toDisplayName(breakpoint: ExtDebugProtocol.AggregatedBreakpoint): string { @@ -165,7 +171,7 @@ export class BreakpointsDialog extends AbstractDialog { } namespace Styles { - export const BREAKPOINTS_CONTAINER = 'theia-debug-breakpoints-container'; - export const BREAKPOINT = 'theia-debug-breakpoint'; + export const BREAKPOINTS = 'theia-debug-breakpoints'; + export const BREAKPOINT_ITEM = 'theia-debug-breakpoint-item'; export const BREAKPOINT_DIALOG = 'theia-debug-breakpoint-dialog'; } diff --git a/packages/debug/src/browser/view/debug-stack-frames-widget.ts b/packages/debug/src/browser/view/debug-stack-frames-widget.ts index 4ae2fef35a594..eacbdf899a234 100644 --- a/packages/debug/src/browser/view/debug-stack-frames-widget.ts +++ b/packages/debug/src/browser/view/debug-stack-frames-widget.ts @@ -21,9 +21,10 @@ import { import { DebugSession } from "../debug-model"; import { h } from '@phosphor/virtualdom'; import { DebugProtocol } from 'vscode-debugprotocol'; -import { injectable, inject } from "inversify"; +import { injectable, inject, postConstruct } from "inversify"; import { DebugSelection } from "./debug-selection-service"; import { SourceOpener, DebugUtils } from "../debug-utils"; +import { Disposable } from "@theia/core"; /** * Is it used to display call stack. @@ -39,11 +40,22 @@ export class DebugStackFramesWidget extends VirtualWidget { super(); this.id = this.createId(); - this.addClass(Styles.FRAMES_CONTAINER); + this.addClass('theia-debug-entry'); this.node.setAttribute("tabIndex", "0"); - this.debugSession.on('stopped', event => this.onStoppedEvent(event)); - this.debugSession.on('continued', event => this.onContinuedEvent(event)); - this.debugSelection.onDidSelectThread(thread => this.onThreadSelected(thread)); + } + + @postConstruct() + protected init() { + this.toDisposeOnDetach.push(this.debugSelection.onDidSelectThread(thread => this.onThreadSelected(thread))); + + const stoppedEventListener = (event: DebugProtocol.StoppedEvent) => this.onStoppedEvent(event); + const continuedEventListener = (event: DebugProtocol.ContinuedEvent) => this.onContinuedEvent(event); + + this.debugSession.on('stopped', stoppedEventListener); + this.debugSession.on('continued', continuedEventListener); + + this.toDisposeOnDetach.push(Disposable.create(() => this.debugSession.removeListener('stopped', stoppedEventListener))); + this.toDisposeOnDetach.push(Disposable.create(() => this.debugSession.removeListener('continued', continuedEventListener))); } get frames(): DebugProtocol.StackFrame[] { @@ -56,12 +68,12 @@ export class DebugStackFramesWidget extends VirtualWidget { } protected render(): h.Child { - const header = h.div({ className: "theia-header" }, "Call stack"); + const header = h.div({ className: "theia-debug-header" }, "Call stack"); const items: h.Child = []; const selectedFrame = this.debugSelection.frame; for (const frame of this._frames) { - const className = Styles.FRAME + (DebugUtils.isEqual(selectedFrame, frame) ? ` ${SELECTED_CLASS}` : ''); + const className = Styles.FRAME_ITEM + (DebugUtils.isEqual(selectedFrame, frame) ? ` ${SELECTED_CLASS}` : ''); const id = this.createId(frame); const item = @@ -76,7 +88,7 @@ export class DebugStackFramesWidget extends VirtualWidget { items.push(item); } - return [header, h.div(items)]; + return [header, h.div({ className: Styles.FRAMES }, items)]; } protected onThreadSelected(thread: DebugProtocol.Thread | undefined) { @@ -93,14 +105,14 @@ export class DebugStackFramesWidget extends VirtualWidget { if (currentFrame) { const element = document.getElementById(this.createId(currentFrame)); if (element) { - element.className = Styles.FRAME; + element.className = Styles.FRAME_ITEM; } } if (newFrame) { const element = document.getElementById(this.createId(newFrame)); if (element) { - element.className = `${Styles.FRAME} ${SELECTED_CLASS}`; + element.className = `${Styles.FRAME_ITEM} ${SELECTED_CLASS}`; } } @@ -151,6 +163,6 @@ export class DebugStackFramesWidget extends VirtualWidget { } namespace Styles { - export const FRAMES_CONTAINER = 'theia-debug-frames-container'; - export const FRAME = 'theia-debug-frame'; + export const FRAMES = 'theia-debug-frames'; + export const FRAME_ITEM = 'theia-debug-frame-item'; } diff --git a/packages/debug/src/browser/view/debug-threads-widget.ts b/packages/debug/src/browser/view/debug-threads-widget.ts index 19739caae29e6..48a2252f5fe1c 100644 --- a/packages/debug/src/browser/view/debug-threads-widget.ts +++ b/packages/debug/src/browser/view/debug-threads-widget.ts @@ -22,6 +22,7 @@ import { injectable, inject, postConstruct } from "inversify"; import { DEBUG_SESSION_THREAD_CONTEXT_MENU } from "../debug-command"; import { DebugSelection } from "./debug-selection-service"; import { DebugUtils } from "../debug-utils"; +import { Disposable } from "@theia/core"; /** * Is it used to display list of threads. @@ -37,15 +38,21 @@ export class DebugThreadsWidget extends VirtualWidget { super(); this.id = this.createId(); - this.addClass(Styles.THREADS_CONTAINER); + this.addClass('theia-debug-entry'); this.node.setAttribute("tabIndex", "0"); - - this.debugSession.on('thread', event => this.onThreadEvent(event)); - this.debugSession.on('connected', () => this.updateThreads()); } @postConstruct() protected init() { + const threadEventListener = (event: DebugProtocol.ThreadEvent) => this.onThreadEvent(event); + const connectedEventListener = () => this.updateThreads(); + + this.debugSession.on('thread', threadEventListener); + this.debugSession.on('connected', connectedEventListener); + + this.toDisposeOnDetach.push(Disposable.create(() => this.debugSession.removeListener('thread', threadEventListener))); + this.toDisposeOnDetach.push(Disposable.create(() => this.debugSession.removeListener('connected', connectedEventListener))); + if (this.debugSession.state.isConnected) { this.updateThreads(); } @@ -61,11 +68,11 @@ export class DebugThreadsWidget extends VirtualWidget { } protected render(): h.Child { - const header = h.div({ className: "theia-header" }, "Threads"); + const header = h.div({ className: "theia-debug-header" }, "Threads"); const items: h.Child = []; for (const thread of this.threads) { - const className = Styles.THREAD + (DebugUtils.isEqual(this.debugSelection.thread, thread) ? ` ${SELECTED_CLASS}` : ''); + const className = Styles.THREAD_ITEM + (DebugUtils.isEqual(this.debugSelection.thread, thread) ? ` ${SELECTED_CLASS}` : ''); const id = this.createId(thread); const item = @@ -82,7 +89,7 @@ export class DebugThreadsWidget extends VirtualWidget { items.push(item); } - return [header, h.div(items)]; + return [header, h.div({ className: Styles.THREADS }, items)]; } protected selectThread(newThread: DebugProtocol.Thread | undefined) { @@ -95,14 +102,14 @@ export class DebugThreadsWidget extends VirtualWidget { if (currentThread) { const element = document.getElementById(this.createId(currentThread)); if (element) { - element.className = Styles.THREAD; + element.className = Styles.THREAD_ITEM; } } if (newThread) { const element = document.getElementById(this.createId(newThread)); if (element) { - element.className = `${Styles.THREAD} ${SELECTED_CLASS}`; + element.className = `${Styles.THREAD_ITEM} ${SELECTED_CLASS}`; } } @@ -133,6 +140,6 @@ export class DebugThreadsWidget extends VirtualWidget { } namespace Styles { - export const THREADS_CONTAINER = 'theia-debug-threads-container'; - export const THREAD = 'theia-debug-thread'; + export const THREADS = 'theia-debug-threads'; + export const THREAD_ITEM = 'theia-debug-thread-item'; } diff --git a/packages/debug/src/browser/view/debug-variables-widget.tsx b/packages/debug/src/browser/view/debug-variables-widget.tsx index 23aa099918a99..31412c14d2434 100644 --- a/packages/debug/src/browser/view/debug-variables-widget.tsx +++ b/packages/debug/src/browser/view/debug-variables-widget.tsx @@ -35,6 +35,7 @@ import { DebugSession } from "../debug-model"; import { DebugSelection } from "../view/debug-selection-service"; import { ExtDebugProtocol } from "../../common/debug-common"; import * as React from "react"; +import { Disposable } from "@theia/core"; /** * Is it used to display variables. @@ -53,9 +54,18 @@ export class DebugVariablesWidget extends TreeWidget { this.id = `debug-variables-${debugSession.sessionId}`; this.title.label = 'Variables'; - this.addClass(Styles.VARIABLES_CONTAINER); - this.debugSession.on('variableUpdated', (event: ExtDebugProtocol.VariableUpdatedEvent) => this.onVariableUpdated(event)); - this.debugSelection.onDidSelectFrame(frame => this.onFrameSelected(frame)); + this.addClass('theia-debug-entry'); + } + + @postConstruct() + protected init() { + super.init(); + + this.toDisposeOnDetach.push(Disposable.create(() => this.debugSession.removeListener('variableUpdated', variableUpdateListener))); + + const variableUpdateListener = (event: ExtDebugProtocol.VariableUpdatedEvent) => this.onVariableUpdated(event); + this.debugSession.on('variableUpdated', variableUpdateListener); + this.toDisposeOnDetach.push(this.debugSelection.onDidSelectFrame(frame => this.onFrameSelected(frame))); } protected onFrameSelected(frame: DebugProtocol.StackFrame | undefined) { @@ -73,7 +83,7 @@ export class DebugVariablesWidget extends TreeWidget { } protected renderTree(model: TreeModel): React.ReactNode { - return
Variables
{super.renderTree(model)}
; + return
Variables
{super.renderTree(model)}
; } protected renderCaption(node: TreeNode, props: NodeProps): React.ReactNode { @@ -249,7 +259,3 @@ namespace FrameNode { function createId(sessionId: string, itemId: string | number, parentId?: string | number): string { return `debug-variables-${sessionId}` + (parentId && `-${parentId}`) + `-${itemId}`; } - -namespace Styles { - export const VARIABLES_CONTAINER = 'theia-debug-variables-container'; -} diff --git a/packages/debug/src/browser/view/debug-view-contribution.ts b/packages/debug/src/browser/view/debug-view-contribution.ts index 5521a76e0bca5..8b286d5dea259 100644 --- a/packages/debug/src/browser/view/debug-view-contribution.ts +++ b/packages/debug/src/browser/view/debug-view-contribution.ts @@ -21,7 +21,6 @@ import { TabBarRenderer, TabBarRendererFactory, SideTabBar, - LEFT_RIGHT_AREA_CLASS, Widget, Message, VirtualWidget, @@ -149,7 +148,7 @@ export class DebugWidget extends Panel { private createTabBar(): SideTabBar { const renderer = this.tabBarRendererFactory(); const tabBar = new SideTabBar({ - orientation: 'vertical', + orientation: 'horizontal', insertBehavior: 'none', removeBehavior: 'select-previous-tab', allowDeselect: false, @@ -162,8 +161,7 @@ export class DebugWidget extends Panel { }); renderer.tabBar = tabBar; renderer.contextMenuPath = DEBUG_SESSION_CONTEXT_MENU; - tabBar.addClass('theia-app-left'); - tabBar.addClass(LEFT_RIGHT_AREA_CLASS); + tabBar.addClass('theia-app-centers'); tabBar.currentChanged.connect(this.onCurrentTabChanged, this); tabBar.tabCloseRequested.connect(this.onTabCloseRequested, this); return tabBar; @@ -192,7 +190,7 @@ export class DebugTargetWidget extends VirtualWidget { this.title.closable = true; this.addClass(Styles.DEBUG_TARGET); this.sessionId = debugSession.sessionId; - this.widgets = [this.breakpoints, this.threads, this.frames, this.variables]; + this.widgets = [this.variables, this.threads, this.frames, this.breakpoints]; } protected onUpdateRequest(msg: Message): void { @@ -223,7 +221,7 @@ export class DebugViewContribution extends AbstractViewContribution widgetId: DEBUG_FACTORY_ID, widgetName: 'Debug', defaultWidgetOptions: { - area: 'bottom', + area: 'left', rank: 500 }, toggleCommandId: 'debug.view.toggle',