You've already forked objdiff-web
mirror of
https://github.com/encounter/objdiff-web.git
synced 2026-07-10 12:18:37 -07:00
Add symbol and instruction context menus
This commit is contained in:
@@ -9,6 +9,7 @@ import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import { FixedSizeList, areEqual } from 'react-window';
|
||||
import type { ListChildComponentProps } from 'react-window';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { createContextMenu, renderContextItems } from '../common/ContextMenu';
|
||||
import TooltipShared from '../common/TooltipShared';
|
||||
import {
|
||||
buildDiffConfig,
|
||||
@@ -36,6 +37,11 @@ const ROTATION_CLASSES = [
|
||||
styles.rotation8,
|
||||
];
|
||||
|
||||
const { ContextMenuProvider, useContextMenu } = createContextMenu<{
|
||||
column: number;
|
||||
row: number;
|
||||
}>();
|
||||
|
||||
const AsmCell = ({
|
||||
obj,
|
||||
config,
|
||||
@@ -53,6 +59,7 @@ const AsmCell = ({
|
||||
highlight: HighlightState;
|
||||
setHighlight: (highlight: HighlightState) => void;
|
||||
}) => {
|
||||
const onContextMenu = useContextMenu();
|
||||
if (!obj || !symbol) {
|
||||
return <div className={styles.instructionCell} />;
|
||||
}
|
||||
@@ -197,6 +204,7 @@ const AsmCell = ({
|
||||
className={clsx(classes)}
|
||||
data-tooltip-id="instruction-tooltip"
|
||||
data-tooltip-content={JSON.stringify(tooltipContent)}
|
||||
onContextMenu={(e) => onContextMenu(e, { column, row })}
|
||||
>
|
||||
{out}
|
||||
</div>
|
||||
@@ -413,28 +421,57 @@ const FunctionView = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.instructionList}>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<FixedSizeList
|
||||
height={height}
|
||||
itemCount={itemData.itemCount}
|
||||
itemSize={itemSize}
|
||||
width={width}
|
||||
itemData={itemData}
|
||||
overscanCount={20}
|
||||
onScroll={(e) => {
|
||||
setSymbolScrollOffset(
|
||||
currentUnitName,
|
||||
itemData.symbolName,
|
||||
e.scrollOffset,
|
||||
);
|
||||
}}
|
||||
initialScrollOffset={initialScrollOffset}
|
||||
>
|
||||
{AsmRow}
|
||||
</FixedSizeList>
|
||||
)}
|
||||
</AutoSizer>
|
||||
<ContextMenuProvider
|
||||
render={({ data }, close) => {
|
||||
let obj: diff.ObjectDiff | undefined;
|
||||
let symbol: display.SectionDisplaySymbol | undefined;
|
||||
switch (data.column) {
|
||||
case 0:
|
||||
obj = diff.left;
|
||||
symbol = itemData.left ?? undefined;
|
||||
break;
|
||||
case 1:
|
||||
obj = diff.right;
|
||||
symbol = itemData.right ?? undefined;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!obj || !symbol) {
|
||||
return null;
|
||||
}
|
||||
const items = display.instructionContext(
|
||||
obj,
|
||||
symbol,
|
||||
data.row,
|
||||
itemData.config,
|
||||
);
|
||||
return renderContextItems(items, close);
|
||||
}}
|
||||
>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<FixedSizeList
|
||||
height={height}
|
||||
itemCount={itemData.itemCount}
|
||||
itemSize={itemSize}
|
||||
width={width}
|
||||
itemData={itemData}
|
||||
overscanCount={20}
|
||||
onScroll={(e) => {
|
||||
setSymbolScrollOffset(
|
||||
currentUnitName,
|
||||
itemData.symbolName,
|
||||
e.scrollOffset,
|
||||
);
|
||||
}}
|
||||
initialScrollOffset={initialScrollOffset}
|
||||
>
|
||||
{AsmRow}
|
||||
</FixedSizeList>
|
||||
)}
|
||||
</AutoSizer>
|
||||
</ContextMenuProvider>
|
||||
</div>
|
||||
<TooltipShared
|
||||
id="instruction-tooltip"
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
areEqual,
|
||||
} from 'react-window';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { createContextMenu, renderContextItems } from '../common/ContextMenu';
|
||||
import TooltipShared from '../common/TooltipShared';
|
||||
import {
|
||||
type UnitScrollOffsets,
|
||||
@@ -22,6 +23,14 @@ import {
|
||||
} from '../state';
|
||||
import { percentClass, useFontSize } from '../util/util';
|
||||
|
||||
type SymbolTooltipContent = {
|
||||
symbolRef: display.SectionDisplaySymbol;
|
||||
side: keyof UnitScrollOffsets;
|
||||
};
|
||||
|
||||
const { ContextMenuProvider, useContextMenu } =
|
||||
createContextMenu<SymbolTooltipContent>();
|
||||
|
||||
const SectionRow = ({
|
||||
section,
|
||||
style,
|
||||
@@ -70,6 +79,7 @@ const SymbolRow = ({
|
||||
style?: React.CSSProperties;
|
||||
}) => {
|
||||
const setSelectedSymbol = useAppStore((state) => state.setSelectedSymbol);
|
||||
const onContextMenu = useContextMenu();
|
||||
const symbol = display.displaySymbol(obj, symbolRef);
|
||||
const flags = [];
|
||||
if (symbol.flags.global) {
|
||||
@@ -136,14 +146,11 @@ const SymbolRow = ({
|
||||
},
|
||||
);
|
||||
}}
|
||||
data-vscode-context={JSON.stringify({
|
||||
contextType: 'symbol',
|
||||
preventDefaultContextMenuItems: true,
|
||||
symbolName: symbol.name,
|
||||
symbolDemangledName: symbol.demangledName,
|
||||
})}
|
||||
data-tooltip-id="symbol-tooltip"
|
||||
data-tooltip-content={JSON.stringify(tooltipContent)}
|
||||
onContextMenu={(e) => {
|
||||
onContextMenu(e, tooltipContent);
|
||||
}}
|
||||
>
|
||||
{flagsElem}
|
||||
{percentElem}
|
||||
@@ -154,11 +161,6 @@ const SymbolRow = ({
|
||||
);
|
||||
};
|
||||
|
||||
type SymbolTooltipContent = {
|
||||
symbolRef: display.SectionDisplaySymbol;
|
||||
side: keyof UnitScrollOffsets;
|
||||
};
|
||||
|
||||
type SectionData = display.SectionDisplay & { collapsed: boolean };
|
||||
|
||||
type ItemData = {
|
||||
@@ -434,14 +436,35 @@ const SymbolsView = ({ diff }: { diff: diff.DiffResult }) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.symbols}>
|
||||
<AutoSizer className={styles.symbols}>
|
||||
{({ height, width }) => (
|
||||
<>
|
||||
{renderList(height, width, leftItemData, 'left')}
|
||||
{renderList(height, width, rightItemData, 'right')}
|
||||
</>
|
||||
)}
|
||||
</AutoSizer>
|
||||
<ContextMenuProvider
|
||||
render={({ data }, close) => {
|
||||
let obj: diff.ObjectDiff | undefined;
|
||||
switch (data.side) {
|
||||
case 'left':
|
||||
obj = diff.left;
|
||||
break;
|
||||
case 'right':
|
||||
obj = diff.right;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!obj) {
|
||||
return null;
|
||||
}
|
||||
const items = display.symbolContext(obj, data.symbolRef);
|
||||
return renderContextItems(items, close);
|
||||
}}
|
||||
>
|
||||
<AutoSizer className={styles.symbols}>
|
||||
{({ height, width }) => (
|
||||
<>
|
||||
{renderList(height, width, leftItemData, 'left')}
|
||||
{renderList(height, width, rightItemData, 'right')}
|
||||
</>
|
||||
)}
|
||||
</AutoSizer>
|
||||
</ContextMenuProvider>
|
||||
</div>
|
||||
<TooltipShared
|
||||
id="symbol-tooltip"
|
||||
|
||||
Reference in New Issue
Block a user