New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persistent Controls for Docks #16116

Open
matthewwithanm opened this Issue Nov 6, 2017 · 17 comments

Comments

Projects
None yet
7 participants
@matthewwithanm
Member

matthewwithanm commented Nov 6, 2017

Recently, the Nuclide team did a in-depth user research sprint to identify ways to improve our UX and discoverability. One of the suggestions that came out of it was to have persistent, predictably-behaved controls for docks. This is our proposal for adding them to Atom 😊.

In a Nutshell

The vertical controls

  • Add a vertical icon bar to the left and right docks, indicating their current items and grouping and allowing the docks to be toggled and items to be repositioned.
  • Subsume the status-bar package, adding similar controls for the bottom dock.

Proposed Changes

Control UI

dock 20behavior 3a 20default 2c 20groups 2c 20new <img width="445" alt="container group item 1" src="https://user-images.githubusercontent.com/126263/32459791-9d6b4e6c-c2e5-11e7-9568-5f2310760c1d.png">

The controls behave as follows:

  • Clicking on a group will open the dock, revealing the items in the group or (if the dock is already open and showing that group), close it.
  • Dragging an individual icon allows you to move it either within the group, to an existing group, or to create a new group.
  • Dragging a group from the grabber (which appears on hover) allows you to move that group.
  • The ability to remove items is de-emphasized (as compared to the current tabs behavior); it's only possible via the context menu. (As a result, I think we can remove the isPermanentDockItem() optional item method.)
  • The icon bars aren't visible unless there are items in the dock.

Open questions:

  • Having left and right dock icon bars in the vanilla Atom install (tree-view and GitHub packages respectively) might be a little much. We recommend moving Git/Hub to the left dock by default. Then it'll just have one (with three items).

Horizontal Control UI

bottomdock 3a 20exposed 20bottom 20panels

bottomdock_ status bar overflow <img width="445" alt="container group item 1" src="https://user-images.githubusercontent.com/126263/32459782-977f5552-c2e5-11e7-941e-b85cbb404940.png">

