Skip to content

Commit

Permalink
Add support for switching pane focus with keyboard
Browse files Browse the repository at this point in the history
Using w+arrow-right or w+arrow-left (or h/l) will move the focus from
one pane to the other (any definitions opened will open in the focused
pane). Currently this is indicated by the "non-focused" pane having a
lower opacity. More testing is required to determine if that is a
sufficient affordance.
  • Loading branch information
hojberg committed Nov 25, 2024
1 parent 343e6db commit e977fb7
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 33 deletions.
8 changes: 4 additions & 4 deletions src/Ucm/Workspace/WorkspacePane.elm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Code.ProjectDependency as ProjectDependency exposing (ProjectDependency)
import Code.Source.SourceViewConfig as SourceViewConfig
import Code.Syntax.SyntaxConfig as SyntaxConfig
import Html exposing (Html, div, span, strong, text)
import Html.Attributes exposing (class)
import Html.Attributes exposing (class, classList)
import Lib.HttpApi as HttpApi exposing (ApiRequest, HttpResult)
import Lib.ScrollTo as ScrollTo
import Lib.Util as Util
Expand Down Expand Up @@ -552,9 +552,9 @@ viewItem definitionSummaryTooltip item isFocused =
|> Maybe.withDefault UI.nothing


view : Model -> Html Msg
view model =
div [ class "workspace-pane" ]
view : Bool -> Model -> Html Msg
view isFocused model =
div [ class "workspace-pane", classList [ ( "workspace-pane_focused", isFocused ) ] ]
(model.workspaceItems
|> WorkspaceItems.mapToList (viewItem model.definitionSummaryTooltip)
)
51 changes: 40 additions & 11 deletions src/Ucm/Workspace/WorkspacePanes.elm
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,38 @@ toggleRightPane model =
{ model | focusedPane = focus }


focusRight : Model -> Model
focusRight model =
let
focus =
case model.focusedPane of
LeftPaneFocus { rightPaneVisible } ->
if rightPaneVisible then
RightPaneFocus

else
model.focusedPane

_ ->
model.focusedPane
in
{ model | focusedPane = focus }


focusLeft : Model -> Model
focusLeft model =
let
focus =
case model.focusedPane of
LeftPaneFocus _ ->
model.focusedPane

RightPaneFocus ->
LeftPaneFocus { rightPaneVisible = True }
in
{ model | focusedPane = focus }


openDefinition : Config -> Model -> Reference -> ( Model, Cmd Msg )
openDefinition config model ref =
case model.focusedPane of
Expand Down Expand Up @@ -150,11 +182,11 @@ subscriptions model =
view : Model -> Html Msg
view model =
let
left =
Html.map LeftPaneMsg (WorkspacePane.view model.left)
left isFocused =
Html.map LeftPaneMsg (WorkspacePane.view isFocused model.left)

right =
Html.map RightPaneMsg (WorkspacePane.view model.right)
right isFocused =
Html.map RightPaneMsg (WorkspacePane.view isFocused model.right)

paneConfig =
SplitPane.createViewConfig
Expand All @@ -165,19 +197,16 @@ view model =

splitter =
{ attributes = [ class "workspace-panes_resize-handle" ]
, children =
[ div [ class "workspace-panes_left" ] []
, div [ class "workspace-panes_right" ] []
]
, children = []
}
in
case model.focusedPane of
LeftPaneFocus { rightPaneVisible } ->
if rightPaneVisible then
SplitPane.view paneConfig left right model.splitPane
div [ class "workspace-panes" ] [ SplitPane.view paneConfig (left True) (right False) model.splitPane ]

else
left
div [ class "workspace-panes_single-pane" ] [ left True ]

RightPaneFocus ->
SplitPane.view paneConfig left right model.splitPane
div [ class "workspace-panes" ] [ SplitPane.view paneConfig (left False) (right True) model.splitPane ]
18 changes: 18 additions & 0 deletions src/Ucm/WorkspaceScreen.elm
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ update appContext msg model =
toggleSidebar =
( { model_ | sidebarVisible = not model_.sidebarVisible }, Cmd.none )

focusLeft =
( { model_ | panes = WorkspacePanes.focusLeft model_.panes }, Cmd.none )

focusRight =
( { model_ | panes = WorkspacePanes.focusRight model_.panes }, Cmd.none )

( nextModel, cmd ) =
case ( model_.modal, shortcut ) of
( NoModal, Chord Ctrl (K _) ) ->
Expand All @@ -210,6 +216,18 @@ update appContext msg model =
( NoModal, Chord Ctrl (B _) ) ->
toggleSidebar

( NoModal, Sequence (Just (W _)) ArrowLeft ) ->
focusLeft

( NoModal, Sequence (Just (W _)) (H _) ) ->
focusLeft

( NoModal, Sequence (Just (W _)) ArrowRight ) ->
focusRight

( NoModal, Sequence (Just (W _)) (L _) ) ->
focusRight

( NoModal, Sequence (Just (W _)) (P _) ) ->
let
( switchProject, switchProjectCmd ) =
Expand Down
3 changes: 1 addition & 2 deletions src/Window.elm
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,7 @@ view toMsg model win =
splitter =
{ attributes = [ class "window-sidebar_resize-handle" ]
, children =
[ div [ class "window-sidebar_resize-handle_sidebar-side" ] []
, div [ class "window-sidebar_resize-handle_main-pane-side" ] []
[ div [ class "window-sidebar_resize-handle_main-pane-side" ] []
]
}

Expand Down
1 change: 1 addition & 0 deletions src/css/ucm/workspace/workspace-card.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
padding: 0;
width: 100%;
max-width: var(--c-workspace-card_width);
z-index: var(--layer-base);

& .workspace-card_titlebar {
display: flex;
Expand Down
18 changes: 18 additions & 0 deletions src/css/ucm/workspace/workspace-pane.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,22 @@
}
}
}

&:not(.workspace-pane_focused) {
opacity: 0.65;
}

/*
* POTENTIAL focus indicator
&.workspace-pane_focused::before {
content: " ";
background: linear-gradient(to bottom, var(--color-gray-darken-10), transparent);
height: 20rem;
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: var(--layer-beneath);
}
*/
}
11 changes: 11 additions & 0 deletions src/css/ucm/workspace/workspace-panes.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
.workspace-panes, .workspace-panes_single-pane {
display: flex;
flex: 1;
width: 100%;
height: 100%;
}

.workspace-panes_resize-handle {
width: 1.5rem;
z-index: 1;
Expand All @@ -21,3 +28,7 @@
.workspace-panes_resize-handle:hover::before {
background: var(--u-color_focus-border);
}

.workspace-panes .workspace-card {
max-width: 100% !important;
}
27 changes: 11 additions & 16 deletions src/css/window.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ body:has(.window-footer) {
font-size: var(--font-size-medium);
}

.window-content-shell:has(.window-sidebar) .window-content {
margin-left: -0.5rem;
}

.window-control-bar {
height: 2.5rem;
user-select: none;
Expand Down Expand Up @@ -89,27 +85,26 @@ body:has(.window-footer) {
}

.window-sidebar_resize-handle {
--c-window_sidebar_resize-handle_width: 1rem;
--c-window_sidebar_resize-handle_width: 0.5rem;
height: 100%;
width: var(--c-window_sidebar_resize-handle_width);
transition: all 0.2s;
cursor: col-resize;
margin-left: -0.5rem;

& .window-sidebar_resize-handle_sidebar-side {
position: relative;
height: 100%;
width: calc(var(--c-window_sidebar_resize-handle_width) / 2);
border-right: 1px solid var(--u-color_chrome_border);
}
margin-left: 0;
position: relative;
width: 1px;

& .window-sidebar_resize-handle_main-pane-side {
height: 100%;
width: calc(var(--c-window_sidebar_resize-handle_width) / 2);
width: var(--c-window_sidebar_resize-handle_width);
border-left: 1px solid var(--u-color_chrome_border);
position: absolute;
z-index: var(--layer-floating-controls);
top: 0;
bottom: 0;
}
}

.window-sidebar_resize-handle:hover .window-sidebar_resize-handle_sidebar-side {
.window-sidebar_resize-handle:hover .window-sidebar_resize-handle_main-pane-side {
border-color: var(--u-color_focus-border);
}

Expand Down

0 comments on commit e977fb7

Please sign in to comment.