You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by sh...@apache.org on 2023/04/04 16:20:32 UTC
[daffodil-vscode] branch main updated: Data Editor UI has togglable color mode.
This is an automated email from the ASF dual-hosted git repository.
shanedell pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-vscode.git
The following commit(s) were added to refs/heads/main by this push:
new 6af6ccb Data Editor UI has togglable color mode.
6af6ccb is described below
commit 6af6ccb82677fae733d99747f3e17a0103a41484
Author: Robert Strickland <st...@gmail.com>
AuthorDate: Tue Mar 28 12:23:00 2023 -0500
Data Editor UI has togglable color mode.
- UI color theme pulls from user selected VSCode color theme.
- Some UI components have locked theme background to ensure readability
across various themes.
Closes #536
---
src/omega_edit/dataEditWebView.ts | 3 +-
src/omega_edit/utils.ts | 19 +-
src/svelte/src/components/dataEditor.svelte | 1298 +++++++++++---------
src/svelte/src/stores/index.ts | 2 +
.../src/utilities/{message.ts => colorScheme.ts} | 48 +-
src/svelte/src/utilities/message.ts | 1 +
6 files changed, 744 insertions(+), 627 deletions(-)
diff --git a/src/omega_edit/dataEditWebView.ts b/src/omega_edit/dataEditWebView.ts
index 02347cd..f03033c 100644
--- a/src/omega_edit/dataEditWebView.ts
+++ b/src/omega_edit/dataEditWebView.ts
@@ -42,7 +42,7 @@ const HEARTBEAT_INTERVAL_MS = 1000 // 1 second (1000 ms)
export class DataEditWebView implements vscode.Disposable {
public panel: vscode.WebviewPanel
private svelteWebviewInitializer: SvelteWebviewInitializer
- private displayState = new DisplayState()
+ private displayState: DisplayState
private currentViewportId: string
private fileToEdit: string = ''
private omegaSessionId = ''
@@ -61,6 +61,7 @@ export class DataEditWebView implements vscode.Disposable {
this.svelteWebviewInitializer.initialize(this.view, this.panel.webview)
this.currentViewportId = ''
this.fileToEdit = fileToEdit
+ this.displayState = new DisplayState(this.panel)
}
async dispose(): Promise<void> {
diff --git a/src/omega_edit/utils.ts b/src/omega_edit/utils.ts
index ae66879..ed6521c 100644
--- a/src/omega_edit/utils.ts
+++ b/src/omega_edit/utils.ts
@@ -83,9 +83,26 @@ export async function viewportSubscribe(
export class DisplayState {
public bytesPerRow: number
public editorEncoding: BufferEncoding
- constructor() {
+ public colorThemeKind: vscode.ColorThemeKind
+ private panel: vscode.WebviewPanel
+
+ constructor(editorPanel: vscode.WebviewPanel) {
this.bytesPerRow = 16
this.editorEncoding = 'hex'
+ this.colorThemeKind = vscode.window.activeColorTheme.kind
+ this.panel = editorPanel
+
+ vscode.window.onDidChangeActiveColorTheme((event) => {
+ this.colorThemeKind = event.kind
+ this.sendUIThemeUpdate()
+ })
+ this.sendUIThemeUpdate()
+ }
+ private sendUIThemeUpdate() {
+ this.panel.webview.postMessage({
+ command: MessageCommand.setUITheme,
+ theme: this.colorThemeKind,
+ })
}
}
diff --git a/src/svelte/src/components/dataEditor.svelte b/src/svelte/src/components/dataEditor.svelte
index 006b137..fac7fa9 100644
--- a/src/svelte/src/components/dataEditor.svelte
+++ b/src/svelte/src/components/dataEditor.svelte
@@ -95,6 +95,11 @@ limitations under the License.
setSelectionOffsetInfo,
radixBytePad,
} from '../utilities/display'
+ import {
+ CSSThemeClass,
+ UIThemeCSSClass,
+ darkUITheme,
+ } from '../utilities/colorScheme'
import { vscode } from '../utilities/vscode'
import { MessageCommand } from '../utilities/message'
import { writable } from 'svelte/store'
@@ -175,6 +180,8 @@ limitations under the License.
}
$rawEditorSelectionTxt = $editorSelection
}
+ $: $UIThemeCSSClass = $darkUITheme ? CSSThemeClass.Dark : CSSThemeClass.Light
+
function clearOnEditModeChange(_: string) {
closeEphemeralWindows()
clearDataDisplays()
@@ -774,658 +781,713 @@ limitations under the License.
scrollSearchResults(false)
}
break
+ case MessageCommand.setUITheme:
+ $darkUITheme = msg.data.theme === 2
+ break
}
})
</script>
<svelte:window on:keydown|nonpassive={handleKeybind} />
-<header>
- <div class="header-container">
- <fieldset class="box file-metrics">
- <legend>File Metrics</legend>
- <div class="flex-container row wrap">
- <div class="row-item flex-container col">
- <label for="file_name" class="col-item file-metrics">Path</label>
- <div id="file_name" class="col-item file-name">{$fileName}</div>
- </div>
- </div>
- <hr />
- <div class="flex-container row" style="padding-top: 5pt;">
- <div class="two-row-items flex-container col">
- <label class="col-item file-metrics" for="disk_file_size"
- >Disk Size</label
- >
- <div class="col-item" id="disk_file_size">{$diskFileSize}</div>
- </div>
- <div class="two-row-item flex-container col">
- <label class="col-item file-metrics" for="computed_file_size"
- >Computed Size</label
- >
- <div class="col-item" id="computed_file_size">
- {$computedFileSize}
+<body class={$UIThemeCSSClass}>
+ <header>
+ <div class="header-container">
+ <fieldset class="box file-metrics">
+ <legend>File Metrics</legend>
+ <div class="flex-container row wrap">
+ <div class="row-item flex-container col">
+ <label for="file_name" class="col-item file-metrics">Path</label>
+ <div id="file_name" class="col-item file-name">{$fileName}</div>
</div>
</div>
- </div>
- <hr />
- <div>
- {#if $saveable}
- <button on:click={saveToDisk}>Save</button>
- {:else}
- <button disabled>Save</button>
- {/if}
- </div>
- </fieldset>
- <fieldset class="box search-replace">
- <legend>Search</legend>
- <div class="flex-container col">
- <div class="col-item">
- Search:
- {#if $searchData.length > 0 && !$searchable}
- <span class="errMsg">{$searchErrMsg}</span>
- {/if}
- <input bind:value={$searchData} />
- </div>
- {#if $allowCaseInsensitiveSearch}
- <div class="case col-item flex-container row center">
- <label for="search_case_insensitive" class="row-item search-case"
- >Case Insensitive:</label
+ <hr />
+ <div class="flex-container row" style="padding-top: 5pt;">
+ <div class="two-row-items flex-container col">
+ <label class="col-item file-metrics" for="disk_file_size"
+ >Disk Size</label
>
- <input
- type="checkbox"
- id="search_case_insensitive"
- class="row-item search-case"
- bind:checked={$searchCaseInsensitive}
- />
+ <div class="col-item" id="disk_file_size">{$diskFileSize}</div>
</div>
- {/if}
- <div class="col-item">
- Replace:
- {#if $replaceData.length > 0 && !$replaceable}
- <span class="errMsg">{$replaceErrMsg}</span>
- {/if}
- <input bind:value={$replaceData} />
- </div>
- <div class="col-item flex-container row center">
- {#if !$searchable}
- <button id="search_btn" disabled>Search</button>
- {:else}
- <button id="search_btn" on:click={search}>Search</button>
- {/if}
- {#if !$replaceable}
- <button id="replace_btn" disabled>Replace</button>
- {:else}
- <button id="replace_btn" on:click={searchAndReplace}>Replace</button
+ <div class="two-row-item flex-container col">
+ <label class="col-item file-metrics" for="computed_file_size"
+ >Computed Size</label
>
- {/if}
- {#if $searching || $replacing}
- <svg class="loader sm" viewBox="0 0 50 50">
- <circle cx="25" cy="25" r="20" />
- </svg>
- {/if}
+ <div class="col-item" id="computed_file_size">
+ {$computedFileSize}
+ </div>
+ </div>
</div>
- <div class="col-item flex-container row center">
- {#if $searchResults.length > 0}
- <button id="search_next" on:click={scrollSearchNext}>Next</button>
- <button id="search_prev" on:click={scrollSearchPrev}>Prev</button>
- <sub>{$searchIndex + 1} / {$searchResults.length} Results </sub>
- {:else if $replacementsCount > 0}
- <sub>{$replacementsCount} Replacements</sub>
+ <hr />
+ <div>
+ {#if $saveable}
+ <button class={$UIThemeCSSClass} on:click={saveToDisk}>Save</button>
+ {:else}
+ <button class={$UIThemeCSSClass} disabled>Save</button>
{/if}
</div>
- </div>
- </fieldset>
- <fieldset class="box">
- <legend>Settings</legend>
- <div class="flex-container col">
- <div class="col-item flex-container row center">
- <div class="two-row-items">
- <label for="edit_mode">Byte Edit Mode:</label>
+ </fieldset>
+ <fieldset class="box search-replace">
+ <legend>Search</legend>
+ <div class="flex-container col">
+ <div class="col-item">
+ Search:
+ {#if $searchData.length > 0 && !$searchable}
+ <span class="errMsg">{$searchErrMsg}</span>
+ {/if}
+ <input class={$UIThemeCSSClass} bind:value={$searchData} />
</div>
- <div class="two-row-items">
- <select
- id="edit_mode"
- class="row-item"
- bind:value={$editMode}
- on:change={closeEphemeralWindows}
- >
- <option value="simple">Single</option>
- <option value="full">Multiple</option>
- </select>
+ {#if $allowCaseInsensitiveSearch}
+ <div class="case col-item flex-container row center">
+ <label for="search_case_insensitive" class="row-item search-case"
+ >Case Insensitive:</label
+ >
+ <input
+ type="checkbox"
+ id="search_case_insensitive"
+ class={$UIThemeCSSClass + ' row-item search-case'}
+ bind:checked={$searchCaseInsensitive}
+ />
+ </div>
+ {/if}
+ <div class="col-item">
+ Replace:
+ {#if $replaceData.length > 0 && !$replaceable}
+ <span class="errMsg">{$replaceErrMsg}</span>
+ {/if}
+ <input class={$UIThemeCSSClass} bind:value={$replaceData} />
</div>
- </div>
- <div class="col-item flex-container row center">
- <div class="two-row-items">
- <label for="radix">Byte Display Radix: </label>
+ <div class="col-item flex-container row center">
+ {#if !$searchable}
+ <button class={$UIThemeCSSClass} id="search_btn" disabled
+ >Search</button
+ >
+ {:else}
+ <button class={$UIThemeCSSClass} id="search_btn" on:click={search}
+ >Search</button
+ >
+ {/if}
+ {#if !$replaceable}
+ <button class={$UIThemeCSSClass} id="replace_btn" disabled
+ >Replace</button
+ >
+ {:else}
+ <button
+ class={$UIThemeCSSClass}
+ id="replace_btn"
+ on:click={searchAndReplace}>Replace</button
+ >
+ {/if}
+ {#if $searching || $replacing}
+ <svg class="loader sm" viewBox="0 0 50 50">
+ <circle cx="25" cy="25" r="20" />
+ </svg>
+ {/if}
</div>
- <div class="two-row-items">
- <select
- id="radix"
- class="row-item"
- bind:value={$displayRadix}
- on:change={closeEphemeralWindows}
- >
- {#each radixOpt as { name, value }}
- <option {value}>{name}</option>
- {/each}
- </select>
+ <div class="col-item flex-container row center">
+ {#if $searchResults.length > 0}
+ <button
+ class={$UIThemeCSSClass}
+ id="search_next"
+ on:click={scrollSearchNext}>Next</button
+ >
+ <button
+ class={$UIThemeCSSClass}
+ id="search_prev"
+ on:click={scrollSearchPrev}>Prev</button
+ >
+ <sub>{$searchIndex + 1} / {$searchResults.length} Results </sub>
+ {:else if $replacementsCount > 0}
+ <sub>{$replacementsCount} Replacements</sub>
+ {/if}
</div>
</div>
- <div class="col-item flex-container row center">
- <div class="two-row-items">
- <label for="radix" class="row-item">Edit Encoding: </label>
+ </fieldset>
+ <fieldset class="box">
+ <legend>Settings</legend>
+ <div class="flex-container col">
+ <div class="col-item flex-container row center">
+ <div class="two-row-items">
+ <label for="edit_mode">Byte Edit Mode:</label>
+ </div>
+ <div class="two-row-items">
+ <select
+ id="edit_mode"
+ class={$UIThemeCSSClass + ' row-item'}
+ bind:value={$editMode}
+ on:change={closeEphemeralWindows}
+ >
+ <option value="simple">Single</option>
+ <option value="full">Multiple</option>
+ </select>
+ </div>
</div>
- <div class="two-row-items">
- <select
- class="row-item"
- id="edit_encoding"
- bind:value={$editorEncoding}
- >
- {#each encoding_groups as { group, encodings }}
- <optgroup label={group}>
- {#each encodings as { name, value }}
- <option {value}>{name}</option>
- {/each}
- </optgroup>
- {/each}
- </select>
+ <div class="col-item flex-container row center">
+ <div class="two-row-items">
+ <label for="radix">Byte Display Radix: </label>
+ </div>
+ <div class="two-row-items">
+ <select
+ id="radix"
+ class={$UIThemeCSSClass + ' row-item'}
+ bind:value={$displayRadix}
+ on:change={closeEphemeralWindows}
+ >
+ {#each radixOpt as { name, value }}
+ <option {value}>{name}</option>
+ {/each}
+ </select>
+ </div>
</div>
- </div>
- <hr />
- <div class="col-item flex-container row center">
- <div class="two-row-items">Offset:</div>
- <div class="two-row-items">
- <input
- class="row-item"
- type="text"
- id="goto_offset"
- bind:value={$gotoOffsetInput}
- />
+ <div class="col-item flex-container row center">
+ <div class="two-row-items">
+ <label for="radix" class="row-item">Edit Encoding: </label>
+ </div>
+ <div class="two-row-items">
+ <select
+ class={$UIThemeCSSClass + ' row-item'}
+ id="edit_encoding"
+ bind:value={$editorEncoding}
+ >
+ {#each encoding_groups as { group, encodings }}
+ <optgroup label={group}>
+ {#each encodings as { name, value }}
+ <option {value}>{name}</option>
+ {/each}
+ </optgroup>
+ {/each}
+ </select>
+ </div>
</div>
- </div>
- <div
- class="col-item flex-container row center"
- style="justify-content: flex-end;"
- >
- <div
- class="two-row-items row-item"
- style="font-size: 9pt; text-align: right;"
- >
- {#if !$gotoable.valid}
- {$gotoable.gotoErrMsg}
- {:else if isScrolledToTop}
- Top
- {:else if isScrolledToEnd}
- End
- {/if}
+ <hr />
+ <div class="col-item flex-container row center">
+ <div class="two-row-items">Offset:</div>
+ <div class="two-row-items">
+ <input
+ class={$UIThemeCSSClass + ' row-item'}
+ type="text"
+ id="goto_offset"
+ bind:value={$gotoOffsetInput}
+ />
+ </div>
</div>
</div>
+ </fieldset>
+ </div>
+ {#if $headerHidden}
+ <div class="display-icons flex-container row center">
+ <div>{$fileName}</div>
+ <button
+ class={$UIThemeCSSClass + ' minmax-icon'}
+ on:click={elementMinMax}>⇳</button
+ >
</div>
- </fieldset>
- </div>
- {#if $headerHidden}
- <div
- class="display-icons flex-container row center"
- style="width: 100%;justify-content: space-between;"
- >
- <div>{$fileName}</div>
- <button class="minmax-icon" on:click={elementMinMax}>⇳</button>
+ {:else}
+ <div class="display-icons">
+ <button
+ class={$UIThemeCSSClass + ' minmax-icon'}
+ on:click={elementMinMax}>⇳</button
+ >
+ </div>
+ {/if}
+ </header>
+
+ <main class="dataEditor" id="data_editor">
+ <div class={$UIThemeCSSClass + ' hd'}>Address</div>
+ <div class={$UIThemeCSSClass + ' hd'}>Physical</div>
+ <div class={$UIThemeCSSClass + ' hd'}>Logical</div>
+ <div class={$UIThemeCSSClass + ' hd'}>Edit</div>
+ <div class={$UIThemeCSSClass + ' measure'} style="align-items: center;">
+ <select
+ class={$UIThemeCSSClass + ' address_type'}
+ id="address_numbering"
+ on:change={updateAddressValue}
+ >
+ {#each addressOpt as { name, value }}
+ <option {value}>{name}</option>
+ {/each}
+ </select>
</div>
- {:else}
- <div class="display-icons">
- <button class="minmax-icon" on:click={elementMinMax}>⇳</button>
+ <div class={$UIThemeCSSClass + ' measure'}>
+ <span id="physical_offsets">
+ {@html physicalOffsetText}
+ </span>
</div>
- {/if}
-</header>
-
-<main class="dataEditor" id="data_editor">
- <div class="hd">Address</div>
- <div class="hd">Physical</div>
- <div class="hd">Logical</div>
- <div class="hd">Edit</div>
- <div class="measure" style="align-items: center;">
- <select
- class="address_type"
- id="address_numbering"
- on:change={updateAddressValue}
- >
- {#each addressOpt as { name, value }}
- <option {value}>{name}</option>
- {/each}
- </select>
- </div>
- <div class="measure">
- <span id="physical_offsets">
- {@html physicalOffsetText}
- </span>
- </div>
- <div class="measure">
- <span id="logical_offsets">
- {@html logicalOffsetText}
- </span>
- </div>
- <div class="measure selection">
- {#if $editMode === 'full'}
- {#if $selectionActive}
- <div
- class="clear-selection"
- title="Clear selection data"
- on:click={clearDataDisplays}
- on:keypress={clearDataDisplays}
- >
- ✖
- </div>
- <!-- on:keypress is needed to silence warning from Svelte A11y, see below
+ <div class={$UIThemeCSSClass + ' measure'}>
+ <span id="logical_offsets">
+ {@html logicalOffsetText}
+ </span>
+ </div>
+ <div class={$UIThemeCSSClass + ' measure selection'}>
+ {#if $editMode === 'full'}
+ {#if $selectionActive}
+ <div
+ class="clear-selection"
+ title="Clear selection data"
+ on:click={clearDataDisplays}
+ on:keypress={clearDataDisplays}
+ >
+ ✖
+ </div>
+ <!-- on:keypress is needed to silence warning from Svelte A11y, see below
== (!) Plugin svelte: A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event. ==
-->
+ {:else}
+ <div class="clear-selection" />
+ {/if}
+ <div>
+ {selectionOffsetText}{#if $cursorPos} | cursor: {$cursorPos} {/if}
+ </div>
{:else}
- <div class="clear-selection" />
+ <div>
+ <sub
+ ><i
+ >The pop-up, single byte, edit window is available upon byte
+ selection, press ESC to close.<br />The edit window below is
+ deactivated in single byte edit mode.</i
+ ></sub
+ >
+ </div>
{/if}
- <div>
- {selectionOffsetText}{#if $cursorPos} | cursor: {$cursorPos} {/if}
- </div>
- {:else}
- <div>
- <sub
- ><i
- >The pop-up, single byte, edit window is available upon byte
- selection, press ESC to close.<br />The edit window below is
- deactivated in single byte edit mode.</i
- ></sub
- >
+ </div>
+ <div
+ class="flex-container col edit-byte-window ephemeral"
+ id="editByteWindow"
+ bind:this={$editByteWindow}
+ >
+ <div class="flex-container row col-item">
+ <input
+ title="byte position {$selectionStartOffset.toString(
+ $addressValue
+ )} {radixToString($addressValue)}"
+ type="text"
+ id="editByteInput"
+ class={$UIThemeCSSClass}
+ bind:value={$editorSelection}
+ on:input={handleEditorEvent}
+ />
+ {#if $commitable}
+ <button
+ title="insert byte before this location"
+ id="insert-before"
+ class="insert"
+ on:click={commitChanges}>⇤</button
+ >
+ <button
+ title="replace byte at this location"
+ id="insert-replace"
+ class="submit"
+ on:click={commitChanges}>⇅</button
+ >
+ <button
+ title="insert byte after this location"
+ id="insert-after"
+ class="insert"
+ on:click={commitChanges}>⇥</button
+ >
+ <button
+ title="delete this byte"
+ id="insert-delete"
+ class="delete"
+ on:click={commitChanges}>✖</button
+ >
+ {:else if $editedByteIsOriginalByte}
+ <button
+ title="insert byte before this location"
+ id="insert-before"
+ class="insert"
+ on:click={commitChanges}>⇤</button
+ >
+ <button class="submit" disabled>⇅</button>
+ <button
+ title="insert byte after this location"
+ id="insert-after"
+ class="insert"
+ on:click={commitChanges}>⇥</button
+ >
+ <button
+ title="delete this byte"
+ id="insert-delete"
+ class="delete"
+ on:click={commitChanges}>✖</button
+ >
+ {:else}
+ <button
+ title="delete this byte"
+ id="insert-delete"
+ class="delete"
+ on:click={commitChanges}>✖</button
+ >
+ <button class="insert" disabled>⇤</button>
+ <button class="submit" disabled>⇅</button>
+ <button class="insert" disabled>⇥</button>
+ {/if}
</div>
- {/if}
- </div>
- <div
- class="flex-container col edit-byte-window ephemeral"
- id="editByteWindow"
- bind:this={$editByteWindow}
- >
- <div class="flex-container row col-item">
- <input
- title="byte position {$selectionStartOffset.toString(
- $addressValue
- )} {radixToString($addressValue)}"
- type="text"
- id="editByteInput"
- bind:value={$editorSelection}
- on:input={handleEditorEvent}
- />
- {#if $commitable}
- <button
- title="insert byte before this location"
- id="insert-before"
- class="insert"
- on:click={commitChanges}>⇤</button
- >
- <button
- title="replace byte at this location"
- id="insert-replace"
- class="submit"
- on:click={commitChanges}>⇅</button
- >
- <button
- title="insert byte after this location"
- id="insert-after"
- class="insert"
- on:click={commitChanges}>⇥</button
- >
- <button
- title="delete this byte"
- id="insert-delete"
- class="delete"
- on:click={commitChanges}>✖</button
- >
- {:else if $editedByteIsOriginalByte}
- <button
- title="insert byte before this location"
- id="insert-before"
- class="insert"
- on:click={commitChanges}>⇤</button
- >
- <button class="submit" disabled>⇅</button>
- <button
- title="insert byte after this location"
- id="insert-after"
- class="insert"
- on:click={commitChanges}>⇥</button
- >
+ {#if $focusedViewportId === 'physical'}
<button
- title="delete this byte"
- id="insert-delete"
- class="delete"
- on:click={commitChanges}>✖</button
+ class={$UIThemeCSSClass +
+ ' flex-container row col-item switch-viewport'}
+ title="Show in Logical View"
+ on:click={moveEditByteWindow}>⇉</button
>
{:else}
<button
- title="delete this byte"
- id="insert-delete"
- class="delete"
- on:click={commitChanges}>✖</button
+ class={$UIThemeCSSClass +
+ ' flex-container row col-item switch-viewport'}
+ title="Show in Physical View"
+ on:click={moveEditByteWindow}>⇇</button
>
- <button class="insert" disabled>⇤</button>
- <button class="submit" disabled>⇅</button>
- <button class="insert" disabled>⇥</button>
+ {/if}
+ {#if !$commitable && $commitErrMsg.length > 0}
+ <div
+ style="background-color: black; opacity: 0.75; border-radius: 5px; margin: 4px; padding: 4px;"
+ >
+ <span class="errMsg">{$commitErrMsg}</span>
+ </div>
{/if}
</div>
- {#if $focusedViewportId === 'physical'}
- <button
- class="flex-container row col-item switch-viewport"
- title="Show in Logical View"
- on:click={moveEditByteWindow}>⇉</button
- >
- {:else}
- <button
- class="flex-container row col-item switch-viewport"
- title="Show in Physical View"
- on:click={moveEditByteWindow}>⇇</button
- >
- {/if}
- {#if !$commitable && $commitErrMsg.length > 0}
- <div
- style="background-color: black; opacity: 0.75; border-radius: 5px; margin: 4px; padding: 4px;"
- >
- <span class="errMsg">{$commitErrMsg}</span>
- </div>
- {/if}
- </div>
- <textarea
- class="address_vw"
- id="address"
- contenteditable="true"
- readonly
- bind:this={address_vwRef}
- bind:innerHTML={addressText}
- on:scroll={scrollHandle}
- />
- {#if $editMode === 'simple'}
<textarea
- class="physical_vw"
- id="physical"
+ class={$UIThemeCSSClass + ' address_vw'}
+ id="address"
contenteditable="true"
readonly
- bind:this={physical_vwRef}
- bind:innerHTML={physicalDisplayText}
+ bind:this={address_vwRef}
+ bind:innerHTML={addressText}
on:scroll={scrollHandle}
- on:click={handleViewportClickEvent}
/>
- <textarea
- class="logicalView"
- id="logical"
- contenteditable="true"
- readonly
- bind:this={logical_vwRef}
- bind:innerHTML={logicalDisplayText}
- on:scroll={scrollHandle}
- on:click={handleViewportClickEvent}
- />
- {:else}
- <textarea
- class="physical_vw"
- id="physical"
- contenteditable="true"
- readonly
- bind:this={physical_vwRef}
- bind:innerHTML={physicalDisplayText}
- on:select={handleSelectionEvent}
- on:scroll={scrollHandle}
- />
- <textarea
- class="logicalView"
- id="logical"
- contenteditable="true"
- readonly
- bind:this={logical_vwRef}
- bind:innerHTML={logicalDisplayText}
- on:select={handleSelectionEvent}
- on:scroll={scrollHandle}
- />
- {/if}
- <div class="editView" id="edit_view">
- {#if $editMode === 'full'}
+ {#if $editMode === 'simple'}
+ <textarea
+ class={$UIThemeCSSClass}
+ id="physical"
+ contenteditable="true"
+ readonly
+ bind:this={physical_vwRef}
+ bind:innerHTML={physicalDisplayText}
+ on:scroll={scrollHandle}
+ on:click={handleViewportClickEvent}
+ />
<textarea
- class="selectedContent"
- id="selectedContent"
+ class={$UIThemeCSSClass}
+ id="logical"
contenteditable="true"
- bind:value={$editorSelection}
- on:keyup|nonpassive={handleEditorEvent}
- on:click={handleEditorEvent}
- on:input={handleEditorEvent}
+ readonly
+ bind:this={logical_vwRef}
+ bind:innerHTML={logicalDisplayText}
+ on:scroll={scrollHandle}
+ on:click={handleViewportClickEvent}
/>
{:else}
- <textarea class="selectedContent" id="selectedContent" disabled />
+ <textarea
+ class={$UIThemeCSSClass}
+ id="physical"
+ contenteditable="true"
+ readonly
+ bind:this={physical_vwRef}
+ bind:innerHTML={physicalDisplayText}
+ on:select={handleSelectionEvent}
+ on:scroll={scrollHandle}
+ />
+ <textarea
+ class={$UIThemeCSSClass}
+ id="logical"
+ contenteditable="true"
+ readonly
+ bind:this={logical_vwRef}
+ bind:innerHTML={logicalDisplayText}
+ on:select={handleSelectionEvent}
+ on:scroll={scrollHandle}
+ />
{/if}
- <!-- Full Mode Content Controls -->
- {#if $editMode === 'full'}
- <fieldset class="box margin-top">
- <legend
- >Content Controls
- {#if !$commitable}
- <span class="errMsg">{$commitErrMsg}</span>
- {/if}
- </legend>
- <div class="contentControls" id="content_controls">
- <!-- Commitable was not reactable to selection data zeroing -->
- {#if $commitable}
- <button id="commit_btn" on:click={commitChanges}>Commit</button>
- {:else}
- <button id="commit_btn" disabled>Commit</button>
- {/if}
- <span>
- {#if $undoCount > 0}
- <button on:click={redo}>Redo ({$undoCount})</button>
- {:else}
- <button disabled>Redo</button>
- {/if}
- {#if $changeCount > 0}
- <button on:click={undo}>Undo ({$changeCount})</button>
- {:else}
- <button disabled>Undo</button>
+ <div class="editView" id="edit_view">
+ {#if $editMode === 'full'}
+ <textarea
+ class={$UIThemeCSSClass}
+ id="selectedContent"
+ contenteditable="true"
+ bind:value={$editorSelection}
+ on:keyup|nonpassive={handleEditorEvent}
+ on:click={handleEditorEvent}
+ on:input={handleEditorEvent}
+ />
+ {:else}
+ <textarea class={$UIThemeCSSClass} id="selectedContent" disabled />
+ {/if}
+ <!-- Full Mode Content Controls -->
+ {#if $editMode === 'full'}
+ <fieldset class="box margin-top">
+ <legend
+ >Content Controls
+ {#if !$commitable}
+ <span class="errMsg">{$commitErrMsg}</span>
{/if}
- {#if $undoCount + $changeCount > 0}
- <button on:click={clearChangeStack}>Revert All</button>
+ </legend>
+ <div class="contentControls" id="content_controls">
+ <!-- Commitable was not reactable to selection data zeroing -->
+ {#if $commitable}
+ <button
+ class={$UIThemeCSSClass}
+ id="commit_btn"
+ on:click={commitChanges}>Commit</button
+ >
{:else}
- <button disabled>Revert All</button>
+ <button class={$UIThemeCSSClass} id="commit_btn" disabled
+ >Commit</button
+ >
{/if}
- </span>
- </div>
- </fieldset>
- <fieldset class="box margin-top">
- <legend>Data View</legend>
- <div class="flex-container col">
- <div class="flex-container col-item center row">
- <div class="flex-container row center row-item">
- <label for="endianness">Endianness: </label>
- <select id="endianness" bind:value={$dataViewEndianness}>
- {#each endiannessOpt as { name, value }}
- <option {value}>{name}</option>
- {/each}
- </select>
- </div>
- </div>
- <div class="flex-container col-item center row">
- <div class="grid-container-column">
- <div id="data_vw">
- <label for="offset_dv"
- > Offset: <text-field
- id="offset_dv"
- />{$dataViewOffsetText}</label
+ <span>
+ {#if $undoCount > 0}
+ <button class={$UIThemeCSSClass} on:click={redo}
+ >Redo ({$undoCount})</button
>
- <span id="b8_dv">
- <br /><label for="int8_dv"
- > int8: <text-field
- id="int8_dv"
- />{$int8}</label
- >
- <br /><label for="uint8_dv"
- > uint8: <text-field
- id="uint8_dv"
- />{$uint8}</label
- >
- </span>
- <span id="b16_dv">
- <br /><label for="int16_dv"
- > int16: <text-field
- id="int16_dv"
- />{$int16}</label
- >
- <br /><label for="uint16_dv"
- > uint16: <text-field id="uint16_dv" />{$uint16}</label
- >
- </span>
- <span id="b32_dv">
- <br /><label for="int32_dv"
- > int32: <text-field
- id="int32_dv"
- />{$int32}</label
- >
- <br /><label for="uint32_dv"
- > uint32: <text-field id="uint32_dv" />{$uint32}</label
- >
- <br /><label for="float32_dv"
- >float32: <text-field id="float32_dv" />{$float32}</label
- >
- </span>
- <span id="b64_dv">
- <br /><label for="int64_dv"
- > int64: <text-field
- id="int64_dv"
- />{$int64}</label
- >
- <br /><label for="uint64_dv"
- > uint64: <text-field id="uint64_dv" />{$uint64}</label
- >
- <br /><label for="float64_dv"
- >float64: <text-field id="float64_dv" />{$float64}</label
- >
- </span>
- </div>
- </div>
+ {:else}
+ <button class={$UIThemeCSSClass} disabled>Redo</button>
+ {/if}
+ {#if $changeCount > 0}
+ <button class={$UIThemeCSSClass} on:click={undo}
+ >Undo ({$changeCount})</button
+ >
+ {:else}
+ <button class={$UIThemeCSSClass} disabled>Undo</button>
+ {/if}
+ {#if $undoCount + $changeCount > 0}
+ <button class={$UIThemeCSSClass} on:click={clearChangeStack}
+ >Revert All</button
+ >
+ {:else}
+ <button class={$UIThemeCSSClass} disabled>Revert All</button>
+ {/if}
+ </span>
</div>
- </div>
- </fieldset>
- <!-- Simple Mode Content Controls -->
- {:else}
- <fieldset class="box margin-top">
- <legend>Content Controls </legend>
- <div class="contentControls" id="content_controls">
- <span>
- {#if $undoCount > 0}
- <button on:click={redo}>Redo ({$undoCount})</button>
- {:else}
- <button disabled>Redo</button>
- {/if}
- {#if $changeCount > 0}
- <button on:click={undo}>Undo ({$changeCount})</button>
- {:else}
- <button disabled>Undo</button>
- {/if}
- {#if $undoCount + $changeCount > 0}
- <button on:click={clearChangeStack}>Revert All</button>
- {:else}
- <button disabled>Revert All</button>
- {/if}
- </span>
- </div>
- </fieldset>
- <fieldset class="box margin-top">
- <legend>Data View</legend>
-
- <div class="grid-container-single-column">
- <div class="grid-container-column">
+ </fieldset>
+ <fieldset class="box margin-top">
+ <legend>Data View</legend>
+ <div class="flex-container col">
<div class="flex-container col-item center row">
<div class="flex-container row center row-item">
<label for="endianness">Endianness: </label>
- <select id="endianness" bind:value={$dataViewEndianness}>
+ <select
+ id="endianness"
+ class={$UIThemeCSSClass}
+ bind:value={$dataViewEndianness}
+ >
{#each endiannessOpt as { name, value }}
<option {value}>{name}</option>
{/each}
</select>
</div>
</div>
- <div class="grid-container-column">
- <div id="data_vw">
- <label for="offset_dv"
- > Offset: <text-field
- id="offset_dv"
- />{$dataViewOffsetText}</label
- >
- <span id="b8_dv">
- <br /><label for="int8_dv"
- > int8: <text-field
- id="int8_dv"
- />{$int8}</label
- >
- <br /><label for="uint8_dv"
- > uint8: <text-field
- id="uint8_dv"
- />{$uint8}</label
- >
- </span>
- <span id="b16_dv">
- <br /><label for="int16_dv"
- > int16: <text-field
- id="int16_dv"
- />{$int16}</label
- >
- <br /><label for="uint16_dv"
- > uint16: <text-field id="uint16_dv" />{$uint16}</label
- >
- </span>
- <span id="b32_dv">
- <br /><label for="int32_dv"
- > int32: <text-field
- id="int32_dv"
- />{$int32}</label
- >
- <br /><label for="uint32_dv"
- > uint32: <text-field id="uint32_dv" />{$uint32}</label
- >
- <br /><label for="float32_dv"
- >float32: <text-field id="float32_dv" />{$float32}</label
- >
- </span>
- <span id="b64_dv">
- <br /><label for="int64_dv"
- > int64: <text-field
- id="int64_dv"
- />{$int64}</label
+ <div class="flex-container col-item center row">
+ <div class="grid-container-column">
+ <div id="data_vw">
+ <label for="offset_dv"
+ > Offset: <text-field
+ id="offset_dv"
+ />{$dataViewOffsetText}</label
>
- <br /><label for="uint64_dv"
- > uint64: <text-field id="uint64_dv" />{$uint64}</label
+ <span id="b8_dv">
+ <br /><label for="int8_dv"
+ > int8: <text-field
+ id="int8_dv"
+ />{$int8}</label
+ >
+ <br /><label for="uint8_dv"
+ > uint8: <text-field
+ id="uint8_dv"
+ />{$uint8}</label
+ >
+ </span>
+ <span id="b16_dv">
+ <br /><label for="int16_dv"
+ > int16: <text-field
+ id="int16_dv"
+ />{$int16}</label
+ >
+ <br /><label for="uint16_dv"
+ > uint16: <text-field
+ id="uint16_dv"
+ />{$uint16}</label
+ >
+ </span>
+ <span id="b32_dv">
+ <br /><label for="int32_dv"
+ > int32: <text-field
+ id="int32_dv"
+ />{$int32}</label
+ >
+ <br /><label for="uint32_dv"
+ > uint32: <text-field
+ id="uint32_dv"
+ />{$uint32}</label
+ >
+ <br /><label for="float32_dv"
+ >float32: <text-field id="float32_dv" />{$float32}</label
+ >
+ </span>
+ <span id="b64_dv">
+ <br /><label for="int64_dv"
+ > int64: <text-field
+ id="int64_dv"
+ />{$int64}</label
+ >
+ <br /><label for="uint64_dv"
+ > uint64: <text-field
+ id="uint64_dv"
+ />{$uint64}</label
+ >
+ <br /><label for="float64_dv"
+ >float64: <text-field id="float64_dv" />{$float64}</label
+ >
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+ <!-- Simple Mode Content Controls -->
+ {:else}
+ <fieldset class="box margin-top">
+ <legend>Content Controls </legend>
+ <div class="contentControls" id="content_controls">
+ <span>
+ {#if $undoCount > 0}
+ <button class={$UIThemeCSSClass} on:click={redo}
+ >Redo ({$undoCount})</button
+ >
+ {:else}
+ <button class={$UIThemeCSSClass} disabled>Redo</button>
+ {/if}
+ {#if $changeCount > 0}
+ <button class={$UIThemeCSSClass} on:click={undo}
+ >Undo ({$changeCount})</button
+ >
+ {:else}
+ <button class={$UIThemeCSSClass} disabled>Undo</button>
+ {/if}
+ {#if $undoCount + $changeCount > 0}
+ <button class={$UIThemeCSSClass} on:click={clearChangeStack}
+ >Revert All</button
+ >
+ {:else}
+ <button class={$UIThemeCSSClass} disabled>Revert All</button>
+ {/if}
+ </span>
+ </div>
+ </fieldset>
+ <fieldset class="box margin-top">
+ <legend>Data View</legend>
+
+ <div class="grid-container-single-column">
+ <div class="grid-container-column">
+ <div class="flex-container col-item center row">
+ <div class="flex-container row center row-item">
+ <label for="endianness">Endianness: </label>
+ <select
+ id="endianness"
+ class={$UIThemeCSSClass}
+ bind:value={$dataViewEndianness}
>
- <br /><label for="float64_dv"
- >float64: <text-field id="float64_dv" />{$float64}</label
+ {#each endiannessOpt as { name, value }}
+ <option {value}>{name}</option>
+ {/each}
+ </select>
+ </div>
+ </div>
+ <div class="grid-container-column">
+ <div id="data_vw">
+ <label for="offset_dv"
+ > Offset: <text-field
+ id="offset_dv"
+ />{$dataViewOffsetText}</label
>
- </span>
+ <span id="b8_dv">
+ <br /><label for="int8_dv"
+ > int8: <text-field
+ id="int8_dv"
+ />{$int8}</label
+ >
+ <br /><label for="uint8_dv"
+ > uint8: <text-field
+ id="uint8_dv"
+ />{$uint8}</label
+ >
+ </span>
+ <span id="b16_dv">
+ <br /><label for="int16_dv"
+ > int16: <text-field
+ id="int16_dv"
+ />{$int16}</label
+ >
+ <br /><label for="uint16_dv"
+ > uint16: <text-field
+ id="uint16_dv"
+ />{$uint16}</label
+ >
+ </span>
+ <span id="b32_dv">
+ <br /><label for="int32_dv"
+ > int32: <text-field
+ id="int32_dv"
+ />{$int32}</label
+ >
+ <br /><label for="uint32_dv"
+ > uint32: <text-field
+ id="uint32_dv"
+ />{$uint32}</label
+ >
+ <br /><label for="float32_dv"
+ >float32: <text-field id="float32_dv" />{$float32}</label
+ >
+ </span>
+ <span id="b64_dv">
+ <br /><label for="int64_dv"
+ > int64: <text-field
+ id="int64_dv"
+ />{$int64}</label
+ >
+ <br /><label for="uint64_dv"
+ > uint64: <text-field
+ id="uint64_dv"
+ />{$uint64}</label
+ >
+ <br /><label for="float64_dv"
+ >float64: <text-field id="float64_dv" />{$float64}</label
+ >
+ </span>
+ </div>
</div>
</div>
</div>
- </div>
- </fieldset>
- {/if}
- </div>
-</main>
-<hr />
-<div class="omega-latency flex-container row center">
- <div>Powered by Ωedit v{serverVersion} on port {omegaEditPort}</div>
- <div class="latency-group flex-container row center">
- <svg class="latency-indicator">
- {#if serverLatency < 20}
- <circle cx="50%" cy="50%" r="4pt" fill="green" />
- {:else if serverLatency < 35}
- <circle cx="50%" cy="50%" r="4pt" fill="yellow" />
- {:else if serverLatency > 50}
- <circle cx="50%" cy="50%" r="4pt" fill="red" />
- {:else}
- <circle cx="50%" cy="50%" r="4pt" fill="grey" />
+ </fieldset>
{/if}
- </svg>
- <div class="latency-text">{serverLatency}ms</div>
+ </div>
+ </main>
+ <hr />
+ <div class="omega-latency flex-container row center">
+ <div>Powered by Ωedit v{serverVersion} on port {omegaEditPort}</div>
+ <div class="latency-group flex-container row center">
+ <svg class="latency-indicator">
+ {#if serverLatency < 20}
+ <circle cx="50%" cy="50%" r="4pt" fill="green" />
+ {:else if serverLatency < 35}
+ <circle cx="50%" cy="50%" r="4pt" fill="yellow" />
+ {:else if serverLatency > 50}
+ <circle cx="50%" cy="50%" r="4pt" fill="red" />
+ {:else}
+ <circle cx="50%" cy="50%" r="4pt" fill="grey" />
+ {/if}
+ </svg>
+ <div class="latency-text">{serverLatency}ms</div>
+ </div>
</div>
-</div>
+</body>
<!-- svelte-ignore css-unused-selector -->
<style lang="scss">
+ body.light {
+ color: #02060b;
+ }
+ body.dark {
+ color: #e1e3e5;
+ }
div.flex-container {
display: flex;
}
@@ -1583,9 +1645,7 @@ limitations under the License.
font-size: 15px;
padding: 0;
font-weight: normal;
- border-color: white;
border-width: 1px;
- background-color: #22272e;
}
header div.flex-container-col {
@@ -1634,13 +1694,27 @@ limitations under the License.
input,
select {
- background-color: #3c3c3c;
- color: white;
border-width: 0;
padding-top: 2px;
padding-bottom: 2px;
font-weight: bold;
}
+ input.dark {
+ background-color: #101821;
+ color: #e1e3e5;
+ }
+ select.dark {
+ background-color: #101821;
+ color: #e1e3e5;
+ }
+ input.light {
+ background-color: #e1e3e5;
+ color: #02060b;
+ }
+ select.light {
+ background-color: #e1e3e5;
+ color: #02060b;
+ }
textarea {
color: inherit;
@@ -1656,13 +1730,18 @@ limitations under the License.
display: inline-block;
border-radius: 4px;
border-width: 0;
- background-color: #727272;
- color: #ffffff;
font-weight: bold;
margin-bottom: 5px;
cursor: pointer;
}
-
+ button.dark {
+ background-color: #322716;
+ color: #fffdfa;
+ }
+ button.light {
+ background-color: #c8b69b;
+ color: #322716;
+ }
.dataEditor {
display: grid;
/* I think this should be 32em instead of 19em for 32 characters, but that didn't work */
@@ -1686,14 +1765,30 @@ limitations under the License.
}
.dataEditor div.hd {
- background: #767676;
text-align: center;
font-weight: bold;
}
-
+ .dataEditor div.hd.dark {
+ background-color: #2f3e4f;
+ color: #02060b;
+ }
+ .dataEditor div.hd.light {
+ background-color: #687483;
+ color: #110b02;
+ }
.dataEditor div.measure {
display: flex;
}
+ .dataEditor div.measure.dark {
+ display: flex;
+ background-color: #101821;
+ color: #e1e3e5;
+ }
+ .dataEditor div.measure.light {
+ display: flex;
+ background-color: #e1e3e5;
+ color: #02060b;
+ }
.dataEditor div.measure.selection {
flex-direction: row;
@@ -1782,17 +1877,20 @@ limitations under the License.
}
button.submit {
background: green;
+ color: #e1e3e5;
}
button.delete {
background: red;
+ color: #e1e3e5;
}
button.insert {
background: darkorchid;
+ color: #e1e3e5;
}
button:disabled {
opacity: 0.3;
cursor: not-allowed;
- color: #3a3838;
+ color: var(--vscode-button-foreground);
}
.dataEditor textarea {
display: block;
@@ -1811,13 +1909,16 @@ limitations under the License.
pointer-events: none;
max-width: 100px;
}
-
- .dataEditor textarea.physical_vw {
- background: #4c4c4c;
+ .dataEditor select.address_type {
+ height: 100%;
}
-
- .dataEditor textarea.logicalView {
- background: #3c3c3c;
+ .dataEditor textarea.dark {
+ background-color: #101821;
+ color: #fffdfa;
+ }
+ .dataEditor textarea.light {
+ background-color: #e1e3e5;
+ color: #02060b;
}
.dataEditor div.editView {
@@ -1828,13 +1929,6 @@ limitations under the License.
word-break: break-all;
}
- .dataEditor textarea.selectedContent {
- background: #2c2c2c;
- }
- .dataEditor textarea.selectedContent:disabled {
- background: #252526;
- }
-
.dataEditor button {
padding: 10px;
margin-right: 5px;
diff --git a/src/svelte/src/stores/index.ts b/src/svelte/src/stores/index.ts
index e3e2513..3475bb1 100644
--- a/src/svelte/src/stores/index.ts
+++ b/src/svelte/src/stores/index.ts
@@ -16,6 +16,7 @@
*/
import { writable, derived } from 'svelte/store'
+import { ThemeType } from '../utilities/colorScheme'
import {
validEncodingStr,
validRequestableData,
@@ -62,6 +63,7 @@ export const replacing = writable(false)
export const replacementsCount = writable(0)
export const searchIndex = writable(0)
export const headerHidden = writable(false)
+export const UITheme = writable(ThemeType.Dark)
export const editByte = derived(
[
diff --git a/src/svelte/src/utilities/message.ts b/src/svelte/src/utilities/colorScheme.ts
similarity index 58%
copy from src/svelte/src/utilities/message.ts
copy to src/svelte/src/utilities/colorScheme.ts
index 25ddf6f..26fc663 100644
--- a/src/svelte/src/utilities/message.ts
+++ b/src/svelte/src/utilities/colorScheme.ts
@@ -14,29 +14,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// import * as vscode from 'vscode'
-export enum MessageCommand {
- viewportSubscribe,
- save,
- undo,
- redo,
- clear,
- fileInfo,
- commit,
- search,
- searchAndReplace,
- addBreakpoint,
- editorOnChange,
- loadFile,
- requestEditedData,
- setSessionFile,
- updateLogicalDisplay,
- populateSelectionData,
- heartBeat,
- replacementsResults,
+import { writable } from 'svelte/store'
+
+export enum ColorPalette {
+ PrimaryDarker = '#02060B',
+ PrimaryDark = '#101821',
+ PrimaryMid = '#2F3E4F',
+ PrimaryLight = '#687483',
+ PrimaryLighter = '#E1E3E5',
+ SecondaryDarker = '#110B02',
+ SecondaryDark = '#322716',
+ SecondaryMid = '#796444',
+ SecondaryLight = '#C8B69B',
+ SecondaryLighter = '#FFFDFA',
+}
+
+export enum ThemeType {
+ Dark = 2,
+ Light = 3,
}
-export type EditorMessage = {
- command: MessageCommand
- data: Record<string, any>
+export enum CSSThemeClass {
+ Dark = 'dark',
+ Light = 'light',
}
+
+export const darkUITheme = writable(true)
+
+export const UIThemeCSSClass = writable(CSSThemeClass.Dark)
diff --git a/src/svelte/src/utilities/message.ts b/src/svelte/src/utilities/message.ts
index 25ddf6f..0ae4a88 100644
--- a/src/svelte/src/utilities/message.ts
+++ b/src/svelte/src/utilities/message.ts
@@ -35,6 +35,7 @@ export enum MessageCommand {
populateSelectionData,
heartBeat,
replacementsResults,
+ setUITheme,
}
export type EditorMessage = {
command: MessageCommand