Controls for the bottom dock will be integrated into the status bar.

  • Grouping (shown in the first pic above) works the same as in the vertical case.
  • The areas on the left and right will remain reserved for status bar tiles. If they don't fit in the allotted area, they'll be clipped by the dock icon bar. Mousing over the areas will cause them to expand, covering the dock icon bar until the mouse is moved away. (We'll experiment with the exact affordance.)
  • The dock icon bar will have a minimal state containing only the icons (removing the text) if there are too many items for the allotted space.
  • When the left dock is open, the width of the left status bar will be tied to that dock's width (though not allowed to go below a minimum). This will keep the bottom icon bar beneath the bottom dock.

Open questions:

  • Currently, tabs above the dock items display the icon and title. With the new controls, this is kind of redundant so we've removed them to save on vertical space. We may need to put it in front of people and gauge reactions though.

“Tabs of Panes”

Currently, docks have the same organization as the workspace center: containers (“PaneContainers”) have one or more groups (“Panes”), which can each contain multiple items, and each group corresponds to a tab bar for selecting the active item (“tabs within panes”) in that group. A single top-level control, however, implies that the user is activating groups of items, not individual items (“panes within tabs”)*.

In terms of relationships, these two aren't actually that different:

Relationship of concepts: Container, Groups, Items

The difference, then, is that, instead of showing one item of every group, Atom will show every item of a single group group. For example, if the user were to select the ⃟ ♡ ♤ group above, the dock would show the three corresponding items, vertically stacked in that order.

Because the difference is purely presentational, it should be possible to retain the current PaneContainer and Pane model classes but associate them with different views in this context. Some new API (e.g. for toggling a Pane) will be necessary.

Open questions:

  • How do we handle the need for new API in dock panes? Are dock Panes a subclass of Pane?
  • Is the word “pane” so strongly associated with a particular presentation that the difference is confusing?
  • What issues will the changes in presentation cause in existing packages? (e.g. currently, non-active items are implicitly non-visible)
  • I think I can implement this in a separate (but bundled) package, dumb down vanilla docks, and remove the docks interaction from the tabs package.

Removal of Dock Toggle Button Affordance

Because the docks will be toggled by the icon bars, these are no longer necessary.

Badge/Notification Support

The presence of persistent controls for dock items means that we'll now have a more natural place for showing those items' statuses than the disconnected icons of the status bar. For example, the button for toggling the diagnostics table can also indicate how many errors there are; the console can indicate new messages.

Our proposal for this is to add two new (optional) methods on workspace items:

getStatus(): {
  severity?: 'info' | 'warning' | 'error',
  count?: number,
},
onDidChangeStatus: (
  cb: (status: {
    severity?: 'info' | 'warning' | 'error',
    count?: number,
  }) => mixed,
) => IDisposable,

While somewhat limiting, this API enforces a consistency of experience across dock items and can be easily expanded later.

Atom will subscribe to this event and show appropriate badges on the items in the persistent controls.

Open questions:

  • I chose getStatus() and onDidChangeStatus() for symmetry with getTitle(), onDidChangeTitle(), getIcon(), etc. However, in many ways, observeStatus() is more natural. Unlike title and icon, status is a changing value by definition. Also, having users implement one method instead of two would be nice. I still think having two methods is the right call but I wanted to flag this for discussion.

*See #672 for some history on this terminology.

cc @karincurkowicz who's been doing the design work on this and @nathansobo who we talked to a while back

@lee-dohm

This comment has been minimized.

Show comment
Hide comment
@lee-dohm

lee-dohm Nov 7, 2017

Member

The areas on the left and right will remain reserved for status bar tiles. If they don't fit in the allotted area, they'll be clipped by the dock icon bar.

I disagree with the status bar tiles being shrunk by the dock icons. The point of a status bar is to be able to look at it and get the current status of things, like a clock on the wall. Having to move the mouse cursor over it even just to hover to get it to expand defeats the purpose. On the other hand, in order to interact with the dock icons (leaving aside the "badge/notifications" part) it seems that your design expects people to move the mouse cursor over them. It would then make more sense for the dock icons to be shrunk or clipped in favor of the status bar tiles until the mouse is hovered over the dock icons area.

Member

lee-dohm commented Nov 7, 2017

The areas on the left and right will remain reserved for status bar tiles. If they don't fit in the allotted area, they'll be clipped by the dock icon bar.

I disagree with the status bar tiles being shrunk by the dock icons. The point of a status bar is to be able to look at it and get the current status of things, like a clock on the wall. Having to move the mouse cursor over it even just to hover to get it to expand defeats the purpose. On the other hand, in order to interact with the dock icons (leaving aside the "badge/notifications" part) it seems that your design expects people to move the mouse cursor over them. It would then make more sense for the dock icons to be shrunk or clipped in favor of the status bar tiles until the mouse is hovered over the dock icons area.

@Ben3eeE

This comment has been minimized.

Show comment
Hide comment
@Ben3eeE

Ben3eeE Nov 7, 2017

Member

Removal of Dock Toggle Button Affordance

I believe this would fix #15728 and #14803

Member

Ben3eeE commented Nov 7, 2017

Removal of Dock Toggle Button Affordance

I believe this would fix #15728 and #14803

@matthewwithanm

This comment has been minimized.

Show comment
Hide comment
@matthewwithanm

matthewwithanm Nov 8, 2017

Member

@karincurkowicz, @nathansobo, @maxbrunsfeld and I just got on video to run through some of these things quick. Some key takeaways:

  • We need to have an "auto hide" option.
    • The icon bar will always be visible when the dock is expanded.
    • When hiding is enabled, the icon bar will appear over the content when the mouse is near.
  • We need to experiment with the bottom dock overflow case (@lee-dohm's point above) to see which is preferable.
  • We'll need to handle the situation where models don't implement getIcon()—probably by displaying the first letter of the title (which is already effectively required by the tabs package).
  • The tentative plans for the dock API is to keep it substantially the same but to deprecate all of the methods containing the word "Pane" with equivalents calling them "Groups." We'll evaluate the API after we have something written and can play with it a little more.
    • Still need to figure out what this means for the idea that docks are comparable to the workspace center (e.g. workspace.getPaneContainers()) 🤔. Are we abandoning this and differentiating them more?
  • A more declarative way to specify that an instance of a dock item should be shown would (1) be convenient for package authors and (2) allow us to show a list of available (but removed) items.
    • This could take the form of a new entry in the package.json. For example, Array<{title: string, icon: string, defaultLocation: string, uri: string}>. (Note that these are already specified by the model, but aren't available statically, e.g. to be used for 2 above.)
    • This is mostly orthogonal to the issue at hand, unless we decide that dock item creation should diverge from the uri-based model of other workspace items.
Member

matthewwithanm commented Nov 8, 2017

@karincurkowicz, @nathansobo, @maxbrunsfeld and I just got on video to run through some of these things quick. Some key takeaways:

  • We need to have an "auto hide" option.
    • The icon bar will always be visible when the dock is expanded.
    • When hiding is enabled, the icon bar will appear over the content when the mouse is near.
  • We need to experiment with the bottom dock overflow case (@lee-dohm's point above) to see which is preferable.
  • We'll need to handle the situation where models don't implement getIcon()—probably by displaying the first letter of the title (which is already effectively required by the tabs package).
  • The tentative plans for the dock API is to keep it substantially the same but to deprecate all of the methods containing the word "Pane" with equivalents calling them "Groups." We'll evaluate the API after we have something written and can play with it a little more.
    • Still need to figure out what this means for the idea that docks are comparable to the workspace center (e.g. workspace.getPaneContainers()) 🤔. Are we abandoning this and differentiating them more?
  • A more declarative way to specify that an instance of a dock item should be shown would (1) be convenient for package authors and (2) allow us to show a list of available (but removed) items.
    • This could take the form of a new entry in the package.json. For example, Array<{title: string, icon: string, defaultLocation: string, uri: string}>. (Note that these are already specified by the model, but aren't available statically, e.g. to be used for 2 above.)
    • This is mostly orthogonal to the issue at hand, unless we decide that dock item creation should diverge from the uri-based model of other workspace items.
@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Nov 8, 2017

Contributor

@Alhadis I'd be curious about your thoughts about a strategy for providing more icon choices for pane items.

Contributor

nathansobo commented Nov 8, 2017

@Alhadis I'd be curious about your thoughts about a strategy for providing more icon choices for pane items.

@Alhadis

This comment has been minimized.

Show comment
Hide comment
@Alhadis

Alhadis Nov 8, 2017

A unified approach would be nice. Currently, there are five different implementations of the icon-services, one for each core package that uses them. Needless to say, that's not going to be fun to maintain.

Is there anything the current service is lacking that would need to be considered for this to happen?

Alhadis commented Nov 8, 2017

A unified approach would be nice. Currently, there are five different implementations of the icon-services, one for each core package that uses them. Needless to say, that's not going to be fun to maintain.

Is there anything the current service is lacking that would need to be considered for this to happen?

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Nov 8, 2017

Contributor

@Alhadis, if and when when you have time, I'd be interested in seeing a proposal for what a core API for making icons more extensible might look like based on your experience with your package and the services. It's one of the most popular packages so that seems to suggest that making it part of core would be wise. We can do it in another channel to keep this issue focused.

Contributor

nathansobo commented Nov 8, 2017

@Alhadis, if and when when you have time, I'd be interested in seeing a proposal for what a core API for making icons more extensible might look like based on your experience with your package and the services. It's one of the most popular packages so that seems to suggest that making it part of core would be wise. We can do it in another channel to keep this issue focused.

@Alhadis

This comment has been minimized.

Show comment
Hide comment
@Alhadis

Alhadis Nov 8, 2017

Sure thing. Which channel? And which forms of extensibility were you thinking about?

Alhadis commented Nov 8, 2017

Sure thing. Which channel? And which forms of extensibility were you thinking about?

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Nov 8, 2017

Contributor

Just an issue... mainly just how do we let people install packages that can offer options for customizing the icons of dock items like the debugger, file tree, diagnostics etc. Like what should the icon story be in Atom ideally?

Contributor

nathansobo commented Nov 8, 2017

Just an issue... mainly just how do we let people install packages that can offer options for customizing the icons of dock items like the debugger, file tree, diagnostics etc. Like what should the icon story be in Atom ideally?

@Alhadis

This comment has been minimized.

Show comment
Hide comment
@Alhadis

Alhadis Nov 8, 2017

Like what should the icon story be in Atom ideally?

Ideally, there should only be one icon-service for element-icons, and that can easily be revised to accommodate subjects which aren't filesystem entities. To recap, the service supplies a function with this signature:

addIconToElement(element, path, options = {}) (Disposable)

We can still use this: but we need to think of the second parameter as a uri, rather than a filesystem path. This would fit neatly into Atom's existing URI-based model:

addIconToElement(element, uri);
addIconToElement(iconDiv, "/path/to/file.txt");
addIconToElement(iconDiv, "nuclide://tree-view-icons/some/icon/id");
addIconToElement(iconDiv, "atom://config");

Am I following okay? If not, it might help to see some actual examples of where these icons might be assigned in cases where they're not file-related... because I actually can't think of any that need to be dynamic.

Alhadis commented Nov 8, 2017

Like what should the icon story be in Atom ideally?

Ideally, there should only be one icon-service for element-icons, and that can easily be revised to accommodate subjects which aren't filesystem entities. To recap, the service supplies a function with this signature:

addIconToElement(element, path, options = {}) (Disposable)

We can still use this: but we need to think of the second parameter as a uri, rather than a filesystem path. This would fit neatly into Atom's existing URI-based model:

addIconToElement(element, uri);
addIconToElement(iconDiv, "/path/to/file.txt");
addIconToElement(iconDiv, "nuclide://tree-view-icons/some/icon/id");
addIconToElement(iconDiv, "atom://config");

Am I following okay? If not, it might help to see some actual examples of where these icons might be assigned in cases where they're not file-related... because I actually can't think of any that need to be dynamic.

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Nov 8, 2017

Contributor

@Alhadis Maybe this already just works via the tabs package already and we don't need to worry about it. I think we may need to let it evolve a bit and check in on the icons story later. Just wanted to make you aware of it more than anything since it leans on icons more heavily than anything has in Atom yet.

Contributor

nathansobo commented Nov 8, 2017

@Alhadis Maybe this already just works via the tabs package already and we don't need to worry about it. I think we may need to let it evolve a bit and check in on the icons story later. Just wanted to make you aware of it more than anything since it leans on icons more heavily than anything has in Atom yet.

@Alhadis

This comment has been minimized.

Show comment
Hide comment
@Alhadis

Alhadis Nov 8, 2017

Alright, thanks for the heads up. ;)

Truth be told, though, the tabs package only supports icons because the earliest versions of Atom (in my memory) assigned icons to "special" panels like Settings, About Atom, Deprecation Cop, and so forth. It yielded a rather ad-hoc method called getIcon(), which TTBOMK, was never used for anything else other than those special edge-cases.

So what @matthewwithanm is proposing re: the replacement of getIcon and co with observeStatus is certainly a step in the right direction, IMHO. No need to be carrying old relics if we're revamping everything.

Alhadis commented Nov 8, 2017

Alright, thanks for the heads up. ;)

Truth be told, though, the tabs package only supports icons because the earliest versions of Atom (in my memory) assigned icons to "special" panels like Settings, About Atom, Deprecation Cop, and so forth. It yielded a rather ad-hoc method called getIcon(), which TTBOMK, was never used for anything else other than those special edge-cases.

So what @matthewwithanm is proposing re: the replacement of getIcon and co with observeStatus is certainly a step in the right direction, IMHO. No need to be carrying old relics if we're revamping everything.

@matthewwithanm

This comment has been minimized.

Show comment
Hide comment
@matthewwithanm

matthewwithanm Nov 9, 2017

Member

So what @matthewwithanm is proposing re: the replacement of getIcon and co with observeStatus is certainly a step in the right direction, IMHO. No need to be carrying old relics if we're revamping everything.

I was actually proposing carrying the old relic 😊

Our proposal for the status notifications is that they would overlay the icons. Mostly, I'd just like to keep the icon question separate. Since workspace items (including dock items) currently use getIcon(), it makes sense to me not to touch that as part of this proposal.

Member

matthewwithanm commented Nov 9, 2017

So what @matthewwithanm is proposing re: the replacement of getIcon and co with observeStatus is certainly a step in the right direction, IMHO. No need to be carrying old relics if we're revamping everything.

I was actually proposing carrying the old relic 😊

Our proposal for the status notifications is that they would overlay the icons. Mostly, I'd just like to keep the icon question separate. Since workspace items (including dock items) currently use getIcon(), it makes sense to me not to touch that as part of this proposal.

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Nov 9, 2017

Contributor

Sorry, I didn't intend the icon discussion to balloon into several screens worth of scrolling. Lesson learned. Let's table further icon discussion for now.

Contributor

nathansobo commented Nov 9, 2017

Sorry, I didn't intend the icon discussion to balloon into several screens worth of scrolling. Lesson learned. Let's table further icon discussion for now.

@RenaKunisaki

This comment has been minimized.

Show comment
Hide comment
@RenaKunisaki

RenaKunisaki Dec 1, 2017

Right now I'm just annoyed that some packages provide a tab that goes into a pane (linter-ui-default) and others provide a tab that goes into a dock (todo-show) and for some reason these are different things, so I can't have Linter and Todo Show stacked vertically at the side of the screen. Can't drag the todo tab into a pane or the linter tab into a dock, nothing happens in either case.

Why are these different things anyway? The only difference from a UI standpoint seems to be that a dock can be hidden by clicking the arrow. Could we not just drop a regular tab into there instead of a special one, and have a pane that can hide?

Actually, it seems like I can get normal editor tabs into a dock by trying to drag a "special" tab from the right side dock to the left side onto an existing dock. For some reason that moves an editor tab instead of the one I dragged. It works perfectly though, except that I have to exploit this bug to do it (and can only put them on the left this way). So it seems like all that's missing is the ability to actually drag editor tabs into docks.

RenaKunisaki commented Dec 1, 2017

Right now I'm just annoyed that some packages provide a tab that goes into a pane (linter-ui-default) and others provide a tab that goes into a dock (todo-show) and for some reason these are different things, so I can't have Linter and Todo Show stacked vertically at the side of the screen. Can't drag the todo tab into a pane or the linter tab into a dock, nothing happens in either case.

Why are these different things anyway? The only difference from a UI standpoint seems to be that a dock can be hidden by clicking the arrow. Could we not just drop a regular tab into there instead of a special one, and have a pane that can hide?

Actually, it seems like I can get normal editor tabs into a dock by trying to drag a "special" tab from the right side dock to the left side onto an existing dock. For some reason that moves an editor tab instead of the one I dragged. It works perfectly though, except that I have to exploit this bug to do it (and can only put them on the left this way). So it seems like all that's missing is the ability to actually drag editor tabs into docks.

@lee-dohm

This comment has been minimized.

Show comment
Hide comment
@lee-dohm

lee-dohm Dec 1, 2017

Member

@RenaKunisaki For more information on Docks and the rationale behind them, see the Docks Deep Dive blog post. Let's keep this issue on topic as to persistent controls in docks. For Docks vs. Panels questions and discussion you can use Discuss, the official Atom message board, or the Slack team.

Member

lee-dohm commented Dec 1, 2017

@RenaKunisaki For more information on Docks and the rationale behind them, see the Docks Deep Dive blog post. Let's keep this issue on topic as to persistent controls in docks. For Docks vs. Panels questions and discussion you can use Discuss, the official Atom message board, or the Slack team.

@simurai

This comment has been minimized.

Show comment
Hide comment
@simurai

simurai Dec 8, 2017

Member

Love it! 😍

Having left and right dock icon bars in the vanilla Atom install (tree-view and GitHub packages respectively) might be a little much. We recommend moving Git/Hub to the left dock by default. Then it'll just have one (with three items).

Agreed. 👍

Another question: Would grouping of dock items be preserved across projects (and be reflected on other open windows? For example if I drag the outline view to another group and then open another project, the outline view should also appear at the new position in that project. Currently when rearranging dock items, they are remembered on a per project basis. In some cases ok and keeps things flexible, but could also get tedious having to re-arrange it for every existing project separately.

Member

simurai commented Dec 8, 2017

Love it! 😍

Having left and right dock icon bars in the vanilla Atom install (tree-view and GitHub packages respectively) might be a little much. We recommend moving Git/Hub to the left dock by default. Then it'll just have one (with three items).

Agreed. 👍

Another question: Would grouping of dock items be preserved across projects (and be reflected on other open windows? For example if I drag the outline view to another group and then open another project, the outline view should also appear at the new position in that project. Currently when rearranging dock items, they are remembered on a per project basis. In some cases ok and keeps things flexible, but could also get tedious having to re-arrange it for every existing project separately.

@simurai

This comment has been minimized.

Show comment
Hide comment
@simurai

simurai Dec 22, 2017

Member

The other day I mocked up how the GitHub package could behave with permanent dock controls: atom/github#440 (comment)

Here with a number badge added:

controls 4

Some packages might want to show more infos. So instead of only a number, it could be a string under the icon. Then for example the Git panel could show behind/ahead like: 1 / 3. Or there could also be status like error, warning, success that will show as an additional icon. Like the GitHub panel could show if CI succeeded with a checkmark.

controls 5

Not sure, might be visually too noisy. Or the main icons need to be bigger.

Member

simurai commented Dec 22, 2017

The other day I mocked up how the GitHub package could behave with permanent dock controls: atom/github#440 (comment)

Here with a number badge added:

controls 4

Some packages might want to show more infos. So instead of only a number, it could be a string under the icon. Then for example the Git panel could show behind/ahead like: 1 / 3. Or there could also be status like error, warning, success that will show as an additional icon. Like the GitHub panel could show if CI succeeded with a checkmark.

controls 5

Not sure, might be visually too noisy. Or the main icons need to be bigger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment