From 615319b2ab14da98c93ad7526da8490233e2d963 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 11 May 2022 16:50:51 -0700 Subject: [PATCH] Rework the contact panel's styling to allow keyboard navigation Co-authored-by: Nathan Sobo --- assets/themes/cave-dark.json | 63 ++++-- assets/themes/cave-light.json | 63 ++++-- assets/themes/dark.json | 63 ++++-- assets/themes/light.json | 63 ++++-- assets/themes/solarized-dark.json | 63 ++++-- assets/themes/solarized-light.json | 63 ++++-- assets/themes/sulphurpool-dark.json | 63 ++++-- assets/themes/sulphurpool-light.json | 63 ++++-- crates/contacts_panel/src/contacts_panel.rs | 211 ++++++++++---------- crates/theme/src/theme.rs | 12 +- styles/src/styleTree/app.ts | 2 +- styles/src/styleTree/contactsPanel.ts | 61 ++++-- 12 files changed, 526 insertions(+), 264 deletions(-) diff --git a/assets/themes/cave-dark.json b/assets/themes/cave-dark.json index 826206477d..a944d171fa 100644 --- a/assets/themes/cave-dark.json +++ b/assets/themes/cave-dark.json @@ -989,9 +989,7 @@ "chat_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "channel_name": { "family": "Zed Sans", @@ -1208,9 +1206,7 @@ "contacts_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "user_query_editor": { "background": "#19171c", @@ -1238,23 +1234,33 @@ "left": 8, "right": 8, "top": 4 + }, + "margin": { + "left": 12, + "right": 12 } }, "user_query_editor_height": 32, "add_contact_button": { "margin": { - "left": 6 + "left": 6, + "right": 12 }, "color": "#e2dfe7", "button_width": 8, "icon_width": 8 }, + "row_height": 28, "header_row": { "family": "Zed Mono", "color": "#8b8792", "size": 14, "margin": { - "top": 8 + "top": 14 + }, + "padding": { + "left": 12, + "right": 12 }, "active": { "family": "Zed Mono", @@ -1265,15 +1271,23 @@ }, "contact_row": { "padding": { - "left": 8 + "left": 12, + "right": 12 }, "active": { "background": "#5852605c" } }, - "row_height": 28, - "tree_branch_color": "#655f6d", - "tree_branch_width": 1, + "tree_branch": { + "color": "#655f6d", + "width": 1, + "hover": { + "color": "#655f6d" + }, + "active": { + "color": "#655f6d" + } + }, "contact_avatar": { "corner_radius": 10, "width": 18 @@ -1282,10 +1296,11 @@ "family": "Zed Mono", "color": "#e2dfe7", "size": 14, - "padding": { + "margin": { "left": 8 } }, + "contact_button_spacing": 8, "contact_button": { "background": "#26232a", "color": "#e2dfe7", @@ -1315,14 +1330,21 @@ "color": "#8b8792", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#26232a", - "corner_radius": 6, "hover": { "background": "#5852603d" }, @@ -1342,14 +1364,21 @@ "color": "#8b8792", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#26232a", - "corner_radius": 6, "hover": { "background": "#5852603d" }, diff --git a/assets/themes/cave-light.json b/assets/themes/cave-light.json index 19158e53b1..47f397a017 100644 --- a/assets/themes/cave-light.json +++ b/assets/themes/cave-light.json @@ -989,9 +989,7 @@ "chat_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "channel_name": { "family": "Zed Sans", @@ -1208,9 +1206,7 @@ "contacts_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "user_query_editor": { "background": "#efecf4", @@ -1238,23 +1234,33 @@ "left": 8, "right": 8, "top": 4 + }, + "margin": { + "left": 12, + "right": 12 } }, "user_query_editor_height": 32, "add_contact_button": { "margin": { - "left": 6 + "left": 6, + "right": 12 }, "color": "#26232a", "button_width": 8, "icon_width": 8 }, + "row_height": 28, "header_row": { "family": "Zed Mono", "color": "#585260", "size": 14, "margin": { - "top": 8 + "top": 14 + }, + "padding": { + "left": 12, + "right": 12 }, "active": { "family": "Zed Mono", @@ -1265,15 +1271,23 @@ }, "contact_row": { "padding": { - "left": 8 + "left": 12, + "right": 12 }, "active": { "background": "#8b87922e" } }, - "row_height": 28, - "tree_branch_color": "#7e7887", - "tree_branch_width": 1, + "tree_branch": { + "color": "#7e7887", + "width": 1, + "hover": { + "color": "#7e7887" + }, + "active": { + "color": "#7e7887" + } + }, "contact_avatar": { "corner_radius": 10, "width": 18 @@ -1282,10 +1296,11 @@ "family": "Zed Mono", "color": "#26232a", "size": 14, - "padding": { + "margin": { "left": 8 } }, + "contact_button_spacing": 8, "contact_button": { "background": "#e2dfe7", "color": "#26232a", @@ -1315,14 +1330,21 @@ "color": "#585260", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#e2dfe7", - "corner_radius": 6, "hover": { "background": "#8b87921f" }, @@ -1342,14 +1364,21 @@ "color": "#585260", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#e2dfe7", - "corner_radius": 6, "hover": { "background": "#8b87921f" }, diff --git a/assets/themes/dark.json b/assets/themes/dark.json index 3adc9ec29e..f9aeb3e3b1 100644 --- a/assets/themes/dark.json +++ b/assets/themes/dark.json @@ -989,9 +989,7 @@ "chat_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "channel_name": { "family": "Zed Sans", @@ -1208,9 +1206,7 @@ "contacts_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "user_query_editor": { "background": "#000000", @@ -1238,23 +1234,33 @@ "left": 8, "right": 8, "top": 4 + }, + "margin": { + "left": 12, + "right": 12 } }, "user_query_editor_height": 32, "add_contact_button": { "margin": { - "left": 6 + "left": 6, + "right": 12 }, "color": "#c6c6c6", "button_width": 8, "icon_width": 8 }, + "row_height": 28, "header_row": { "family": "Zed Mono", "color": "#9c9c9c", "size": 14, "margin": { - "top": 8 + "top": 14 + }, + "padding": { + "left": 12, + "right": 12 }, "active": { "family": "Zed Mono", @@ -1265,15 +1271,23 @@ }, "contact_row": { "padding": { - "left": 8 + "left": 12, + "right": 12 }, "active": { "background": "#1c1c1c" } }, - "row_height": 28, - "tree_branch_color": "#404040", - "tree_branch_width": 1, + "tree_branch": { + "color": "#000000", + "width": 1, + "hover": { + "color": "#000000" + }, + "active": { + "color": "#000000" + } + }, "contact_avatar": { "corner_radius": 10, "width": 18 @@ -1282,10 +1296,11 @@ "family": "Zed Mono", "color": "#f1f1f1", "size": 14, - "padding": { + "margin": { "left": 8 } }, + "contact_button_spacing": 8, "contact_button": { "background": "#2b2b2b", "color": "#c6c6c6", @@ -1315,14 +1330,21 @@ "color": "#9c9c9c", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#1c1c1c", - "corner_radius": 6, "hover": { "background": "#232323" }, @@ -1342,14 +1364,21 @@ "color": "#9c9c9c", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#1c1c1c", - "corner_radius": 6, "hover": { "background": "#232323" }, diff --git a/assets/themes/light.json b/assets/themes/light.json index 69bca672f7..6a9624b587 100644 --- a/assets/themes/light.json +++ b/assets/themes/light.json @@ -989,9 +989,7 @@ "chat_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "channel_name": { "family": "Zed Sans", @@ -1208,9 +1206,7 @@ "contacts_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "user_query_editor": { "background": "#ffffff", @@ -1238,23 +1234,33 @@ "left": 8, "right": 8, "top": 4 + }, + "margin": { + "left": 12, + "right": 12 } }, "user_query_editor_height": 32, "add_contact_button": { "margin": { - "left": 6 + "left": 6, + "right": 12 }, "color": "#393939", "button_width": 8, "icon_width": 8 }, + "row_height": 28, "header_row": { "family": "Zed Mono", "color": "#474747", "size": 14, "margin": { - "top": 8 + "top": 14 + }, + "padding": { + "left": 12, + "right": 12 }, "active": { "family": "Zed Mono", @@ -1265,15 +1271,23 @@ }, "contact_row": { "padding": { - "left": 8 + "left": 12, + "right": 12 }, "active": { "background": "#d5d5d5" } }, - "row_height": 28, - "tree_branch_color": "#e3e3e3", - "tree_branch_width": 1, + "tree_branch": { + "color": "#b8b8b8", + "width": 1, + "hover": { + "color": "#b8b8b8" + }, + "active": { + "color": "#b8b8b8" + } + }, "contact_avatar": { "corner_radius": 10, "width": 18 @@ -1282,10 +1296,11 @@ "family": "Zed Mono", "color": "#2b2b2b", "size": 14, - "padding": { + "margin": { "left": 8 } }, + "contact_button_spacing": 8, "contact_button": { "background": "#eaeaea", "color": "#393939", @@ -1315,14 +1330,21 @@ "color": "#474747", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#f8f8f8", - "corner_radius": 6, "hover": { "background": "#eaeaea" }, @@ -1342,14 +1364,21 @@ "color": "#474747", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#f8f8f8", - "corner_radius": 6, "hover": { "background": "#eaeaea" }, diff --git a/assets/themes/solarized-dark.json b/assets/themes/solarized-dark.json index 75e0eb9b7b..d360fea75c 100644 --- a/assets/themes/solarized-dark.json +++ b/assets/themes/solarized-dark.json @@ -989,9 +989,7 @@ "chat_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "channel_name": { "family": "Zed Sans", @@ -1208,9 +1206,7 @@ "contacts_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "user_query_editor": { "background": "#002b36", @@ -1238,23 +1234,33 @@ "left": 8, "right": 8, "top": 4 + }, + "margin": { + "left": 12, + "right": 12 } }, "user_query_editor_height": 32, "add_contact_button": { "margin": { - "left": 6 + "left": 6, + "right": 12 }, "color": "#eee8d5", "button_width": 8, "icon_width": 8 }, + "row_height": 28, "header_row": { "family": "Zed Mono", "color": "#93a1a1", "size": 14, "margin": { - "top": 8 + "top": 14 + }, + "padding": { + "left": 12, + "right": 12 }, "active": { "family": "Zed Mono", @@ -1265,15 +1271,23 @@ }, "contact_row": { "padding": { - "left": 8 + "left": 12, + "right": 12 }, "active": { "background": "#586e755c" } }, - "row_height": 28, - "tree_branch_color": "#657b83", - "tree_branch_width": 1, + "tree_branch": { + "color": "#657b83", + "width": 1, + "hover": { + "color": "#657b83" + }, + "active": { + "color": "#657b83" + } + }, "contact_avatar": { "corner_radius": 10, "width": 18 @@ -1282,10 +1296,11 @@ "family": "Zed Mono", "color": "#eee8d5", "size": 14, - "padding": { + "margin": { "left": 8 } }, + "contact_button_spacing": 8, "contact_button": { "background": "#073642", "color": "#eee8d5", @@ -1315,14 +1330,21 @@ "color": "#93a1a1", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#073642", - "corner_radius": 6, "hover": { "background": "#586e753d" }, @@ -1342,14 +1364,21 @@ "color": "#93a1a1", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#073642", - "corner_radius": 6, "hover": { "background": "#586e753d" }, diff --git a/assets/themes/solarized-light.json b/assets/themes/solarized-light.json index e88872bdfb..0f93014911 100644 --- a/assets/themes/solarized-light.json +++ b/assets/themes/solarized-light.json @@ -989,9 +989,7 @@ "chat_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "channel_name": { "family": "Zed Sans", @@ -1208,9 +1206,7 @@ "contacts_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "user_query_editor": { "background": "#fdf6e3", @@ -1238,23 +1234,33 @@ "left": 8, "right": 8, "top": 4 + }, + "margin": { + "left": 12, + "right": 12 } }, "user_query_editor_height": 32, "add_contact_button": { "margin": { - "left": 6 + "left": 6, + "right": 12 }, "color": "#073642", "button_width": 8, "icon_width": 8 }, + "row_height": 28, "header_row": { "family": "Zed Mono", "color": "#586e75", "size": 14, "margin": { - "top": 8 + "top": 14 + }, + "padding": { + "left": 12, + "right": 12 }, "active": { "family": "Zed Mono", @@ -1265,15 +1271,23 @@ }, "contact_row": { "padding": { - "left": 8 + "left": 12, + "right": 12 }, "active": { "background": "#93a1a12e" } }, - "row_height": 28, - "tree_branch_color": "#839496", - "tree_branch_width": 1, + "tree_branch": { + "color": "#839496", + "width": 1, + "hover": { + "color": "#839496" + }, + "active": { + "color": "#839496" + } + }, "contact_avatar": { "corner_radius": 10, "width": 18 @@ -1282,10 +1296,11 @@ "family": "Zed Mono", "color": "#073642", "size": 14, - "padding": { + "margin": { "left": 8 } }, + "contact_button_spacing": 8, "contact_button": { "background": "#eee8d5", "color": "#073642", @@ -1315,14 +1330,21 @@ "color": "#586e75", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#eee8d5", - "corner_radius": 6, "hover": { "background": "#93a1a11f" }, @@ -1342,14 +1364,21 @@ "color": "#586e75", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#eee8d5", - "corner_radius": 6, "hover": { "background": "#93a1a11f" }, diff --git a/assets/themes/sulphurpool-dark.json b/assets/themes/sulphurpool-dark.json index ef136a0e44..ab316085b2 100644 --- a/assets/themes/sulphurpool-dark.json +++ b/assets/themes/sulphurpool-dark.json @@ -989,9 +989,7 @@ "chat_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "channel_name": { "family": "Zed Sans", @@ -1208,9 +1206,7 @@ "contacts_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "user_query_editor": { "background": "#202746", @@ -1238,23 +1234,33 @@ "left": 8, "right": 8, "top": 4 + }, + "margin": { + "left": 12, + "right": 12 } }, "user_query_editor_height": 32, "add_contact_button": { "margin": { - "left": 6 + "left": 6, + "right": 12 }, "color": "#dfe2f1", "button_width": 8, "icon_width": 8 }, + "row_height": 28, "header_row": { "family": "Zed Mono", "color": "#979db4", "size": 14, "margin": { - "top": 8 + "top": 14 + }, + "padding": { + "left": 12, + "right": 12 }, "active": { "family": "Zed Mono", @@ -1265,15 +1271,23 @@ }, "contact_row": { "padding": { - "left": 8 + "left": 12, + "right": 12 }, "active": { "background": "#5e66875c" } }, - "row_height": 28, - "tree_branch_color": "#6b7394", - "tree_branch_width": 1, + "tree_branch": { + "color": "#6b7394", + "width": 1, + "hover": { + "color": "#6b7394" + }, + "active": { + "color": "#6b7394" + } + }, "contact_avatar": { "corner_radius": 10, "width": 18 @@ -1282,10 +1296,11 @@ "family": "Zed Mono", "color": "#dfe2f1", "size": 14, - "padding": { + "margin": { "left": 8 } }, + "contact_button_spacing": 8, "contact_button": { "background": "#293256", "color": "#dfe2f1", @@ -1315,14 +1330,21 @@ "color": "#979db4", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#293256", - "corner_radius": 6, "hover": { "background": "#5e66873d" }, @@ -1342,14 +1364,21 @@ "color": "#979db4", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#293256", - "corner_radius": 6, "hover": { "background": "#5e66873d" }, diff --git a/assets/themes/sulphurpool-light.json b/assets/themes/sulphurpool-light.json index 998a540f1b..56a2468b77 100644 --- a/assets/themes/sulphurpool-light.json +++ b/assets/themes/sulphurpool-light.json @@ -989,9 +989,7 @@ "chat_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "channel_name": { "family": "Zed Sans", @@ -1208,9 +1206,7 @@ "contacts_panel": { "padding": { "top": 12, - "left": 12, - "bottom": 12, - "right": 12 + "bottom": 12 }, "user_query_editor": { "background": "#f5f7ff", @@ -1238,23 +1234,33 @@ "left": 8, "right": 8, "top": 4 + }, + "margin": { + "left": 12, + "right": 12 } }, "user_query_editor_height": 32, "add_contact_button": { "margin": { - "left": 6 + "left": 6, + "right": 12 }, "color": "#293256", "button_width": 8, "icon_width": 8 }, + "row_height": 28, "header_row": { "family": "Zed Mono", "color": "#5e6687", "size": 14, "margin": { - "top": 8 + "top": 14 + }, + "padding": { + "left": 12, + "right": 12 }, "active": { "family": "Zed Mono", @@ -1265,15 +1271,23 @@ }, "contact_row": { "padding": { - "left": 8 + "left": 12, + "right": 12 }, "active": { "background": "#979db42e" } }, - "row_height": 28, - "tree_branch_color": "#898ea4", - "tree_branch_width": 1, + "tree_branch": { + "color": "#898ea4", + "width": 1, + "hover": { + "color": "#898ea4" + }, + "active": { + "color": "#898ea4" + } + }, "contact_avatar": { "corner_radius": 10, "width": 18 @@ -1282,10 +1296,11 @@ "family": "Zed Mono", "color": "#293256", "size": 14, - "padding": { + "margin": { "left": 8 } }, + "contact_button_spacing": 8, "contact_button": { "background": "#dfe2f1", "color": "#293256", @@ -1315,14 +1330,21 @@ "color": "#5e6687", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#dfe2f1", - "corner_radius": 6, "hover": { "background": "#979db41f" }, @@ -1342,14 +1364,21 @@ "color": "#5e6687", "size": 14, "margin": { + "left": 8, "right": 6 } }, + "guests": { + "margin": { + "left": 8, + "right": 8 + } + }, "padding": { - "left": 8 + "left": 12, + "right": 12 }, "background": "#dfe2f1", - "corner_radius": 6, "hover": { "background": "#979db41f" }, diff --git a/crates/contacts_panel/src/contacts_panel.rs b/crates/contacts_panel/src/contacts_panel.rs index 4cc8091a77..9c8e4b1d12 100644 --- a/crates/contacts_panel/src/contacts_panel.rs +++ b/crates/contacts_panel/src/contacts_panel.rs @@ -186,6 +186,7 @@ impl ContactsPanel { .with_style(theme.contact_username.container) .aligned() .left() + .flex(1., true) .boxed(), ) .constrained() @@ -211,6 +212,13 @@ impl ContactsPanel { ) -> ElementBox { let project = &contact.projects[project_ix]; let project_id = project.id; + let is_host = Some(contact.user.id) == current_user_id; + let is_guest = !is_host + && project + .guests + .iter() + .any(|guest| Some(guest.id) == current_user_id); + let is_shared = project.is_shared; let font_cache = cx.font_cache(); let host_avatar_height = theme @@ -219,120 +227,103 @@ impl ContactsPanel { .or(theme.contact_avatar.height) .unwrap_or(0.); let row = &theme.unshared_project_row.default; + let tree_branch = theme.tree_branch.clone(); let line_height = row.name.text.line_height(font_cache); let cap_height = row.name.text.cap_height(font_cache); let baseline_offset = - row.name.text.baseline_offset(font_cache) + (row.height - line_height) / 2.; - let tree_branch_width = theme.tree_branch_width; - let tree_branch_color = theme.tree_branch_color; + row.name.text.baseline_offset(font_cache) + (theme.row_height - line_height) / 2.; - Flex::row() - .with_child( - Canvas::new(move |bounds, _, cx| { - let start_x = bounds.min_x() + (bounds.width() / 2.) - (tree_branch_width / 2.); - let end_x = bounds.max_x(); - let start_y = bounds.min_y(); - let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.); + MouseEventHandler::new::(project_id as usize, cx, |mouse_state, _| { + let tree_branch = *tree_branch.style_for(mouse_state, is_selected); + let row = if project.is_shared { + &theme.shared_project_row + } else { + &theme.unshared_project_row + } + .style_for(mouse_state, is_selected); - cx.scene.push_quad(gpui::Quad { - bounds: RectF::from_points( - vec2f(start_x, start_y), - vec2f( - start_x + tree_branch_width, - if is_last_project { - end_y - } else { - bounds.max_y() - }, + Flex::row() + .with_child( + Canvas::new(move |bounds, _, cx| { + let start_x = + bounds.min_x() + (bounds.width() / 2.) - (tree_branch.width / 2.); + let end_x = bounds.max_x(); + let start_y = bounds.min_y(); + let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.); + + cx.scene.push_quad(gpui::Quad { + bounds: RectF::from_points( + vec2f(start_x, start_y), + vec2f( + start_x + tree_branch.width, + if is_last_project { + end_y + } else { + bounds.max_y() + }, + ), ), - ), - background: Some(tree_branch_color), - border: gpui::Border::default(), - corner_radius: 0., - }); - cx.scene.push_quad(gpui::Quad { - bounds: RectF::from_points( - vec2f(start_x, end_y), - vec2f(end_x, end_y + tree_branch_width), - ), - background: Some(tree_branch_color), - border: gpui::Border::default(), - corner_radius: 0., - }); - }) - .constrained() - .with_width(host_avatar_height) - .boxed(), - ) - .with_child({ - let is_host = Some(contact.user.id) == current_user_id; - let is_guest = !is_host - && project - .guests - .iter() - .any(|guest| Some(guest.id) == current_user_id); - let is_shared = project.is_shared; - let app_state = app_state.clone(); - - MouseEventHandler::new::( - project_id as usize, - cx, - |mouse_state, _| { - let style = if project.is_shared { - &theme.shared_project_row - } else { - &theme.unshared_project_row - } - .style_for(mouse_state, is_selected); - Flex::row() - .with_child( - Label::new( - project.worktree_root_names.join(", "), - style.name.text.clone(), - ) - .aligned() - .left() - .contained() - .with_style(style.name.container) - .boxed(), - ) - .with_children(project.guests.iter().filter_map(|participant| { - participant.avatar.clone().map(|avatar| { - Image::new(avatar) - .with_style(style.guest_avatar) - .aligned() - .left() - .contained() - .with_margin_right(style.guest_avatar_spacing) - .boxed() - }) - })) - .contained() - .with_style(style.container) - .constrained() - .with_height(style.height) - .boxed() - }, - ) - .with_cursor_style(if !is_host && is_shared { - CursorStyle::PointingHand - } else { - CursorStyle::Arrow - }) - .on_click(move |_, cx| { - if !is_host && !is_guest { - cx.dispatch_global_action(JoinProject { - project_id, - app_state: app_state.clone(), + background: Some(tree_branch.color), + border: gpui::Border::default(), + corner_radius: 0., }); - } - }) - .flex(1., true) + cx.scene.push_quad(gpui::Quad { + bounds: RectF::from_points( + vec2f(start_x, end_y), + vec2f(end_x, end_y + tree_branch.width), + ), + background: Some(tree_branch.color), + border: gpui::Border::default(), + corner_radius: 0., + }); + }) + .constrained() + .with_width(host_avatar_height) + .boxed(), + ) + .with_child( + Label::new( + project.worktree_root_names.join(", "), + row.name.text.clone(), + ) + .aligned() + .left() + .contained() + .with_style(row.name.container) + .flex(1., false) + .boxed(), + ) + .with_children(project.guests.iter().filter_map(|participant| { + participant.avatar.clone().map(|avatar| { + Image::new(avatar) + .with_style(row.guest_avatar) + .aligned() + .left() + .contained() + .with_margin_right(row.guest_avatar_spacing) + .boxed() + }) + })) + .constrained() + .with_height(theme.row_height) + .contained() + .with_style(row.container) .boxed() - }) - .constrained() - .with_height(row.height) - .boxed() + }) + .with_cursor_style(if !is_host && is_shared { + CursorStyle::PointingHand + } else { + CursorStyle::Arrow + }) + .on_click(move |_, cx| { + if !is_host && !is_guest { + cx.dispatch_global_action(JoinProject { + project_id, + app_state: app_state.clone(), + }); + } + }) + .boxed() } fn render_contact_request( @@ -364,11 +355,13 @@ impl ContactsPanel { .with_style(theme.contact_username.container) .aligned() .left() + .flex(1., true) .boxed(), ); let user_id = user.id; let is_contact_request_pending = user_store.read(cx).is_contact_request_pending(&user); + let button_spacing = theme.contact_button_spacing; if is_incoming { row.add_children([ @@ -380,7 +373,7 @@ impl ContactsPanel { }; render_icon_button(button_style, "icons/reject.svg") .aligned() - .flex_float() + // .flex_float() .boxed() }) .with_cursor_style(CursorStyle::PointingHand) @@ -390,7 +383,9 @@ impl ContactsPanel { accept: false, }) }) - .flex_float() + // .flex_float() + .contained() + .with_margin_right(button_spacing) .boxed(), MouseEventHandler::new::(user.id as usize, cx, |mouse_state, _| { let button_style = if is_contact_request_pending { diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index c55fe0ae5f..92a8b2dba7 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -246,9 +246,15 @@ pub struct ContactsPanel { pub contact_avatar: ImageStyle, pub contact_username: ContainedText, pub contact_button: Interactive, + pub contact_button_spacing: f32, pub disabled_contact_button: IconButton, - pub tree_branch_width: f32, - pub tree_branch_color: Color, + pub tree_branch: Interactive, +} + +#[derive(Deserialize, Default, Clone, Copy)] +pub struct TreeBranch { + pub width: f32, + pub color: Color, } #[derive(Deserialize, Default)] @@ -273,8 +279,8 @@ pub struct IconButton { pub struct ProjectRow { #[serde(flatten)] pub container: ContainerStyle, - pub height: f32, pub name: ContainedText, + pub guests: ContainerStyle, pub guest_avatar: ImageStyle, pub guest_avatar_spacing: f32, } diff --git a/styles/src/styleTree/app.ts b/styles/src/styleTree/app.ts index 0da6ada222..8e5a12d9b8 100644 --- a/styles/src/styleTree/app.ts +++ b/styles/src/styleTree/app.ts @@ -12,7 +12,7 @@ import workspace from "./workspace"; import projectDiagnostics from "./projectDiagnostics"; export const panel = { - padding: { top: 12, left: 12, bottom: 12, right: 12 }, + padding: { top: 12, bottom: 12 }, }; export default function app(theme: Theme): Object { diff --git a/styles/src/styleTree/contactsPanel.ts b/styles/src/styleTree/contactsPanel.ts index 69c62b5c02..5135e8ba45 100644 --- a/styles/src/styleTree/contactsPanel.ts +++ b/styles/src/styleTree/contactsPanel.ts @@ -3,7 +3,10 @@ import { panel } from "./app"; import { backgroundColor, border, borderColor, iconColor, player, text } from "./components"; export default function contactsPanel(theme: Theme) { - const project = { + const nameMargin = 8; + const sidePadding = 12; + + const projectRow = { guestAvatarSpacing: 4, height: 24, guestAvatar: { @@ -13,11 +16,19 @@ export default function contactsPanel(theme: Theme) { name: { ...text(theme, "mono", "placeholder", { size: "sm" }), margin: { + left: nameMargin, right: 6, }, }, + guests: { + margin: { + left: nameMargin, + right: nameMargin, + } + }, padding: { - left: 8, + left: sidePadding, + right: sidePadding, }, }; @@ -44,41 +55,61 @@ export default function contactsPanel(theme: Theme) { right: 8, top: 4, }, + margin: { + left: sidePadding, + right: sidePadding, + } }, userQueryEditorHeight: 32, addContactButton: { - margin: { left: 6 }, + margin: { left: 6, right: 12 }, color: iconColor(theme, "primary"), buttonWidth: 8, iconWidth: 8, }, + rowHeight: 28, headerRow: { ...text(theme, "mono", "secondary", { size: "sm" }), - margin: { top: 8 }, + margin: { top: 14 }, + padding: { + left: sidePadding, + right: sidePadding, + }, active: { ...text(theme, "mono", "primary", { size: "sm" }), background: backgroundColor(theme, 100, "active"), } }, contactRow: { - padding: { left: 8 }, + padding: { + left: sidePadding, + right: sidePadding + }, active: { background: backgroundColor(theme, 100, "active"), } }, - rowHeight: 28, - treeBranchColor: borderColor(theme, "muted"), - treeBranchWidth: 1, + treeBranch: { + color: borderColor(theme, "active"), + width: 1, + hover: { + color: borderColor(theme, "active"), + }, + active: { + color: borderColor(theme, "active"), + } + }, contactAvatar: { cornerRadius: 10, width: 18, }, contactUsername: { ...text(theme, "mono", "primary", { size: "sm" }), - padding: { - left: 8, + margin: { + left: nameMargin, }, }, + contactButtonSpacing: nameMargin, contactButton: { ...contactButton, hover: { @@ -91,11 +122,10 @@ export default function contactsPanel(theme: Theme) { color: iconColor(theme, "muted"), }, sharedProjectRow: { - ...project, + ...projectRow, background: backgroundColor(theme, 300), - cornerRadius: 6, name: { - ...project.name, + ...projectRow.name, ...text(theme, "mono", "secondary", { size: "sm" }), }, hover: { @@ -106,11 +136,10 @@ export default function contactsPanel(theme: Theme) { } }, unsharedProjectRow: { - ...project, + ...projectRow, background: backgroundColor(theme, 300), - cornerRadius: 6, name: { - ...project.name, + ...projectRow.name, ...text(theme, "mono", "secondary", { size: "sm" }), }, hover: {