The header view is now completely working. The position control accepts

decimal, hexadecimal, and octal values (it is using strtoll(..., 0);)
Setting the number base type does now work, too.
Updated the Slider class to a PositionSlider class that creates the
illusion of supporting off_t values - almost (see note in Position()).


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6623 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-02-18 03:34:10 +00:00
parent e805d89711
commit 5475e6e54c
2 changed files with 264 additions and 25 deletions
+263 -25
View File
@@ -29,6 +29,10 @@
#include <stdio.h> #include <stdio.h>
static const uint32 kMsgSliderUpdate = 'slup';
static const uint32 kMsgPositionUpdate = 'poup';
class IconView : public BView { class IconView : public BView {
public: public:
IconView(BRect frame, entry_ref *ref, bool isDevice); IconView(BRect frame, entry_ref *ref, bool isDevice);
@@ -46,33 +50,62 @@ class IconView : public BView {
}; };
class Slider : public BSlider { class PositionSlider : public BSlider {
public: public:
Slider(BRect rect, const char *name); PositionSlider(BRect rect, const char *name, BMessage *message,
virtual ~Slider(); off_t size, uint32 blockSize);
virtual ~PositionSlider();
virtual void DrawBar(); virtual void DrawBar();
off_t Position() const;
off_t Size() const { return fSize; }
uint32 BlockSize() const { return fBlockSize; }
void SetPosition(off_t position);
void SetSize(off_t size);
void SetBlockSize(uint32 blockSize);
private:
void Reset();
static const int32 kMaxSliderLimit = 0x7fffff80;
// this is the maximum value that BSlider seem to work with fine
off_t fSize;
uint32 fBlockSize;
}; };
class HeaderView : public BView { class HeaderView : public BView, public BInvoker {
public: public:
HeaderView(BRect frame, entry_ref *ref, bool isDevice, const char *attribute = NULL); HeaderView(BRect frame, entry_ref *ref, DataEditor &editor);
virtual ~HeaderView(); virtual ~HeaderView();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
virtual void GetPreferredSize(float *_width, float *_height); virtual void GetPreferredSize(float *_width, float *_height);
virtual void MessageReceived(BMessage *message);
base_type Base() const { return fBase; }
void SetBase(base_type);
private: private:
void FormatValue(char *buffer, size_t bufferSize, off_t value);
void UpdatePositionViews(off_t position);
void UpdateFileSizeView();
const char *fAttribute; const char *fAttribute;
off_t fFileSize;
uint32 fBlockSize;
base_type fBase;
BTextControl *fPositionControl; BTextControl *fPositionControl;
BStringView *fPathView; BStringView *fPathView;
BStringView *fSizeView; BStringView *fSizeView;
BStringView *fOffsetView; BStringView *fOffsetView;
BStringView *fFileOffsetView; BStringView *fFileOffsetView;
BSlider *fPositionSlider; PositionSlider *fPositionSlider;
IconView *fIconView; IconView *fIconView;
}; };
@@ -147,20 +180,24 @@ IconView::UpdateIcon()
// #pragma mark - // #pragma mark -
Slider::Slider(BRect rect, const char *name) PositionSlider::PositionSlider(BRect rect, const char *name, BMessage *message,
: BSlider(rect, name, NULL, NULL, 0, 0x10000000, B_HORIZONTAL, off_t size, uint32 blockSize)
B_TRIANGLE_THUMB, B_FOLLOW_LEFT_RIGHT) : BSlider(rect, name, NULL, message, 0, kMaxSliderLimit, B_HORIZONTAL,
B_TRIANGLE_THUMB, B_FOLLOW_LEFT_RIGHT),
fSize(size),
fBlockSize(blockSize)
{ {
Reset();
} }
Slider::~Slider() PositionSlider::~PositionSlider()
{ {
} }
void void
Slider::DrawBar() PositionSlider::DrawBar()
{ {
BView *view = OffscreenView(); BView *view = OffscreenView();
@@ -209,16 +246,75 @@ Slider::DrawBar()
} }
void
PositionSlider::Reset()
{
SetKeyIncrementValue(int32(1.0 * kMaxSliderLimit / (fSize / fBlockSize) + 0.5));
}
off_t
PositionSlider::Position() const
{
// ToDo:
// Note: this code is far from being perfect: depending on the file size, it has
// a maxium granularity that might be less than the actual block size demands...
// The only way to work around this that I can think of, is to replace the slider
// class completely with one that understands off_t values.
// For example, with a block size of 512 bytes, it should be good enough for about
// 1024 GB - and that's not really that far away these days.
return (off_t(1.0 * fSize * Value() / kMaxSliderLimit + 0.5) / fBlockSize) * fBlockSize;
}
void
PositionSlider::SetPosition(off_t position)
{
position /= fBlockSize;
SetValue(int32(1.0 * kMaxSliderLimit * position / (fSize / fBlockSize) + 0.5));
}
void
PositionSlider::SetSize(off_t size)
{
if (size == fSize)
return;
off_t position = Position();
fSize = size;
Reset();
SetPosition(position);
}
void
PositionSlider::SetBlockSize(uint32 blockSize)
{
if (blockSize == fBlockSize)
return;
off_t position = Position();
fBlockSize = blockSize;
Reset();
SetPosition(position);
}
// #pragma mark - // #pragma mark -
HeaderView::HeaderView(BRect frame, entry_ref *ref, bool isDevice, const char *attribute) HeaderView::HeaderView(BRect frame, entry_ref *ref, DataEditor &editor)
: BView(frame, "probeHeader", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW), : BView(frame, "probeHeader", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW),
fAttribute(attribute) fAttribute(editor.Attribute()),
fFileSize(editor.FileSize()),
fBlockSize(editor.BlockSize()),
fBase(kHexBase)
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fIconView = new IconView(BRect(10, 10, 41, 41), ref, isDevice); fIconView = new IconView(BRect(10, 10, 41, 41), ref, editor.IsDevice());
AddChild(fIconView); AddChild(fIconView);
BFont boldFont = *be_bold_font; BFont boldFont = *be_bold_font;
@@ -227,16 +323,16 @@ HeaderView::HeaderView(BRect frame, entry_ref *ref, bool isDevice, const char *a
plainFont.SetSize(10.0); plainFont.SetSize(10.0);
BStringView *stringView = new BStringView(BRect(50, 6, frame.right, 20), BStringView *stringView = new BStringView(BRect(50, 6, frame.right, 20),
B_EMPTY_STRING, attribute != NULL ? "Attribute: " : isDevice ? "Device: " : "File: "); B_EMPTY_STRING, editor.IsAttribute() ? "Attribute: " : editor.IsDevice() ? "Device: " : "File: ");
stringView->SetFont(&boldFont); stringView->SetFont(&boldFont);
stringView->ResizeToPreferred(); stringView->ResizeToPreferred();
AddChild(stringView); AddChild(stringView);
BPath path(ref); BPath path(ref);
BString string = path.Path(); BString string = path.Path();
if (attribute != NULL) { if (fAttribute != NULL) {
string.Prepend(" ("); string.Prepend(" (");
string.Prepend(attribute); string.Prepend(fAttribute);
string.Append(")"); string.Append(")");
} }
BRect rect = stringView->Frame(); BRect rect = stringView->Frame();
@@ -256,7 +352,7 @@ HeaderView::HeaderView(BRect frame, entry_ref *ref, bool isDevice, const char *a
rect.right += 75; rect.right += 75;
rect.OffsetBy(0, -2); rect.OffsetBy(0, -2);
// BTextControl oddities // BTextControl oddities
fPositionControl = new BTextControl(rect, B_EMPTY_STRING, NULL, "0x0", NULL); fPositionControl = new BTextControl(rect, B_EMPTY_STRING, NULL, "0x0", new BMessage(kMsgPositionUpdate));
fPositionControl->SetDivider(0.0); fPositionControl->SetDivider(0.0);
fPositionControl->SetFont(&plainFont); fPositionControl->SetFont(&plainFont);
fPositionControl->TextView()->SetFontAndColor(&plainFont); fPositionControl->TextView()->SetFontAndColor(&plainFont);
@@ -269,6 +365,7 @@ HeaderView::HeaderView(BRect frame, entry_ref *ref, bool isDevice, const char *a
fSizeView = new BStringView(rect, B_EMPTY_STRING, "of 0x0"); fSizeView = new BStringView(rect, B_EMPTY_STRING, "of 0x0");
fSizeView->SetFont(&plainFont); fSizeView->SetFont(&plainFont);
AddChild(fSizeView); AddChild(fSizeView);
UpdateFileSizeView();
rect.left = rect.right + 4; rect.left = rect.right + 4;
rect.right = frame.right; rect.right = frame.right;
@@ -287,7 +384,7 @@ HeaderView::HeaderView(BRect frame, entry_ref *ref, bool isDevice, const char *a
rect.left = rect.right + 4; rect.left = rect.right + 4;
rect.right = frame.right; rect.right = frame.right;
stringView = new BStringView(rect, B_EMPTY_STRING, stringView = new BStringView(rect, B_EMPTY_STRING,
attribute != NULL ? "Attribute Offset: " : isDevice ? "Device Offset: " : "File Offset: "); editor.IsAttribute() ? "Attribute Offset: " : editor.IsDevice() ? "Device Offset: " : "File Offset: ");
stringView->SetFont(&boldFont); stringView->SetFont(&boldFont);
stringView->ResizeToPreferred(); stringView->ResizeToPreferred();
AddChild(stringView); AddChild(stringView);
@@ -303,7 +400,9 @@ HeaderView::HeaderView(BRect frame, entry_ref *ref, bool isDevice, const char *a
rect.InsetBy(3, 0); rect.InsetBy(3, 0);
rect.top = 48; rect.top = 48;
rect.bottom = 60; rect.bottom = 60;
fPositionSlider = new Slider(rect, "slider"); fPositionSlider = new PositionSlider(rect, "slider", new BMessage(kMsgSliderUpdate),
editor.FileSize(), editor.BlockSize());
fPositionSlider->SetModificationMessage(new BMessage(kMsgSliderUpdate));
fPositionSlider->SetBarThickness(8); fPositionSlider->SetBarThickness(8);
fPositionSlider->ResizeToPreferred(); fPositionSlider->ResizeToPreferred();
AddChild(fPositionSlider); AddChild(fPositionSlider);
@@ -318,6 +417,10 @@ HeaderView::~HeaderView()
void void
HeaderView::AttachedToWindow() HeaderView::AttachedToWindow()
{ {
SetTarget(Window());
fPositionControl->SetTarget(this);
fPositionSlider->SetTarget(this);
} }
@@ -344,6 +447,96 @@ HeaderView::GetPreferredSize(float *_width, float *_height)
} }
void
HeaderView::FormatValue(char *buffer, size_t bufferSize, off_t value)
{
snprintf(buffer, bufferSize, fBase == kHexBase ? "0x%Lx" : "%Ld", value);
}
void
HeaderView::UpdatePositionViews(off_t position)
{
char buffer[64];
FormatValue(buffer, sizeof(buffer), position / fBlockSize);
fPositionControl->SetText(buffer);
FormatValue(buffer, sizeof(buffer), position);
fFileOffsetView->SetText(buffer);
}
void
HeaderView::UpdateFileSizeView()
{
char buffer[64];
strcpy(buffer, "of ");
FormatValue(buffer + 3, sizeof(buffer) - 3, fFileSize / fBlockSize);
fSizeView->SetText(buffer);
}
void
HeaderView::SetBase(base_type type)
{
if (fBase == type)
return;
fBase = type;
UpdatePositionViews(fPositionSlider->Position());
UpdateFileSizeView();
}
void
HeaderView::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgSliderUpdate:
{
off_t position = fPositionSlider->Position();
// update position text control
UpdatePositionViews(position);
// notify our target
BMessage update(kMsgPositionUpdate);
update.AddInt64("position", position);
Messenger().SendMessage(&update);
break;
}
case kMsgPositionUpdate:
{
off_t position = strtoll(fPositionControl->Text(), NULL, 0) * fBlockSize;
// update views
UpdatePositionViews(position);
fPositionSlider->SetPosition(position);
// notify our target
BMessage update(kMsgPositionUpdate);
update.AddInt64("position", position);
Messenger().SendMessage(&update);
break;
}
case kMsgBaseType:
{
int32 type;
if (message->FindInt32("base", &type) != B_OK)
break;
SetBase((base_type)type);
break;
}
default:
BView::MessageReceived(message);
}
}
// #pragma mark - // #pragma mark -
@@ -353,7 +546,7 @@ ProbeView::ProbeView(BRect rect, entry_ref *ref, const char *attribute)
fEditor.SetTo(*ref, attribute); fEditor.SetTo(*ref, attribute);
rect = Bounds(); rect = Bounds();
fHeaderView = new HeaderView(rect, ref, fEditor.IsDevice(), fEditor.Attribute()); fHeaderView = new HeaderView(rect, ref, fEditor);
fHeaderView->ResizeToPreferred(); fHeaderView->ResizeToPreferred();
AddChild(fHeaderView); AddChild(fHeaderView);
@@ -460,17 +653,37 @@ ProbeView::AttachedToWindow()
menu->AddItem(new BMenuItem(subMenu)); menu->AddItem(new BMenuItem(subMenu));
bar->AddItem(menu); bar->AddItem(menu);
// Number Base (hex/decimal)
menu = new BMenu("View"); menu = new BMenu("View");
subMenu = new BMenu("Base"); subMenu = new BMenu("Base");
subMenu->AddItem(new BMenuItem("Decimal", NULL, 'D', B_COMMAND_KEY)); BMenuItem *item;
subMenu->AddItem(new BMenuItem("Hex", NULL, 'H', B_COMMAND_KEY)); BMessage *message = new BMessage(kMsgBaseType);
message->AddInt32("base", kDecimalBase);
subMenu->AddItem(item = new BMenuItem("Decimal", message, 'D', B_COMMAND_KEY));
item->SetTarget(this);
if (fHeaderView->Base() == kDecimalBase)
item->SetMarked(true);
message = new BMessage(kMsgBaseType);
message->AddInt32("base", kHexBase);
subMenu->AddItem(item = new BMenuItem("Hex", message, 'H', B_COMMAND_KEY));
item->SetTarget(this);
if (fHeaderView->Base() == kHexBase)
item->SetMarked(true);
subMenu->SetRadioMode(true);
menu->AddItem(new BMenuItem(subMenu)); menu->AddItem(new BMenuItem(subMenu));
// Block Size
subMenu = new BMenu("BlockSize"); subMenu = new BMenu("BlockSize");
subMenu->AddItem(new BMenuItem("512", NULL)); subMenu->AddItem(new BMenuItem("512", NULL));
menu->AddItem(new BMenuItem(subMenu)); menu->AddItem(new BMenuItem(subMenu));
menu->AddSeparatorItem(); menu->AddSeparatorItem();
// Font Size
subMenu = new BMenu("Font Size"); subMenu = new BMenu("Font Size");
const int32 fontSizes[] = {9, 10, 12, 14, 18, 24, 36, 48}; const int32 fontSizes[] = {9, 10, 12, 14, 18, 24, 36, 48};
for (uint32 i = 0; i < sizeof(fontSizes) / sizeof(fontSizes[0]); i++) { for (uint32 i = 0; i < sizeof(fontSizes) / sizeof(fontSizes[0]); i++) {
@@ -487,8 +700,33 @@ ProbeView::AttachedToWindow()
void void
ProbeView::MessageReceived(BMessage *message) ProbeView::AllAttached()
{ {
BView::MessageReceived(message); fHeaderView->SetTarget(this);
}
void
ProbeView::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgBaseType:
{
int32 type;
if (message->FindInt32("base", &type) != B_OK)
break;
fHeaderView->SetBase((base_type)type);
fDataView->SetBase((base_type)type);
break;
}
case kMsgPositionUpdate:
// ToDo: update data
break;
default:
BView::MessageReceived(message);
}
} }
+1
View File
@@ -26,6 +26,7 @@ class ProbeView : public BView {
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void AllAttached();
virtual void MessageReceived(BMessage *message); virtual void MessageReceived(BMessage *message);
void AddFileMenuItems(BMenu *menu, int32 index); void AddFileMenuItems(BMenu *menu, int32 index);