Debugger: Add selection support to MemoryView.
- The Inspector's memory view now supports selecting chunks of the hex display in the manner one would in a TextView. The selection can also be copied to the clipboard, or if it matches the size of a target address, can be used as input for an address to inspect directly. Still needs some fine tuning, but basically works.
This commit is contained in:
parent
29fdf5e8ae
commit
6c5893fbbf
@ -11,20 +11,30 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <Clipboard.h>
|
||||
#include <Looper.h>
|
||||
#include <MenuItem.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <Messenger.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <Region.h>
|
||||
#include <ScrollView.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "Architecture.h"
|
||||
#include "AutoDeleter.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "Team.h"
|
||||
#include "TeamMemoryBlock.h"
|
||||
|
||||
|
||||
enum {
|
||||
MSG_TARGET_ADDRESS_CHANGED = 'mtac'
|
||||
MSG_TARGET_ADDRESS_CHANGED = 'mtac',
|
||||
MSG_VIEW_AUTOSCROLL = 'mvas'
|
||||
};
|
||||
|
||||
static const bigtime_t kScrollTimer = 10000LL;
|
||||
|
||||
|
||||
MemoryView::MemoryView(::Team* team, Listener* listener)
|
||||
:
|
||||
@ -39,6 +49,10 @@ MemoryView::MemoryView(::Team* team, Listener* listener)
|
||||
fHexBlocksPerLine(0),
|
||||
fHexMode(HexMode8BitInt),
|
||||
fTextMode(TextModeASCII),
|
||||
fSelectionBase(0),
|
||||
fSelectionStart(0),
|
||||
fSelectionEnd(0),
|
||||
fScrollRunner(NULL),
|
||||
fListener(listener)
|
||||
{
|
||||
Architecture* architecture = team->GetArchitecture();
|
||||
@ -76,11 +90,14 @@ void
|
||||
MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address)
|
||||
{
|
||||
fTargetAddress = address;
|
||||
if (fTargetBlock != NULL)
|
||||
if (block != fTargetBlock && fTargetBlock != NULL)
|
||||
fTargetBlock->ReleaseReference();
|
||||
|
||||
fTargetBlock = block;
|
||||
fTargetBlock->AcquireReference();
|
||||
if (block != fTargetBlock) {
|
||||
fTargetBlock = block;
|
||||
fTargetBlock->AcquireReference();
|
||||
}
|
||||
|
||||
MakeFocus(true);
|
||||
BMessenger(this).SendMessage(MSG_TARGET_ADDRESS_CHANGED);
|
||||
}
|
||||
@ -119,7 +136,7 @@ MemoryView::Draw(BRect rect)
|
||||
if (fTargetBlock == NULL)
|
||||
return;
|
||||
|
||||
uint32 hexBlockSize = (1 << fHexMode) + 1;
|
||||
uint32 hexBlockSize = _GetHexDigitsPerBlock() + 1;
|
||||
uint32 blockByteSize = hexBlockSize / 2;
|
||||
if (fHexMode != HexModeNone && fTextMode != TextModeNone) {
|
||||
divider += (fHexBlocksPerLine * hexBlockSize + 1) * fCharWidth;
|
||||
@ -156,7 +173,6 @@ MemoryView::Draw(BRect rect)
|
||||
DrawString(buffer, drawPoint);
|
||||
drawPoint.x += fCharWidth * (fTargetAddressSize + 2);
|
||||
PopState();
|
||||
|
||||
if (fHexMode != HexModeNone) {
|
||||
if (currentAddress + (currentBlocksPerLine * blockByteSize)
|
||||
> maxAddress) {
|
||||
@ -190,6 +206,7 @@ MemoryView::Draw(BRect rect)
|
||||
drawPoint.x += fCharWidth * hexBlockSize
|
||||
* (fHexBlocksPerLine - currentBlocksPerLine);
|
||||
}
|
||||
|
||||
if (fTextMode != TextModeNone) {
|
||||
drawPoint.x += fCharWidth;
|
||||
for (int32 j = 0; j < currentCharsPerLine; j++) {
|
||||
@ -226,6 +243,15 @@ MemoryView::Draw(BRect rect)
|
||||
lineAddress += fTextCharsPerLine;
|
||||
}
|
||||
}
|
||||
|
||||
if (fSelectionStart != fSelectionEnd) {
|
||||
PushState();
|
||||
BRegion selectionRegion;
|
||||
_GetSelectionRegion(selectionRegion);
|
||||
SetDrawingMode(B_OP_INVERT);
|
||||
FillRegion(&selectionRegion, B_SOLID_HIGH);
|
||||
PopState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -332,6 +358,11 @@ void
|
||||
MemoryView::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch(message->what) {
|
||||
case B_COPY:
|
||||
{
|
||||
_CopySelectionToClipboard();
|
||||
break;
|
||||
}
|
||||
case MSG_TARGET_ADDRESS_CHANGED:
|
||||
{
|
||||
_RecalcScrollBars();
|
||||
@ -370,6 +401,11 @@ MemoryView::MessageReceived(BMessage* message)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSG_VIEW_AUTOSCROLL:
|
||||
{
|
||||
_HandleAutoScroll();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
BView::MessageReceived(message);
|
||||
@ -385,7 +421,78 @@ MemoryView::MouseDown(BPoint point)
|
||||
if (!IsFocus())
|
||||
MakeFocus(true);
|
||||
|
||||
BView::MouseDown(point);
|
||||
if (fTargetBlock == NULL)
|
||||
return;
|
||||
|
||||
int32 buttons;
|
||||
if (Looper()->CurrentMessage()->FindInt32("buttons", &buttons) != B_OK)
|
||||
buttons = B_PRIMARY_MOUSE_BUTTON;
|
||||
|
||||
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
||||
_HandleContextMenu(point);
|
||||
return;
|
||||
}
|
||||
|
||||
int32 offset = _GetOffsetAt(point);
|
||||
if (offset < fSelectionStart || offset > fSelectionEnd) {
|
||||
BRegion oldSelectionRegion;
|
||||
_GetSelectionRegion(oldSelectionRegion);
|
||||
fSelectionBase = offset;
|
||||
fSelectionStart = fSelectionBase;
|
||||
fSelectionEnd = fSelectionBase;
|
||||
Invalidate(oldSelectionRegion.Frame());
|
||||
}
|
||||
|
||||
SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
|
||||
fTrackingMouse = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::MouseMoved(BPoint point, uint32 transit, const BMessage* message)
|
||||
{
|
||||
if (!fTrackingMouse)
|
||||
return;
|
||||
|
||||
BRegion oldSelectionRegion;
|
||||
_GetSelectionRegion(oldSelectionRegion);
|
||||
int32 offset = _GetOffsetAt(point);
|
||||
if (offset < fSelectionBase) {
|
||||
fSelectionStart = offset;
|
||||
fSelectionEnd = fSelectionBase;
|
||||
} else {
|
||||
fSelectionStart = fSelectionBase;
|
||||
fSelectionEnd = offset;
|
||||
}
|
||||
|
||||
BRegion region;
|
||||
_GetSelectionRegion(region);
|
||||
region.Include(&oldSelectionRegion);
|
||||
Invalidate(region.Frame());
|
||||
|
||||
switch (transit) {
|
||||
case B_EXITED_VIEW:
|
||||
fScrollRunner = new BMessageRunner(BMessenger(this),
|
||||
new BMessage(MSG_VIEW_AUTOSCROLL), kScrollTimer);
|
||||
break;
|
||||
|
||||
case B_ENTERED_VIEW:
|
||||
delete fScrollRunner;
|
||||
fScrollRunner = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::MouseUp(BPoint point)
|
||||
{
|
||||
fTrackingMouse = false;
|
||||
delete fScrollRunner;
|
||||
fScrollRunner = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -395,10 +502,12 @@ MemoryView::ScrollToSelection()
|
||||
if (fTargetBlock != NULL) {
|
||||
target_addr_t offset = fTargetAddress - fTargetBlock->BaseAddress();
|
||||
int32 lineNumber = 0;
|
||||
if (fHexBlocksPerLine > 0)
|
||||
lineNumber = offset / (fHexBlocksPerLine * (1 << (fHexMode - 1)));
|
||||
else if (fTextCharsPerLine > 0)
|
||||
if (fHexBlocksPerLine > 0) {
|
||||
lineNumber = offset / (fHexBlocksPerLine
|
||||
* (_GetHexDigitsPerBlock() / 2));
|
||||
} else if (fTextCharsPerLine > 0)
|
||||
lineNumber = offset / fTextCharsPerLine;
|
||||
|
||||
float y = lineNumber * fLineHeight;
|
||||
if (y < Bounds().top)
|
||||
ScrollTo(0.0, y);
|
||||
@ -429,40 +538,23 @@ MemoryView::_RecalcScrollBars()
|
||||
float max = 0.0;
|
||||
BScrollBar *scrollBar = ScrollBar(B_VERTICAL);
|
||||
if (fTargetBlock != NULL) {
|
||||
BRect bounds = Bounds();
|
||||
// the left portion of the view is off limits since it
|
||||
// houses the address offset of the current line
|
||||
float baseWidth = bounds.Width() - ((fTargetAddressSize + 2)
|
||||
* fCharWidth);
|
||||
float hexWidth = 0.0;
|
||||
float textWidth = 0.0;
|
||||
int32 hexDigits = 1 << fHexMode;
|
||||
int32 hexDigits = _GetHexDigitsPerBlock();
|
||||
int32 sizeFactor = 1 + hexDigits;
|
||||
if (fHexMode != HexModeNone) {
|
||||
if (fTextMode != TextModeNone) {
|
||||
float hexProportion = sizeFactor / (float)(sizeFactor
|
||||
+ hexDigits / 2);
|
||||
hexWidth = baseWidth * hexProportion;
|
||||
// when sharing the display between hex and text,
|
||||
// we allocate a 2 character space to separate the views
|
||||
hexWidth -= 2 * fCharWidth;
|
||||
textWidth = baseWidth - hexWidth;
|
||||
} else
|
||||
hexWidth = baseWidth;
|
||||
} else if (fTextMode != TextModeNone)
|
||||
textWidth = baseWidth;
|
||||
_RecalcBounds();
|
||||
|
||||
float hexWidth = fHexRight - fHexLeft;
|
||||
int32 nybblesPerLine = int32(hexWidth / fCharWidth);
|
||||
fHexBlocksPerLine = 0;
|
||||
fTextCharsPerLine = 0;
|
||||
if (fHexMode != HexModeNone) {
|
||||
fHexBlocksPerLine = nybblesPerLine / sizeFactor;
|
||||
fHexBlocksPerLine &= ~1;
|
||||
fHexRight = fHexLeft + (fHexBlocksPerLine * sizeFactor
|
||||
* fCharWidth);
|
||||
if (fTextMode != TextModeNone)
|
||||
fTextCharsPerLine = fHexBlocksPerLine * hexDigits / 2;
|
||||
} else if (fTextMode != TextModeNone)
|
||||
fTextCharsPerLine = int32(textWidth / fCharWidth);
|
||||
|
||||
fTextCharsPerLine = int32((fTextRight - fTextLeft) / fCharWidth);
|
||||
int32 lineCount = 0;
|
||||
float totalHeight = 0.0;
|
||||
if (fHexBlocksPerLine > 0) {
|
||||
@ -473,6 +565,7 @@ MemoryView::_RecalcScrollBars()
|
||||
|
||||
totalHeight = lineCount * fLineHeight;
|
||||
if (totalHeight > 0.0) {
|
||||
BRect bounds = Bounds();
|
||||
max = totalHeight - bounds.Height();
|
||||
scrollBar->SetProportion(bounds.Height() / totalHeight);
|
||||
scrollBar->SetSteps(fLineHeight, bounds.Height());
|
||||
@ -558,6 +651,290 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize,
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
MemoryView::_GetOffsetAt(BPoint point) const
|
||||
{
|
||||
if (fTargetBlock == NULL)
|
||||
return -1;
|
||||
|
||||
// TODO: support selection in the text region as well
|
||||
if (fHexMode == HexModeNone)
|
||||
return -1;
|
||||
|
||||
int32 lineNumber = point.y / fLineHeight;
|
||||
int32 charsPerBlock = _GetHexDigitsPerBlock() / 2;
|
||||
int32 totalHexBlocks = fTargetBlock->Size() / charsPerBlock;
|
||||
int32 lineCount = totalHexBlocks / fHexBlocksPerLine;
|
||||
|
||||
if (lineNumber >= lineCount)
|
||||
return -1;
|
||||
|
||||
point.x -= fHexLeft;
|
||||
if (point.x < 0)
|
||||
point.x = 0;
|
||||
else if (point.x > fHexRight)
|
||||
point.x = fHexRight;
|
||||
|
||||
float blockWidth = (charsPerBlock * 2 + 1) * fCharWidth;
|
||||
int32 containingBlock = int32(floor(point.x / blockWidth));
|
||||
|
||||
return fHexBlocksPerLine * lineNumber
|
||||
+ containingBlock * charsPerBlock;
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
MemoryView::_GetPointForOffset(int32 offset) const
|
||||
{
|
||||
BPoint point;
|
||||
int32 bytesPerLine = fHexBlocksPerLine * _GetHexDigitsPerBlock() / 2;
|
||||
int32 line = offset / bytesPerLine;
|
||||
int32 lineOffset = offset % bytesPerLine;
|
||||
|
||||
point.x = fHexLeft + (lineOffset * 2 * fCharWidth)
|
||||
+ (lineOffset * 2 * fCharWidth / _GetHexDigitsPerBlock());
|
||||
point.y = line * fLineHeight;
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_RecalcBounds()
|
||||
{
|
||||
fHexLeft = 0;
|
||||
fHexRight = 0;
|
||||
fTextLeft = 0;
|
||||
fTextRight = 0;
|
||||
|
||||
// the left bound is determined by the space taken up by the actual
|
||||
// displayed addresses.
|
||||
float left = _GetAddressDisplayWidth();
|
||||
float width = Bounds().Width() - left;
|
||||
|
||||
if (fHexMode != HexModeNone) {
|
||||
int32 hexDigits = _GetHexDigitsPerBlock();
|
||||
int32 sizeFactor = 1 + hexDigits;
|
||||
if (fTextMode != TextModeNone) {
|
||||
float hexProportion = sizeFactor / (float)(sizeFactor
|
||||
+ hexDigits / 2);
|
||||
float hexWidth = width * hexProportion;
|
||||
fTextLeft = left + hexWidth;
|
||||
fHexLeft = left;
|
||||
// when sharing the display between hex and text,
|
||||
// we allocate a 2 character space to separate the views
|
||||
hexWidth -= 2 * fCharWidth;
|
||||
fHexRight = left + hexWidth;
|
||||
} else {
|
||||
fHexLeft = left;
|
||||
fHexRight = left + width;
|
||||
}
|
||||
} else if (fTextMode != TextModeNone) {
|
||||
fTextLeft = left;
|
||||
fTextRight = left + width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
MemoryView::_GetAddressDisplayWidth() const
|
||||
{
|
||||
return (fTargetAddressSize + 2) * fCharWidth;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_GetSelectionRegion(BRegion& region)
|
||||
{
|
||||
region.MakeEmpty();
|
||||
BPoint startPoint = _GetPointForOffset(fSelectionStart);
|
||||
BPoint endPoint = _GetPointForOffset(fSelectionEnd);
|
||||
|
||||
BRect rect;
|
||||
if (startPoint.y == endPoint.y) {
|
||||
// single line case
|
||||
rect.left = startPoint.x;
|
||||
rect.top = startPoint.y;
|
||||
rect.right = endPoint.x;
|
||||
rect.bottom = endPoint.y + fLineHeight;
|
||||
region.Include(rect);
|
||||
} else {
|
||||
float currentLine = startPoint.y;
|
||||
|
||||
// first line
|
||||
rect.left = startPoint.x;
|
||||
rect.top = startPoint.y;
|
||||
rect.right = fHexRight;
|
||||
rect.bottom = startPoint.y + fLineHeight;
|
||||
region.Include(rect);
|
||||
currentLine += fLineHeight;
|
||||
|
||||
// middle region
|
||||
if (currentLine < endPoint.y) {
|
||||
rect.left = fHexLeft;
|
||||
rect.top = currentLine;
|
||||
rect.right = fHexRight;
|
||||
rect.bottom = endPoint.y;
|
||||
region.Include(rect);
|
||||
}
|
||||
|
||||
rect.left = fHexLeft;
|
||||
rect.top = endPoint.y;
|
||||
rect.right = endPoint.x;
|
||||
rect.bottom = endPoint.y + fLineHeight;
|
||||
region.Include(rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_GetSelectedText(BString& text)
|
||||
{
|
||||
if (fSelectionStart == fSelectionEnd)
|
||||
return;
|
||||
|
||||
text.Truncate(0);
|
||||
|
||||
char* data = (char *)fTargetBlock->Data() + fSelectionStart;
|
||||
int16 blockSize = _GetHexDigitsPerBlock() / 2;
|
||||
int32 count = (fSelectionEnd - fSelectionStart)
|
||||
/ blockSize;
|
||||
|
||||
char buffer[32];
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
_GetNextHexBlock(buffer, sizeof(buffer), data);
|
||||
data += blockSize;
|
||||
text << buffer;
|
||||
if (i < count - 1)
|
||||
text << " ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_CopySelectionToClipboard()
|
||||
{
|
||||
BString text;
|
||||
_GetSelectedText(text);
|
||||
|
||||
if (text.Length() > 0) {
|
||||
be_clipboard->Lock();
|
||||
be_clipboard->Data()->RemoveData("text/plain");
|
||||
be_clipboard->Data()->AddData ("text/plain",
|
||||
B_MIME_TYPE, text.String(), text.Length());
|
||||
be_clipboard->Commit();
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_HandleAutoScroll()
|
||||
{
|
||||
BPoint point;
|
||||
uint32 buttons;
|
||||
GetMouse(&point, &buttons);
|
||||
float difference = 0.0;
|
||||
int factor = 0;
|
||||
BRect visibleRect = Bounds();
|
||||
if (point.y < visibleRect.top)
|
||||
difference = point.y - visibleRect.top;
|
||||
else if (point.y > visibleRect.bottom)
|
||||
difference = point.y - visibleRect.bottom;
|
||||
if (difference != 0.0) {
|
||||
factor = (int)(ceilf(difference / fLineHeight));
|
||||
_ScrollByLines(factor);
|
||||
}
|
||||
|
||||
MouseMoved(point, B_OUTSIDE_VIEW, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_ScrollByLines(int32 lineCount)
|
||||
{
|
||||
BScrollBar* vertical = ScrollBar(B_VERTICAL);
|
||||
if (vertical == NULL)
|
||||
return;
|
||||
|
||||
float value = vertical->Value();
|
||||
vertical->SetValue(value + fLineHeight * lineCount);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MemoryView::_HandleContextMenu(BPoint point)
|
||||
{
|
||||
int32 offset = _GetOffsetAt(point);
|
||||
if (offset < fSelectionStart || offset > fSelectionEnd)
|
||||
return;
|
||||
|
||||
BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("Options");
|
||||
if (menu == NULL)
|
||||
return;
|
||||
|
||||
ObjectDeleter<BPopUpMenu> menuDeleter(menu);
|
||||
ObjectDeleter<BMenuItem> itemDeleter;
|
||||
ObjectDeleter<BMessage> messageDeleter;
|
||||
BMessage* message = NULL;
|
||||
BMenuItem* item = NULL;
|
||||
if (fSelectionEnd - fSelectionStart == fTargetAddressSize / 2) {
|
||||
BMessage* message = new(std::nothrow) BMessage(MSG_INSPECT_ADDRESS);
|
||||
if (message == NULL)
|
||||
return;
|
||||
|
||||
target_addr_t address;
|
||||
if (fTargetAddressSize == 8)
|
||||
address = *((uint32*)(fTargetBlock->Data() + fSelectionStart));
|
||||
else
|
||||
address = *((uint64*)(fTargetBlock->Data() + fSelectionStart));
|
||||
|
||||
if (fEndianMode == EndianModeBigEndian)
|
||||
address = B_HOST_TO_BENDIAN_INT64(address);
|
||||
else
|
||||
address = B_HOST_TO_LENDIAN_INT64(address);
|
||||
|
||||
messageDeleter.SetTo(message);
|
||||
message->AddUInt64("address", address);
|
||||
BMenuItem* item = new(std::nothrow) BMenuItem("Inspect", message);
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
messageDeleter.Detach();
|
||||
itemDeleter.SetTo(item);
|
||||
if (!menu->AddItem(item))
|
||||
return;
|
||||
|
||||
item->SetTarget(Looper());
|
||||
itemDeleter.Detach();
|
||||
}
|
||||
|
||||
message = new(std::nothrow) BMessage(B_COPY);
|
||||
if (message == NULL)
|
||||
return;
|
||||
|
||||
messageDeleter.SetTo(message);
|
||||
item = new(std::nothrow) BMenuItem("Copy", message);
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
messageDeleter.Detach();
|
||||
itemDeleter.SetTo(item);
|
||||
if (!menu->AddItem(item))
|
||||
return;
|
||||
|
||||
item->SetTarget(this);
|
||||
itemDeleter.Detach();
|
||||
menuDeleter.Detach();
|
||||
|
||||
BPoint screenWhere(point);
|
||||
ConvertToScreen(&screenWhere);
|
||||
BRect mouseRect(screenWhere, screenWhere);
|
||||
mouseRect.InsetBy(-4.0, -4.0);
|
||||
menu->Go(screenWhere, true, false, mouseRect, true);
|
||||
}
|
||||
|
||||
|
||||
//#pragma mark - Listener
|
||||
|
||||
|
||||
|
@ -38,9 +38,9 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
class BMessageRunner;
|
||||
|
||||
class Team;
|
||||
|
||||
|
||||
class TeamMemoryBlock;
|
||||
|
||||
|
||||
@ -66,6 +66,9 @@ public:
|
||||
virtual void MakeFocus(bool isFocused);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void MouseDown(BPoint point);
|
||||
virtual void MouseMoved(BPoint point, uint32 transit,
|
||||
const BMessage* dragMessage);
|
||||
virtual void MouseUp(BPoint point);
|
||||
void ScrollToSelection();
|
||||
virtual void TargetedByScrollView(BScrollView* scrollView);
|
||||
|
||||
@ -75,6 +78,22 @@ private:
|
||||
void _GetNextHexBlock(char* buffer,
|
||||
int32 bufferSize, const char* address);
|
||||
|
||||
int32 _GetOffsetAt(BPoint point) const;
|
||||
BPoint _GetPointForOffset(int32 offset) const;
|
||||
void _RecalcBounds();
|
||||
float _GetAddressDisplayWidth() const;
|
||||
|
||||
inline int32 _GetHexDigitsPerBlock() const
|
||||
{ return 1 << fHexMode; };
|
||||
|
||||
void _GetSelectionRegion(BRegion& region);
|
||||
void _GetSelectedText(BString& text);
|
||||
void _CopySelectionToClipboard();
|
||||
|
||||
void _HandleAutoScroll();
|
||||
void _ScrollByLines(int32 lineCount);
|
||||
void _HandleContextMenu(BPoint point);
|
||||
|
||||
private:
|
||||
::Team* fTeam;
|
||||
TeamMemoryBlock* fTargetBlock;
|
||||
@ -87,6 +106,17 @@ private:
|
||||
int32 fCurrentEndianMode;
|
||||
int32 fHexMode;
|
||||
int32 fTextMode;
|
||||
float fHexLeft;
|
||||
float fHexRight;
|
||||
float fTextLeft;
|
||||
float fTextRight;
|
||||
int32 fSelectionBase;
|
||||
int32 fSelectionStart;
|
||||
int32 fSelectionEnd;
|
||||
BMessageRunner* fScrollRunner;
|
||||
|
||||
bool fTrackingMouse;
|
||||
|
||||
Listener* fListener;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user