You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by ar...@apache.org on 2023/08/21 21:08:30 UTC
[daffodil-vscode] branch main updated: Fixed Multiple Data Editor Editing / Display Items
This is an automated email from the ASF dual-hosted git repository.
arosien 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 af689c7 Fixed Multiple Data Editor Editing / Display Items
af689c7 is described below
commit af689c7b55cc1b1223257134f82535e0232f62d4
Author: Robert Strickland <st...@gmail.com>
AuthorDate: Mon Aug 21 10:27:58 2023 -0500
Fixed Multiple Data Editor Editing / Display Items
- Fixed issue where binary display radix would still display 16 bytes
per row, instead of 8.
- Fixed inability to edit a "non-regular" sized file ( file size < 2 )
- Rerouted all file / viewport UI offset traversal to use toplevel
`seek()` function.
Closes #821
Closes #783
---
.../DataDisplays/CustomByteDisplay/BinaryData.ts | 38 +++++-
.../CustomByteDisplay/DataLineFeed.svelte | 114 +++++++++--------
.../CustomByteDisplay/DataValue.svelte | 10 +-
.../FileTraversalIndicator.svelte | 5 +-
.../components/DataDisplays/DataViewports.svelte | 3 -
.../src/components/Editors/DataEditor.svelte | 13 +-
.../Header/fieldsets/SearchReplace.svelte | 2 +
.../components/Header/fieldsets/Settings.svelte | 3 +
src/svelte/src/components/dataEditor.svelte | 142 +++++++++++----------
src/svelte/src/stores/index.ts | 55 ++++++--
src/svelte/src/utilities/display.ts | 16 ++-
src/svelte/src/utilities/elementKeypressEvents.ts | 1 -
src/svelte/src/utilities/highlights.ts | 2 +
13 files changed, 250 insertions(+), 154 deletions(-)
diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts b/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
index dec18d0..95e75e4 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
@@ -16,8 +16,16 @@
*/
import { SimpleWritable } from '../../../stores/localStore'
-import type { RadixValues } from '../../../stores/configuration'
-import { radixBytePad } from '../../../utilities/display'
+import {
+ NUM_LINES_DISPLAYED,
+ type BytesPerRow,
+ type RadixValues,
+ VIEWPORT_CAPACITY_MAX,
+} from '../../../stores/configuration'
+import {
+ radixBytePad,
+ viewport_offset_to_line_num,
+} from '../../../utilities/display'
export const BYTE_ACTION_DIV_OFFSET: number = 24
@@ -97,6 +105,32 @@ export class ViewportDataStore_t extends SimpleWritable<ViewportData_t> {
this._offsetMax = value.fileOffset + value.bytesLeft + value.length
}
+ public lowerFetchBoundary(): number {
+ return this.storeData().fileOffset
+ }
+
+ public upperFetchBoundary(bytesPerRow: BytesPerRow): number {
+ const store = this.storeData()
+ const boundary =
+ store.fileOffset + store.length - NUM_LINES_DISPLAYED * bytesPerRow
+
+ return boundary
+ }
+
+ public lineTopMax(bytesPerRow: BytesPerRow): number {
+ const vpMaxOffset = Math.max(
+ 0,
+ this.storeData().length - NUM_LINES_DISPLAYED * bytesPerRow
+ )
+ const vpLineTopMax = viewport_offset_to_line_num(
+ vpMaxOffset + this.storeData().fileOffset,
+ this.storeData().fileOffset,
+ bytesPerRow
+ )
+
+ return vpLineTopMax + 1
+ }
+
public physical_byte_values(
radix: RadixValues,
bytesPerRow: 16 | 8
diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
index 7051354..7d4d08d 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
@@ -28,11 +28,11 @@ limitations under the License.
searchQuery,
editorActionsAllowed,
dataFeedLineTop,
+ seekOffsetInput,
} from '../../../stores'
import {
EditByteModes,
NUM_LINES_DISPLAYED,
- type BytesPerRow,
type RadixValues,
EditActionRestrictions,
VIEWPORT_SCROLL_INCREMENT,
@@ -52,6 +52,7 @@ limitations under the License.
import FileTraversalIndicator from './FileTraversalIndicator.svelte'
import {
byteDivWidthFromRadix,
+ line_num_to_file_offset,
viewport_offset_to_line_num,
} from '../../../utilities/display'
import SelectedByteEdit from './SelectedByteEdit.svelte'
@@ -63,11 +64,10 @@ limitations under the License.
selectionHighlights,
searchResultsHighlights,
updateSearchResultsHighlights,
+ searchResultsUpdated,
} from '../../../utilities/highlights'
-
- // export let $dataFeedLineTop: number
+ import { bytesPerRow } from '../../../stores'
export let awaitViewportSeek: boolean
- export let bytesPerRow: BytesPerRow = 16
export let dataRadix: RadixValues = 16
export let addressRadix: RadixValues = 16
export let viewportData: ViewportData_t
@@ -81,7 +81,7 @@ limitations under the License.
numLinesToScroll: number
) {
const newLineTopOffset =
- numLinesToScroll * bytesPerRow + $dataFeedLineTop * bytesPerRow
+ numLinesToScroll * $bytesPerRow + $dataFeedLineTop * $bytesPerRow
let scroll_count = Math.floor(newLineTopOffset / VIEWPORT_SCROLL_INCREMENT)
if (direction === ViewportScrollDirection.INCREMENT) {
@@ -89,8 +89,8 @@ limitations under the License.
viewportData.fileOffset + scroll_count * VIEWPORT_SCROLL_INCREMENT
if (fetchBound > $fileMetrics.computedSize)
return (
- ($fileMetrics.computedSize / bytesPerRow) * bytesPerRow -
- NUM_LINES_DISPLAYED * bytesPerRow
+ ($fileMetrics.computedSize / $bytesPerRow) * $bytesPerRow -
+ NUM_LINES_DISPLAYED * $bytesPerRow
)
return fetchBound
@@ -107,22 +107,44 @@ limitations under the License.
}
const INCREMENT_LINE = () => {
- handle_navigation(1)
+ $seekOffsetInput = line_num_to_file_offset(
+ $dataFeedLineTop + 1,
+ viewportData.fileOffset,
+ $bytesPerRow
+ ).toString(addressRadix)
+ eventDispatcher('seek')
}
const DECREMENT_LINE = () => {
- handle_navigation(-1)
+ $seekOffsetInput = line_num_to_file_offset(
+ $dataFeedLineTop - 1,
+ viewportData.fileOffset,
+ $bytesPerRow
+ ).toString(addressRadix)
+ eventDispatcher('seek')
}
const INCREMENT_SEGMENT = () => {
- handle_navigation(NUM_LINES_DISPLAYED)
+ $seekOffsetInput = line_num_to_file_offset(
+ $dataFeedLineTop + NUM_LINES_DISPLAYED,
+ viewportData.fileOffset,
+ $bytesPerRow
+ ).toString(addressRadix)
+ eventDispatcher('seek')
}
const DECREMENT_SEGMENT = () => {
- handle_navigation(-NUM_LINES_DISPLAYED)
+ $seekOffsetInput = line_num_to_file_offset(
+ $dataFeedLineTop - NUM_LINES_DISPLAYED,
+ viewportData.fileOffset,
+ $bytesPerRow
+ ).toString(addressRadix)
+ eventDispatcher('seek')
}
const SCROLL_TO_END = () => {
- handle_navigation(lineTopMaxFile)
+ $seekOffsetInput = $fileMetrics.computedSize.toString(addressRadix)
+ eventDispatcher('seek')
}
const SCROLL_TO_TOP = () => {
- handle_navigation(-lineTopMaxFile)
+ $seekOffsetInput = '0'
+ eventDispatcher('seek')
}
let totalLinesPerFilesize = 0
@@ -171,8 +193,8 @@ limitations under the License.
$: themeClass = $UIThemeCSSClass
$: {
- totalLinesPerFilesize = Math.ceil($fileMetrics.computedSize / bytesPerRow)
- totalLinesPerViewport = Math.ceil(viewportData.data.length / bytesPerRow)
+ totalLinesPerFilesize = Math.ceil($fileMetrics.computedSize / $bytesPerRow)
+ totalLinesPerViewport = Math.ceil(viewportData.data.length / $bytesPerRow)
lineTopMaxFile = Math.max(totalLinesPerFilesize - NUM_LINES_DISPLAYED, 0)
lineTopMaxViewport = Math.max(
totalLinesPerViewport - NUM_LINES_DISPLAYED,
@@ -188,56 +210,54 @@ limitations under the License.
$selectionDataStore.active || (atViewportHead && atFileHead)
disableIncrement =
$selectionDataStore.active || (atViewportTail && atFileTail)
- lineTopFileOffset = $dataFeedLineTop * bytesPerRow
+ lineTopFileOffset = $dataFeedLineTop * $bytesPerRow
}
$: {
+ activeSelection = $selectionHighlights
+ searchResults = $searchResultsHighlights
if (
- viewportData.fileOffset >= 0 &&
- !awaitViewportSeek &&
- $dataFeedLineTop >= 0
+ (viewportData.fileOffset >= 0 &&
+ !awaitViewportSeek &&
+ $dataFeedLineTop >= 0) ||
+ $searchResultsUpdated
) {
if (
viewportLines.length !== 0 &&
- bytesPerRow !== viewportLines[0].bytes.length
+ $bytesPerRow !== viewportLines[0].bytes.length
) {
$dataFeedLineTop = viewport_offset_to_line_num(
parseInt(viewportLines[0].offset, addressRadix),
viewportData.fileOffset,
- bytesPerRow
+ $bytesPerRow
)
}
viewportLines = generate_line_data(
$dataFeedLineTop,
dataRadix,
- addressRadix,
- bytesPerRow
+ addressRadix
)
+ $searchResultsUpdated = false
}
}
$: byteElementWidth = byteDivWidthFromRadix(dataRadix)
- $: {
- activeSelection = $selectionHighlights
- searchResults = $searchResultsHighlights
- }
function generate_line_data(
startIndex: number,
dataRadix: RadixValues,
addressRadix: RadixValues,
- bytesPerRow: BytesPerRow,
endIndex: number = startIndex + (NUM_LINES_DISPLAYED - 1)
): Array<ViewportLineData> {
let ret = []
for (let i = startIndex; i <= endIndex; i++) {
- const viewportLineOffset = i * bytesPerRow
+ const viewportLineOffset = i * $bytesPerRow
const fileOffset = viewportLineOffset + viewportData.fileOffset
let bytes: Array<ByteValue> = []
const highlight = i % 2 === 0
- for (let bytePos = 0; bytePos < bytesPerRow; bytePos++) {
+ for (let bytePos = 0; bytePos < $bytesPerRow; bytePos++) {
let byteOffset = viewportLineOffset + bytePos
bytes.push({
offset: byteOffset,
@@ -251,7 +271,7 @@ limitations under the License.
ret.push({
offset: fileOffset.toString(addressRadix).padStart(8, '0'),
- fileLine: fileOffset / bytesPerRow,
+ fileLine: fileOffset / $bytesPerRow,
bytes: bytes,
highlight: highlight ? 'even' : 'odd',
})
@@ -311,7 +331,7 @@ limitations under the License.
nextViewportOffset: nextViewportOffset,
lineTopOnRefresh:
Math.floor(
- (viewportOffset + lineTopOffset - nextViewportOffset) / bytesPerRow
+ (viewportOffset + lineTopOffset - nextViewportOffset) / $bytesPerRow
) + numLinesToScroll,
})
return
@@ -413,9 +433,9 @@ limitations under the License.
const offset =
Math.ceil(
($fileMetrics.computedSize * (percentageTraversed / 100.0)) /
- bytesPerRow
- ) * bytesPerRow
- const firstPageThreshold = bytesPerRow * NUM_LINES_DISPLAYED
+ $bytesPerRow
+ ) * $bytesPerRow
+ const firstPageThreshold = $bytesPerRow * NUM_LINES_DISPLAYED
const lastPageThreshold = $fileMetrics.computedSize - firstPageThreshold
if (offset <= firstPageThreshold) {
// scroll to the top because we are somewhere in the first page
@@ -425,13 +445,8 @@ limitations under the License.
SCROLL_TO_END()
} else {
// scroll to the offset since we are not in the first or last page
- vscode.postMessage({
- command: MessageCommand.scrollViewport,
- data: {
- scrollOffset: offset,
- bytesPerRow: bytesPerRow,
- },
- })
+ $seekOffsetInput = offset.toString(addressRadix)
+ eventDispatcher('seek')
lineTopOnRefresh = lineTopMaxViewport
awaitViewportSeek = true
}
@@ -495,7 +510,6 @@ limitations under the License.
<div class="address" id="address">
<b>{viewportLine.offset}</b>
</div>
-
<div
class="byte-line"
id="physical-line-{i.toString(16).padStart(2, '0')}"
@@ -510,14 +524,13 @@ limitations under the License.
id={'physical'}
radix={dataRadix}
width={byteElementWidth}
- disabled={byte.offset > viewportData.length}
+ disabled={!byte.value}
bind:selectionData={$selectionDataStore}
on:mouseup={mouseup}
on:mousedown={mousedown}
/>
{/each}
</div>
-
<div
class="byte-line"
id="logical-line-{i.toString(16).padStart(2, '0')}"
@@ -532,7 +545,7 @@ limitations under the License.
id={'logical'}
radix={dataRadix}
width={byteElementWidth}
- disabled={byte.offset > viewportData.length}
+ disabled={!byte.value}
bind:selectionData={$selectionDataStore}
on:mouseup={mouseup}
on:mousedown={mousedown}
@@ -551,7 +564,6 @@ limitations under the License.
maxDisplayLines={NUM_LINES_DISPLAYED}
bind:percentageTraversed
on:indicatorClicked={handleClickedIndicator}
- {bytesPerRow}
/>
<FlexContainer --dir="row">
<Button
@@ -570,7 +582,7 @@ limitations under the License.
disabledBy={disableIncrement}
width="30pt"
description="Increment offset by {NUM_LINES_DISPLAYED *
- bytesPerRow} bytes"
+ $bytesPerRow} bytes"
tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
@@ -581,7 +593,7 @@ limitations under the License.
fn={INCREMENT_LINE}
disabledBy={disableIncrement}
width="30pt"
- description="Increment offset by {bytesPerRow} bytes"
+ description="Increment offset by {$bytesPerRow} bytes"
tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
@@ -592,7 +604,7 @@ limitations under the License.
fn={DECREMENT_LINE}
disabledBy={disableDecrement}
width="30pt"
- description="Decrement offset by {bytesPerRow} bytes"
+ description="Decrement offset by {$bytesPerRow} bytes"
tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
@@ -604,7 +616,7 @@ limitations under the License.
disabledBy={disableDecrement}
width="30pt"
description="Decrement offset by {NUM_LINES_DISPLAYED *
- bytesPerRow} bytes"
+ $bytesPerRow} bytes"
tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte
index fdcc1c8..ab12df4 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataValue.svelte
@@ -39,7 +39,6 @@ limitations under the License.
const eventDispatcher = createEventDispatcher()
- let consideredForSelection = false
let makingSelection = false
$: {
@@ -50,6 +49,11 @@ limitations under the License.
function mouse_enter_handle(event: MouseEvent) {
if (!makingSelection) return
+ if (disabled) {
+ selectionData.endOffset = -1
+ makingSelection = false
+ return
+ }
selectionData.endOffset = byte.offset
}
function mouse_leave_handle(event: MouseEvent) {
@@ -78,7 +82,6 @@ limitations under the License.
class:isSelected
class:isSearchResult
class:possibleSelection
- class:selecting={consideredForSelection}
id={id + '-' + byte.offset.toString()}
style:width
on:mouseup={mouse_event_handle}
@@ -95,12 +98,13 @@ limitations under the License.
class:isSelected
class:isSearchResult
class:possibleSelection
- class:selecting={consideredForSelection}
id={id + '-' + byte.offset.toString()}
style:width={'20px'}
class:latin1Undefined={latin1Undefined(byte.value)}
on:mouseup={mouse_event_handle}
on:mousedown={mouse_event_handle}
+ on:mouseenter={mouse_enter_handle}
+ on:mouseleave={mouse_leave_handle}
>
{latin1Undefined(byte.value) ? '' : String.fromCharCode(byte.value)}
</div>
diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/FileTraversalIndicator.svelte b/src/svelte/src/components/DataDisplays/CustomByteDisplay/FileTraversalIndicator.svelte
index 7c7b8f4..96496be 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/FileTraversalIndicator.svelte
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/FileTraversalIndicator.svelte
@@ -16,13 +16,12 @@ limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
-
+ import { bytesPerRow } from '../../../stores'
const eventDispatcher = createEventDispatcher()
export let totalLines = 0
export let currentLine = 0
export let fileOffset = 0
- export let bytesPerRow = 16
export let percentageTraversed
export let maxDisplayLines = 20
export let selectionActive: boolean
@@ -42,7 +41,7 @@ limitations under the License.
} else {
indicatorClickDisabled = false
percentageTraversed =
- ((currentLine + (fileOffset / bytesPerRow + 20)) / totalLines) * 100.0
+ ((currentLine + (fileOffset / $bytesPerRow + 20)) / totalLines) * 100.0
if (indicatorContainer)
indicatorContainer.addEventListener('click', updatePercentageTraversed)
}
diff --git a/src/svelte/src/components/DataDisplays/DataViewports.svelte b/src/svelte/src/components/DataDisplays/DataViewports.svelte
index 2c0cafe..99f4d25 100644
--- a/src/svelte/src/components/DataDisplays/DataViewports.svelte
+++ b/src/svelte/src/components/DataDisplays/DataViewports.svelte
@@ -17,9 +17,7 @@ limitations under the License.
<script lang="ts">
import {
addressRadix,
- bytesPerRow,
displayRadix,
- dataFeedLineTop,
dataFeedAwaitRefresh,
viewport,
} from '../../stores'
@@ -32,7 +30,6 @@ limitations under the License.
on:applyChanges
on:handleEditorEvent
viewportData={$viewport}
- bytesPerRow={$bytesPerRow}
dataRadix={$displayRadix}
addressRadix={$addressRadix}
bind:awaitViewportSeek={$dataFeedAwaitRefresh}
diff --git a/src/svelte/src/components/Editors/DataEditor.svelte b/src/svelte/src/components/Editors/DataEditor.svelte
index d1d0987..f8d51b1 100644
--- a/src/svelte/src/components/Editors/DataEditor.svelte
+++ b/src/svelte/src/components/Editors/DataEditor.svelte
@@ -15,7 +15,12 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<script lang="ts">
- import { editorSelection, editMode, selectionDataStore } from '../../stores'
+ import {
+ editorSelection,
+ editMode,
+ selectionDataStore,
+ regularSizedFile,
+ } from '../../stores'
import { EditByteModes } from '../../stores/configuration'
import { UIThemeCSSClass } from '../../utilities/colorScheme'
import { createEventDispatcher } from 'svelte'
@@ -30,7 +35,9 @@ limitations under the License.
{
const eventDetails = event as InputEvent
const editorElement = eventDetails.target as HTMLTextAreaElement
- $editorSelection = editorElement.value
+ editorSelection.update(() => {
+ return editorElement.value
+ })
}
break
@@ -45,7 +52,7 @@ limitations under the License.
</script>
<div class="editView" id="edit_view">
- {#if $editMode === EditByteModes.Multiple && $selectionDataStore.active}
+ {#if $editMode === EditByteModes.Multiple && ($selectionDataStore.active || !$regularSizedFile)}
<textarea
class={$UIThemeCSSClass}
id="selectedContent"
diff --git a/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte b/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte
index 7f32d7a..0ba4114 100644
--- a/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte
+++ b/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte
@@ -29,6 +29,7 @@ limitations under the License.
searchErr,
searchQuery,
seekErr,
+ dataFeedAwaitRefresh,
} from '../../../stores'
import { vscode } from '../../../utilities/vscode'
import { MessageCommand } from '../../../utilities/message'
@@ -255,6 +256,7 @@ limitations under the License.
searchStarted = replaceStarted = false
if (msg.data.data.replacementsCount > 0) {
// subtract 1 from the next offset because search next will add 1
+ clearSearchResultsHighlights()
matchOffset = msg.data.data.nextOffset - 1
preReplaceHasPrev = hasPrev
justReplaced = true
diff --git a/src/svelte/src/components/Header/fieldsets/Settings.svelte b/src/svelte/src/components/Header/fieldsets/Settings.svelte
index 2605a7e..5a0c841 100644
--- a/src/svelte/src/components/Header/fieldsets/Settings.svelte
+++ b/src/svelte/src/components/Header/fieldsets/Settings.svelte
@@ -24,9 +24,12 @@ limitations under the License.
displayRadix,
editorEncoding,
editorActionsAllowed,
+ bytesPerRow,
} from '../../../stores'
import FlexContainer from '../../layouts/FlexContainer.svelte'
import { UIThemeCSSClass } from '../../../utilities/colorScheme'
+
+ $: $bytesPerRow = $displayRadix === RADIX_OPTIONS.Binary ? 8 : 16
</script>
<fieldset>
diff --git a/src/svelte/src/components/dataEditor.svelte b/src/svelte/src/components/dataEditor.svelte
index a64acfe..5ed6520 100644
--- a/src/svelte/src/components/dataEditor.svelte
+++ b/src/svelte/src/components/dataEditor.svelte
@@ -33,9 +33,9 @@ limitations under the License.
dataFeedLineTop,
SelectionData_t,
dataFeedAwaitRefresh,
- fileMetrics,
viewport,
searchQuery,
+ regularSizedFile,
} from '../stores'
import {
CSSThemeClass,
@@ -48,9 +48,8 @@ limitations under the License.
import Main from './Main.svelte'
import {
EditByteModes,
- NUM_LINES_DISPLAYED,
- VIEWPORT_CAPACITY_MAX,
VIEWPORT_SCROLL_INCREMENT,
+ type BytesPerRow,
} from '../stores/configuration'
import ServerMetrics from './ServerMetrics/ServerMetrics.svelte'
import {
@@ -61,10 +60,7 @@ limitations under the License.
EditEvent,
ViewportData_t,
} from './DataDisplays/CustomByteDisplay/BinaryData'
- import {
- byte_count_divisible_offset,
- viewport_offset_to_line_num,
- } from '../utilities/display'
+ import { byte_count_divisible_offset } from '../utilities/display'
import { clearSearchResultsHighlights } from '../utilities/highlights'
$: $UIThemeCSSClass = $darkUITheme ? CSSThemeClass.Dark : CSSThemeClass.Light
@@ -86,71 +82,72 @@ limitations under the License.
}
}
+ function offset_to_viewport_line_number(
+ offset: number,
+ bytesPerRow: BytesPerRow,
+ viewportStartOffset: number = $viewport.fileOffset
+ ): number {
+ const nearestBPRdivisibleOffset = byte_count_divisible_offset(
+ offset - viewportStartOffset,
+ bytesPerRow
+ )
+ const offsetLineNumInViewport = nearestBPRdivisibleOffset / bytesPerRow
+ return offsetLineNumInViewport
+ }
+
+ function fetchable_content(offset: number): boolean {
+ return offset > $viewport.fileOffset
+ ? $viewport.bytesLeft > 0
+ : $viewport.fileOffset > 0
+ }
+
+ function should_fetch_new_viewoprt(offset: number) {
+ const lowerBound = viewport.lowerFetchBoundary()
+ const upperBound = viewport.upperFetchBoundary($bytesPerRow)
+ const fetchableContent = fetchable_content(offset)
+ if (!fetchableContent) return false
+
+ const boundaryTripped = offset < lowerBound || offset > upperBound
+
+ return boundaryTripped
+ }
+
+ function target_offset_in_viewport(offset: number): boolean {
+ return offset >= $viewport.fileOffset && offset <= $viewport.length
+ }
+
function seek(offsetArg?: number) {
if (!offsetArg) offsetArg = $seekOffset
- const fileSize = $fileMetrics.computedSize
- const viewportBoundary =
- $viewport.length +
- $viewport.fileOffset -
- NUM_LINES_DISPLAYED * $bytesPerRow
- const offset =
- offsetArg > 0 &&
- offsetArg < viewport.offsetMax &&
- offsetArg % $bytesPerRow === 0
- ? offsetArg + 1
- : offsetArg
-
- const relativeFileLine = Math.floor(offset / $bytesPerRow)
- const relativeFileOffset = relativeFileLine * $bytesPerRow
- const lineTopBoundary =
- Math.floor($viewport.length / $bytesPerRow) - NUM_LINES_DISPLAYED
- let relativeTargetLine = relativeFileLine
- let viewportStartOffset = $viewport.fileOffset
- $dataFeedAwaitRefresh = true
- // make sure that the offset is within the loaded viewport
- if (
- offset < $viewport.fileOffset ||
- offset > viewportBoundary ||
- relativeTargetLine > lineTopBoundary
- ) {
- let adjustedFileOffset = Math.max(
- 0,
- relativeFileOffset - VIEWPORT_SCROLL_INCREMENT
+ const shouldFetchData = should_fetch_new_viewoprt(offsetArg)
+
+ if (!shouldFetchData) {
+ $dataFeedLineTop = Math.min(
+ viewport.lineTopMax($bytesPerRow),
+ offset_to_viewport_line_number(offsetArg, $bytesPerRow)
)
- const fetchPastFileBoundary =
- fileSize - adjustedFileOffset < VIEWPORT_CAPACITY_MAX
- if (fetchPastFileBoundary)
- adjustedFileOffset = byte_count_divisible_offset(
- fileSize - VIEWPORT_CAPACITY_MAX,
- $bytesPerRow,
- 1
- )
-
- viewportStartOffset = adjustedFileOffset
- relativeTargetLine = fetchPastFileBoundary
- ? viewport_offset_to_line_num(
- offset,
- viewportStartOffset,
- $bytesPerRow
- ) -
- (NUM_LINES_DISPLAYED - 1)
- : viewport_offset_to_line_num(offset, viewportStartOffset, $bytesPerRow)
-
- // NOTE: Scrolling the viewport will make the display bounce until it goes to the correct offset
- vscode.postMessage({
- command: MessageCommand.scrollViewport,
- data: {
- // scroll the viewport with the offset in the middle
- scrollOffset: viewportStartOffset,
- bytesPerRow: $bytesPerRow,
- numLinesDisplayed: $viewportNumLinesDisplayed,
- },
- })
+ return
}
- $dataFeedLineTop = relativeTargetLine
- $dataFeedAwaitRefresh = false
+ $dataFeedAwaitRefresh = true
+
+ offsetArg = byte_count_divisible_offset(offsetArg, $bytesPerRow)
+ const fetchOffset = Math.max(0, offsetArg - VIEWPORT_SCROLL_INCREMENT)
+
+ $dataFeedLineTop = offset_to_viewport_line_number(
+ offsetArg,
+ $bytesPerRow,
+ fetchOffset
+ )
+
+ vscode.postMessage({
+ command: MessageCommand.scrollViewport,
+ data: {
+ scrollOffset: fetchOffset,
+ bytesPerRow: $bytesPerRow,
+ numLinesDisplayed: $viewportNumLinesDisplayed,
+ },
+ })
clearDataDisplays()
}
@@ -175,10 +172,12 @@ limitations under the License.
}
function handleEditorEvent(_: Event) {
- if ($selectionSize < 0) {
+ if ($regularSizedFile && $selectionSize < 0) {
clearDataDisplays()
return
}
+ if (!$regularSizedFile && $editorSelection.length == 0) return
+
requestEditedData()
}
@@ -187,7 +186,9 @@ limitations under the License.
let editedData: Uint8Array
let originalData = $originalDataSegment
- let editedOffset = $selectionDataStore.startOffset + $viewport.fileOffset
+ let editedOffset = $regularSizedFile
+ ? $selectionDataStore.startOffset + $viewport.fileOffset
+ : 0
// noinspection FallThroughInSwitchStatementJS
switch (action) {
@@ -200,7 +201,10 @@ limitations under the License.
editedData = $editedDataSegment.subarray(0, 1)
break
case 'insert-replace':
- editedData = $editedDataSegment
+ editedData =
+ !$regularSizedFile && $editorSelection.length == 0
+ ? new Uint8Array(0)
+ : $editedDataSegment
break
case 'delete':
editedData = new Uint8Array(0)
diff --git a/src/svelte/src/stores/index.ts b/src/svelte/src/stores/index.ts
index 39add99..185cba1 100644
--- a/src/svelte/src/stores/index.ts
+++ b/src/svelte/src/stores/index.ts
@@ -89,9 +89,6 @@ export const dataViewEndianness = writable('le')
// radix to use for displaying raw bytes (2, 8, 10, 16)
export const displayRadix = writable(16 as RadixValues)
-// true if the edit byte window is hidden
-export const editByteWindowHidden = writable(true)
-
// segment of data that is being edited in single or multiple byte modes
export const editedDataSegment = writable(new Uint8Array(0))
@@ -108,8 +105,12 @@ export const seekOffsetInput = writable('')
// writeable boolean, true indicates that the search is case insensitive for character sets that support it
export const searchCaseInsensitive = writable(false)
+// Current viewport line number at the top of the data display
export const dataFeedLineTop = writable(0)
+
+// Data display needs to wait from data from extension or function
export const dataFeedAwaitRefresh = writable(false)
+
export const rerenderActionElements = writable(false)
// Viewport properties
@@ -124,6 +125,7 @@ export const selectedByte = writable({
value: -1,
} as ByteValue)
+// Omega Edit and Data Editor file information
export const fileMetrics = new FileMetrics()
export const searchQuery = new SearchQuery()
@@ -133,13 +135,21 @@ export const searchErr = new ErrorStore(ErrorComponentType.SYMBOL)
export const replaceErr = new ErrorStore(ErrorComponentType.SYMBOL)
export const seekErr = new ErrorStore(ErrorComponentType.SYMBOL)
+// Which types of edit restrictions are in place
export const editorActionsAllowed = writable(EditActionRestrictions.None)
export const tooltipsEnabled = writable(false)
+
+// If byte lengths should be in a human readable format
export const sizeHumanReadable = writable(false)
// tracks the start and end offsets of the current selection
export const selectionDataStore = new SelectionData()
+// Can the user's selection derive both edit modes?
+export const regularSizedFile = derived(fileMetrics, ($fileMetrics) => {
+ return $fileMetrics.computedSize >= 2
+})
+
export const searchable = derived(
[searchQuery, editorEncoding],
([$searchQuery, $editorEncoding]) => {
@@ -187,8 +197,10 @@ export const replaceable = derived(
// derived readable enumeration that indicates the edit mode (single byte or multiple bytes)
export const editMode = derived(
- selectionDataStore,
- ($selectionData) => {
+ [selectionDataStore, regularSizedFile],
+ ([$selectionData, $regularSizedFile]) => {
+ if (!$regularSizedFile) return EditByteModes.Multiple
+
return $selectionData.originalEndOffset - $selectionData.startOffset === 0
? EditByteModes.Single
: EditByteModes.Multiple
@@ -211,7 +223,7 @@ export const seekOffset = derived(
[seekOffsetInput, addressRadix],
([$seekOffsetInput, $addressRadix]) => {
return $seekOffsetInput.length > 0
- ? parseInt($seekOffsetInput, $addressRadix)
+ ? Math.max(0, parseInt($seekOffsetInput, $addressRadix))
: 0
}
)
@@ -277,19 +289,21 @@ export const requestable = derived(
applyErrMsg.update(() => {
return ret.errMsg
})
+
return ret.valid
}
)
export const originalDataSegment = derived(
- [viewport, selectionDataStore],
- ([$viewport, $selectionData]) => {
- return !$viewport.data
- ? []
- : $viewport.data.slice(
- $selectionData.startOffset,
- $selectionData.originalEndOffset + 1
- )
+ [viewport, selectionDataStore, regularSizedFile],
+ ([$viewport, $selectionData, $regularSizedFile]) => {
+ if (!$viewport.data) return []
+ if (!$regularSizedFile) return $viewport.data
+
+ return $viewport.data.slice(
+ $selectionData.startOffset,
+ $selectionData.originalEndOffset + 1
+ )
}
)
@@ -298,23 +312,36 @@ export const applicable = derived(
[
requestable,
viewport,
+ editorSelection,
+ displayRadix,
editedDataSegment,
selectionDataStore,
selectionSize,
editMode,
editedByteIsOriginalByte,
editorActionsAllowed,
+ regularSizedFile,
],
([
$requestable,
$viewport,
+ $editorSelection,
+ $displayRadix,
$selectedFileData,
$selectionData,
$selectionSize,
$editMode,
$editedByteIsOriginalByte,
$editorActionsAllowed,
+ $regularSizedFile,
]) => {
+ if (!$regularSizedFile) {
+ return $viewport.data.length !=
+ $editorSelection.length / radixBytePad($displayRadix) &&
+ $editorActionsAllowed === EditActionRestrictions.OverwriteOnly
+ ? false
+ : $requestable
+ }
if (
!$requestable ||
($editedByteIsOriginalByte && $editMode === EditByteModes.Single)
diff --git a/src/svelte/src/utilities/display.ts b/src/svelte/src/utilities/display.ts
index a9edc4b..6b0f522 100644
--- a/src/svelte/src/utilities/display.ts
+++ b/src/svelte/src/utilities/display.ts
@@ -37,10 +37,6 @@ const ByteDivWidths = {
2: '64px' as ByteDivWidth,
}
-export type BinaryBytePrefix = 'B' | 'KB' | 'MB' | 'GB' | 'TB' | 'PB'
-
-export type BinaryBitPrefix = 'b' | 'Kb' | 'Mb' | 'Gb' | 'Tb' | 'Pb'
-
export function radixBytePad(radix: RadixValues): number {
switch (radix) {
case 2:
@@ -181,7 +177,17 @@ export function viewport_offset_to_line_num(
vpStartOffset: number,
bytesPerRow: BytesPerRow
): number {
- return Math.floor((offset - vpStartOffset) / bytesPerRow)
+ return Math.max(0, Math.floor((offset - vpStartOffset) / bytesPerRow))
+}
+
+export function line_num_to_file_offset(
+ lineNum: number,
+ viewportStartOffset: number,
+ bytesPerRow: BytesPerRow
+): number {
+ const offsetInViewport = lineNum * bytesPerRow
+ const offsetInFile = viewportStartOffset + offsetInViewport
+ return Math.max(0, offsetInFile)
}
export enum BinaryBytePrefixes {
diff --git a/src/svelte/src/utilities/elementKeypressEvents.ts b/src/svelte/src/utilities/elementKeypressEvents.ts
index 8cbabc8..5d266b7 100644
--- a/src/svelte/src/utilities/elementKeypressEvents.ts
+++ b/src/svelte/src/utilities/elementKeypressEvents.ts
@@ -26,7 +26,6 @@ type ElementKeypressEvent = {
}
class ElementKeypressEventMap {
- // private events: Array<ElementKeypressEvent> = []
private events: {
[key in ElementKeypressEventKey]: Array<ElementKeypressEvent>
} = {
diff --git a/src/svelte/src/utilities/highlights.ts b/src/svelte/src/utilities/highlights.ts
index 1ceeb44..bb00644 100644
--- a/src/svelte/src/utilities/highlights.ts
+++ b/src/svelte/src/utilities/highlights.ts
@@ -50,6 +50,7 @@ export const selectionHighlights = derived(
)
export const searchResultsHighlights = readable(searchResultsHighlightLUT)
+export const searchResultsUpdated = writable(false)
export function updateSearchResultsHighlights(
data: number[],
viewportFileOffset: number,
@@ -68,6 +69,7 @@ export function updateSearchResultsHighlights(
for (let i = 0; i < byteWidth; i++)
searchResultsHighlightLUT[offset - viewportFileOffset + i] = 1
})
+ searchResultsUpdated.set(true)
}
export function clearSearchResultsHighlights() {
searchResultsHighlightLUT.fill(0)