[IMP] devtools: icons and UI improvements

This commit adapts the layout of icons in the UI to be more intuitive
and also adds some feedback on hover on some elements for clarity. Also
fixes a bug where an object line could be toggled on select.
This commit is contained in:
Julien Carion (juca)
2023-10-04 14:44:19 +02:00
committed by Géry Debongnie
parent ff5ef82ea2
commit 035895b043
6 changed files with 55 additions and 18 deletions
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve"> <templates xml:space="preserve">
<t t-name="devtools.ComponentSearchBar" owl="1"> <t t-name="devtools.ComponentSearchBar" owl="1">
<div class="pointer-icon ms-1 px-2 py-1" t-on-click.stop='() => this.store.toggleSelector()'> <div class="mouse-icon p-1" t-on-click.stop='() => this.store.toggleSelector()'>
<i title="Select an element in the page to inspect the corresponding component" class="fa fa-mouse-pointer" t-attf-style="color: {{store.componentSearch.activeSelector ? 'var(--active-icon)' : 'var(--text-color)'}};"></i> <i title="Select an element in the page to inspect the corresponding component" class="fa fa-fw fa-mouse-pointer" t-attf-style="color: {{store.componentSearch.activeSelector ? 'var(--active-icon)' : 'var(--text-color)'}};"></i>
</div> </div>
<div class="icons-separator"/> <div class="icons-separator"/>
<div class="d-flex align-items-center ms-2 flex-grow-1"> <div class="d-flex align-items-center ms-2 flex-grow-1">
@@ -2,8 +2,8 @@
<templates xml:space="preserve"> <templates xml:space="preserve">
<t t-name="devtools.ObjectTreeElement" owl="1"> <t t-name="devtools.ObjectTreeElement" owl="1">
<div class="m-0 p-0 text-nowrap w-100 object-line" <div class="m-0 p-0 text-nowrap w-100 object-line"
t-att-class="props.class" t-att-class="props.class + (props.object.hasChildren ? ' bg-feedback' : '')"
t-on-click.stop="() => this.store.toggleObjectTreeElementsDisplay(this.props.object)" t-on-click.stop="() => this.store.toggleObjectTreeElementsDisplay(this.props.object)"
t-on-contextmenu.prevent="openMenu" t-on-contextmenu.prevent="openMenu"
> >
<div t-attf-style="padding-left: {{objectPadding}}rem"> <div t-attf-style="padding-left: {{objectPadding}}rem">
@@ -16,9 +16,9 @@
<option t-att-value="frame"><t t-esc="frame"/></option> <option t-att-value="frame"><t t-esc="frame"/></option>
</t> </t>
</select> </select>
<i class="ms-auto p-1 me-1 lg-icon fa fa-question-circle pointer-icon" title="Open devtools doc" t-on-click.stop="() => this.store.openDocumentation()"></i> <i class="ms-auto p-1 me-1 lg-icon fa fa-question-circle navbar-icon" title="Open devtools doc" t-on-click.stop="() => this.store.openDocumentation()"></i>
<i class="p-1 me-1 lg-icon fa pointer-icon" title="Toggle dark mode" t-att-class="{ 'fa-sun-o': store.settings.darkMode, 'fa-moon-o' : !store.settings.darkMode}" t-on-click.stop="() => this.store.toggleDarkMode()"></i> <i class="p-1 me-1 lg-icon fa navbar-icon" title="Toggle dark mode" t-att-class="{ 'fa-sun-o': store.settings.darkMode, 'fa-moon-o' : !store.settings.darkMode}" t-on-click.stop="() => this.store.toggleDarkMode()"></i>
<i class="p-1 me-1 lg-icon fa fa-repeat pointer-icon" title="Refresh extension" t-on-click.stop="() => this.store.refreshExtension()"></i> <i class="p-1 me-1 lg-icon fa fa-repeat navbar-icon" title="Refresh extension" t-on-click.stop="() => this.store.refreshExtension()"></i>
</div> </div>
<ComponentsTab t-if="store.page === 'ComponentsTab'"/> <ComponentsTab t-if="store.page === 'ComponentsTab'"/>
<ProfilerTab t-if="store.page === 'ProfilerTab'"/> <ProfilerTab t-if="store.page === 'ProfilerTab'"/>
@@ -3,20 +3,20 @@
<t t-name="devtools.ProfilerTab" owl="1"> <t t-name="devtools.ProfilerTab" owl="1">
<div class="position-relative overflow-hidden d-flex flex-column h-100"> <div class="position-relative overflow-hidden d-flex flex-column h-100">
<div class="panel-top d-flex align-items-center"> <div class="panel-top d-flex align-items-center">
<i title="Start/Stop Recording" class="fa fa-circle pointer-icon ms-1 p-1" t-attf-style="color: {{store.activeRecorder ? 'var(--active-recorder)' : 'var(--text-color)'}};" t-on-click.stop="() => this.store.toggleRecording()" aria-hidden="true"></i> <i title="Start/Stop Recording" class="fa fa-circle profiler-icon p-2" t-attf-style="color: {{store.activeRecorder ? 'var(--active-recorder)' : 'var(--text-color)'}};" t-on-click.stop="() => this.store.toggleRecording()" aria-hidden="true"></i>
<i title="Clear events" class="fa fa-ban pointer-icon p-1 px-2" t-on-click.stop="() => this.store.clearEventsConsole()" aria-hidden="true"></i> <i title="Clear events" class="fa fa-ban profiler-icon p-2" t-on-click.stop="() => this.store.clearEventsConsole()" aria-hidden="true"></i>
<div class="icons-separator mx-1"/> <div class="icons-separator"/>
<select class="form-select form-select-sm custom-select border-0" t-on-change="selectDisplayMode"> <select class="form-select form-select-sm custom-select pointer-icon border-0" t-on-change="selectDisplayMode">
<option t-att-selected="store.eventsTreeView" value="Tree">Tree view</option> <option t-att-selected="store.eventsTreeView" value="Tree">Tree view</option>
<option t-att-selected="!store.eventsTreeView" value="List">Events log</option> <option t-att-selected="!store.eventsTreeView" value="List">Events log</option>
</select> </select>
<i title="Collapse All" type="button" class="fa fa-list me-2" t-on-click="() => this.store.collapseAll()" t-attf-style="{{store.eventsTreeView ? '' : 'visibility: hidden;'}}"></i> <i title="Collapse All" class="fa fa-list p-2 profiler-icon" t-on-click="() => this.store.collapseAll()" t-attf-style="{{store.eventsTreeView ? '' : 'display: none;'}}"></i>
<div class="icons-separator"/> <div class="icons-separator"/>
<label class="mx-2 form-check-label pointer-icon" title="Trace renderings in console"> <label class="p-1 mx-1 form-check-label pointer-icon" title="Trace renderings in console">
<input type="checkbox" class="form-check-input me-1" t-att-checked="store.traceRenderings" t-on-input="() => this.store.toggleTracing()"/> Trace Renderings <input type="checkbox" class="form-check-input me-1 pointer-icon" t-att-checked="store.traceRenderings" t-on-input="() => this.store.toggleTracing()"/> Trace Renderings
</label> </label>
<label class="mx-2 form-check-label pointer-icon" title="Trace subscriptions in console (warning: it is VERY verbose)"> <label class="p-1 mx-1 form-check-label pointer-icon" title="Trace subscriptions in console (warning: it is VERY verbose)">
<input type="checkbox" class="form-check-input me-1" t-att-checked="store.traceSubscriptions" t-on-input="() => this.store.toggleSubscriptionTracing()"/> Trace Subscriptions <input type="checkbox" class="form-check-input me-1 pointer-icon" t-att-checked="store.traceSubscriptions" t-on-input="() => this.store.toggleSubscriptionTracing()"/> Trace Subscriptions
</label> </label>
<!-- <EventSearchBar/> --> <!-- <EventSearchBar/> -->
</div> </div>
@@ -350,7 +350,7 @@ export const store = reactive({
// Expand the children of the input object property and load it from page if necessary // Expand the children of the input object property and load it from page if necessary
async toggleObjectTreeElementsDisplay(obj) { async toggleObjectTreeElementsDisplay(obj) {
if (!obj.hasChildren) { if (!obj.hasChildren || window.getSelection().toString().length) {
return; return;
} }
// Since it is sometimes impossible (and always ineffective) to load all descendants of a property // Since it is sometimes impossible (and always ineffective) to load all descendants of a property
+38 -1
View File
@@ -26,6 +26,8 @@
--text-selected: white; --text-selected: white;
--menu-highlight-bg: rgb(201, 201, 201); --menu-highlight-bg: rgb(201, 201, 201);
--version-bg: teal; --version-bg: teal;
--hover-bg: #ebebeb;
--navbar-hover-bg: #d3d3d3;
/* to change the color here, put it in stroke='%23[color in hexadecimal]' */ /* to change the color here, put it in stroke='%23[color in hexadecimal]' */
--select-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23444444' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); --select-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23444444' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
} }
@@ -52,6 +54,8 @@
--text-selected: #c9c9c9; --text-selected: #c9c9c9;
--menu-highlight-bg: rgb(65, 65, 65); --menu-highlight-bg: rgb(65, 65, 65);
--version-bg: #805900ad; --version-bg: #805900ad;
--hover-bg: #575757;
--navbar-hover-bg: #6b6b6b;
color-scheme: dark; color-scheme: dark;
/* to change the color here, put it in stroke='%23[color in hexadecimal]' */ /* to change the color here, put it in stroke='%23[color in hexadecimal]' */
--select-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23c9c9c9' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); --select-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23c9c9c9' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
@@ -82,6 +86,10 @@
color: var(--text-color) !important; color: var(--text-color) !important;
} }
.form-check-label {
user-select: none;
}
.navbar-btn { .navbar-btn {
height: 23px; height: 23px;
padding: 0.5rem; padding: 0.5rem;
@@ -244,7 +252,7 @@
.search-input { .search-input {
background-color: var(--background-color); background-color: var(--background-color);
color: var(--text-color); color: var(--text-color);
padding: 0.4rem 0rem; padding: 0.37rem 0rem;
} }
.search-icon { .search-icon {
@@ -255,6 +263,35 @@
.utility-icon { .utility-icon {
cursor: pointer; cursor: pointer;
font-size: 1.2em; font-size: 1.2em;
border-radius: 35%;
}
.mouse-icon {
border-radius: 35%;
cursor: pointer;
padding-left: 0.4rem !important;
}
.profiler-icon {
border-radius: 35%;
cursor: pointer;
}
.utility-icon:hover, .mouse-icon:hover, .profiler-icon:hover, .bg-feedback:hover {
background-color: var(--hover-bg);
}
.navbar-icon {
border-radius: 35%;
cursor: pointer;
}
.navbar-icon:hover {
background-color: var(--navbar-hover-bg);
}
.bg-feedback {
border-radius: 5%;
} }
.lg-icon { .lg-icon {