* implemented detecting and displaying available space on devices and

partitions - I couldn't test it yet, but what is definitely missing
  is being able to select these spaces to create new partitions on them
* fixed the bug that if you select a partition on another disk, the
  disk view does not switch to the new disk. (I was comparing disk
  pointers, but since I deleted the old BDiskDevice instance first, the
  new one got assigned the same pointer... at least it appears I am not
  leaking memory anywhere... :-))


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23811 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-02-01 14:50:06 +00:00
parent 90e3bbf0cb
commit 56d794d68e
5 changed files with 101 additions and 35 deletions

View File

@ -11,6 +11,7 @@
#include <DiskDeviceVisitor.h> #include <DiskDeviceVisitor.h>
#include <GroupLayout.h> #include <GroupLayout.h>
#include <HashMap.h> #include <HashMap.h>
#include <PartitioningInfo.h>
#include <String.h> #include <String.h>
using BPrivate::HashMap; using BPrivate::HashMap;
@ -24,10 +25,13 @@ static const float kLayoutInset = 6;
class PartitionView : public BView { class PartitionView : public BView {
public: public:
PartitionView(const char* name, float weight, int32 level, partition_id id) PartitionView(const char* name, float weight, off_t offset,
int32 level, partition_id id)
: BView(name, B_WILL_DRAW | B_SUPPORTS_LAYOUT | B_FULL_UPDATE_ON_RESIZE) : BView(name, B_WILL_DRAW | B_SUPPORTS_LAYOUT | B_FULL_UPDATE_ON_RESIZE)
, fID(id) , fID(id)
, fWeight(weight) , fWeight(weight)
, fOffset(offset)
, fLevel(level)
, fSelected(false) , fSelected(false)
, fMouseOver(false) , fMouseOver(false)
, fGroupLayout(new BGroupLayout(B_HORIZONTAL, kLayoutInset)) , fGroupLayout(new BGroupLayout(B_HORIZONTAL, kLayoutInset))
@ -37,7 +41,7 @@ public:
SetViewColor(B_TRANSPARENT_COLOR); SetViewColor(B_TRANSPARENT_COLOR);
rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
base = tint_color(base, B_LIGHTEN_2_TINT); base = tint_color(base, B_LIGHTEN_2_TINT);
base = tint_color(base, 1 + 0.13 * level); base = tint_color(base, 1 + 0.13 * (level - 1));
SetLowColor(base); SetLowColor(base);
SetHighColor(tint_color(base, B_DARKEN_1_TINT)); SetHighColor(tint_color(base, B_DARKEN_1_TINT));
@ -84,11 +88,16 @@ public:
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
StrokeRect(b, B_SOLID_HIGH); StrokeRect(b, B_SOLID_HIGH);
b.InsetBy(1, 1); b.InsetBy(1, 1);
StrokeRect(b, B_SOLID_HIGH);
b.InsetBy(1, 1);
} else if (fLevel > 0) {
StrokeRect(b, B_SOLID_HIGH);
b.InsetBy(1, 1);
} }
StrokeRect(b, B_SOLID_HIGH);
b.InsetBy(1, 1);
FillRect(b, B_SOLID_LOW); FillRect(b, B_SOLID_LOW);
// prevent the text from moving when border width changes
if (!fSelected) if (!fSelected)
b.InsetBy(1, 1); b.InsetBy(1, 1);
@ -127,6 +136,16 @@ public:
return fWeight; return fWeight;
} }
off_t Offset() const
{
return fOffset;
}
int32 Level() const
{
return fLevel;
}
BGroupLayout* GroupLayout() const BGroupLayout* GroupLayout() const
{ {
return fGroupLayout; return fGroupLayout;
@ -153,6 +172,8 @@ private:
private: private:
partition_id fID; partition_id fID;
float fWeight; float fWeight;
off_t fOffset;
int32 fLevel;
bool fSelected; bool fSelected;
bool fMouseOver; bool fMouseOver;
BGroupLayout* fGroupLayout; BGroupLayout* fGroupLayout;
@ -170,20 +191,22 @@ public:
virtual bool Visit(BDiskDevice* device) virtual bool Visit(BDiskDevice* device)
{ {
PartitionView* view = new PartitionView("Device", 1.0, 0, device->ID()); PartitionView* view = new PartitionView("Device", 1.0,
device->Offset(), 0, device->ID());
fViewMap.Put(device->ID(), view); fViewMap.Put(device->ID(), view);
fView->GetLayout()->AddView(view); fView->GetLayout()->AddView(view);
_AddSpaces(device, view);
return false; return false;
} }
virtual bool Visit(BPartition* partition, int32 level) virtual bool Visit(BPartition* partition, int32 level)
{ {
if (!partition->Parent() || !fViewMap.ContainsKey(partition->Parent()->ID())) if (!partition->Parent()
|| !fViewMap.ContainsKey(partition->Parent()->ID()))
return false; return false;
// calculate size factor within parent frame // calculate size factor within parent frame
// TODO: support gaps view these offsets: off_t offset = partition->Offset();
// off_t offset = partition->Offset();
// off_t parentOffset = partition->Parent()->Offset(); // off_t parentOffset = partition->Parent()->Offset();
off_t size = partition->Size(); off_t size = partition->Size();
off_t parentSize = partition->Parent()->Size(); off_t parentSize = partition->Parent()->Size();
@ -197,13 +220,15 @@ public:
name << "Partition " << partition->ID(); name << "Partition " << partition->ID();
} }
partition_id id = partition->ID(); partition_id id = partition->ID();
PartitionView* view = new PartitionView(name.String(), scale, level, id); PartitionView* view = new PartitionView(name.String(), scale, offset,
level, id);
view->SetSelected(id == fSelectedPartition); view->SetSelected(id == fSelectedPartition);
PartitionView* parent = fViewMap.Get(partition->Parent()->ID()); PartitionView* parent = fViewMap.Get(partition->Parent()->ID());
BGroupLayout* layout = parent->GroupLayout(); BGroupLayout* layout = parent->GroupLayout();
layout->AddView(view, scale); layout->AddView(view, scale);
fViewMap.Put(partition->ID(), view); fViewMap.Put(partition->ID(), view);
_AddSpaces(partition, view);
return false; return false;
} }
@ -232,6 +257,35 @@ public:
} }
private: private:
void _AddSpaces(BPartition* partition, PartitionView* parentView) const
{
// add any available space on the partition
BPartitioningInfo info;
if (partition->GetPartitioningInfo(&info) >= B_OK) {
off_t parentSize = partition->Size();
off_t offset;
off_t size;
for (int32 i = 0;
info.GetPartitionableSpaceAt(i, &offset, &size) >= B_OK;
i++) {
double scale = (double)size / parentSize;
PartitionView* view = new PartitionView("Empty", scale,
offset, parentView->Level() + 1, -2);
BGroupLayout* layout = parentView->GroupLayout();
int32 count = parentView->CountChildren();
int32 insertIndex = 0;
for (int32 j = 0; j < count; j++) {
PartitionView* sibling = dynamic_cast<PartitionView*>(
parentView->ChildAt(j));
if (sibling && sibling->Offset() > offset)
break;
insertIndex++;
}
layout->AddView(view, scale);
}
}
}
typedef HashKey32<partition_id> PartitionKey; typedef HashKey32<partition_id> PartitionKey;
typedef HashMap<PartitionKey, PartitionView* > PartitionViewMap; typedef HashMap<PartitionKey, PartitionView* > PartitionViewMap;
@ -247,15 +301,15 @@ public:
DiskView::DiskView(const BRect& frame, uint32 resizeMode) DiskView::DiskView(const BRect& frame, uint32 resizeMode)
: Inherited(frame, "diskview", resizeMode, : Inherited(frame, "diskview", resizeMode,
B_WILL_DRAW | B_FRAME_EVENTS) B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE)
, fDiskCount(0) , fDiskCount(0)
, fDisk(NULL) , fDisk(NULL)
, fPartitionLayout(new PartitionLayout(this)) , fPartitionLayout(new PartitionLayout(this))
{ {
BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL, kLayoutInset); BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL, kLayoutInset);
layout->SetInsets(2, 2, 2, 2);
SetLayout(layout); SetLayout(layout);
SetViewColor(B_TRANSPARENT_COLOR);
rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
SetHighColor(tint_color(base, B_DARKEN_2_TINT)); SetHighColor(tint_color(base, B_DARKEN_2_TINT));
SetLowColor(tint_color(base, (B_DARKEN_2_TINT + B_DARKEN_1_TINT) / 2)); SetLowColor(tint_color(base, (B_DARKEN_2_TINT + B_DARKEN_1_TINT) / 2));
@ -336,13 +390,6 @@ DiskView::Draw(BRect updateRect)
} }
void
DiskView::FrameResized(float width, float height)
{
// DoLayout();
}
void void
DiskView::SetDiskCount(int32 count) DiskView::SetDiskCount(int32 count)
{ {

View File

@ -19,7 +19,6 @@ public:
// BView interface // BView interface
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
virtual void FrameResized(float width, float height);
void SetDiskCount(int32 count); void SetDiskCount(int32 count);
void SetDisk(BDiskDevice* disk, void SetDisk(BDiskDevice* disk,

View File

@ -20,6 +20,7 @@
#include <DiskSystem.h> #include <DiskSystem.h>
#include <DiskDevice.h> #include <DiskDevice.h>
#include <Partition.h> #include <Partition.h>
#include <PartitioningInfo.h>
#include <Path.h> #include <Path.h>
#include <ColumnListView.h> #include <ColumnListView.h>
@ -49,17 +50,35 @@ public:
virtual bool Visit(BDiskDevice* device) virtual bool Visit(BDiskDevice* device)
{ {
fDiskCount++; fDiskCount++;
fPartitionList->AddPartition(device); _AddPartition(device);
return false; // Don't stop yet! return false; // Don't stop yet!
} }
virtual bool Visit(BPartition* partition, int32 level) virtual bool Visit(BPartition* partition, int32 level)
{ {
fPartitionList->AddPartition(partition); _AddPartition(partition);
return false; // Don't stop yet! return false; // Don't stop yet!
} }
private: private:
void _AddPartition(BPartition* partition) const
{
// add the partition itself
fPartitionList->AddPartition(partition);
// add any available space on it
BPartitioningInfo info;
if (partition->GetPartitioningInfo(&info) >= B_OK) {
off_t offset;
off_t size;
for (int32 i = 0;
info.GetPartitionableSpaceAt(i, &offset, &size) >= B_OK;
i++) {
fPartitionList->AddSpace(partition->ID(), offset, size);
}
}
}
PartitionListView* fPartitionList; PartitionListView* fPartitionList;
int32& fDiskCount; int32& fDiskCount;
}; };
@ -402,8 +421,9 @@ MainWindow::_AdaptToSelectedPartition()
void void
MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition) MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition)
{ {
BDiskDevice* oldDisk = NULL;
if (!fCurrentDisk || fCurrentDisk->ID() != disk) { if (!fCurrentDisk || fCurrentDisk->ID() != disk) {
delete fCurrentDisk; oldDisk = fCurrentDisk;
fCurrentDisk = NULL; fCurrentDisk = NULL;
if (disk >= 0) { if (disk >= 0) {
BDiskDevice* newDisk = new BDiskDevice(); BDiskDevice* newDisk = new BDiskDevice();
@ -420,6 +440,8 @@ MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition)
fDiskView->SetDisk(fCurrentDisk, fCurrentPartitionID); fDiskView->SetDisk(fCurrentDisk, fCurrentPartitionID);
_EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID); _EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID);
delete oldDisk;
} }

View File

@ -28,6 +28,7 @@ enum {
PartitionListRow::PartitionListRow(BPartition* partition) PartitionListRow::PartitionListRow(BPartition* partition)
: Inherited() : Inherited()
, fPartitionID(partition->ID()) , fPartitionID(partition->ID())
, fParentID(partition->Parent() ? partition->Parent()->ID() : -1)
, fOffset(partition->Offset()) , fOffset(partition->Offset())
, fSize(partition->Size()) , fSize(partition->Size())
{ {
@ -57,9 +58,11 @@ PartitionListRow::PartitionListRow(BPartition* partition)
} }
PartitionListRow::PartitionListRow(partition_id id, off_t offset, off_t size) PartitionListRow::PartitionListRow(partition_id parentID, off_t offset,
off_t size)
: Inherited() : Inherited()
, fPartitionID(id) , fPartitionID(-2)
, fParentID(parentID)
, fOffset(offset) , fOffset(offset)
, fSize(size) , fSize(size)
{ {
@ -156,22 +159,16 @@ PartitionListView::AddPartition(BPartition* partition)
PartitionListRow* PartitionListRow*
PartitionListView::AddSpace(partition_id parentID, partition_id id, PartitionListView::AddSpace(partition_id parentID, off_t offset, off_t size)
off_t offset, off_t size)
{ {
PartitionListRow* partitionrow = FindRow(id);
// forget about it if this item is already in the listview
if (partitionrow != NULL)
return partitionrow;
// the parent should already be in the listview // the parent should already be in the listview
PartitionListRow* parent = FindRow(parentID); PartitionListRow* parent = FindRow(parentID);
if (!parent) if (!parent)
return NULL; return NULL;
// create the row for this partition // create the row for this partition
partitionrow = new PartitionListRow(id, offset, size); PartitionListRow* partitionrow = new PartitionListRow(parentID,
offset, size);
// find a proper insertion index based on the on-disk offset // find a proper insertion index based on the on-disk offset
int32 index = _InsertIndexForOffset(parent, offset); int32 index = _InsertIndexForOffset(parent, offset);

View File

@ -25,7 +25,7 @@ class PartitionListRow : public BRow {
typedef BRow Inherited; typedef BRow Inherited;
public: public:
PartitionListRow(BPartition* partition); PartitionListRow(BPartition* partition);
PartitionListRow(partition_id id, PartitionListRow(partition_id parentID,
off_t offset, off_t size); off_t offset, off_t size);
partition_id ID() const partition_id ID() const
@ -36,6 +36,7 @@ public:
{ return fSize; } { return fSize; }
private: private:
partition_id fPartitionID; partition_id fPartitionID;
partition_id fParentID;
off_t fOffset; off_t fOffset;
off_t fSize; off_t fSize;
}; };
@ -51,7 +52,7 @@ public:
PartitionListRow* parent = NULL); PartitionListRow* parent = NULL);
PartitionListRow* AddPartition(BPartition* partition); PartitionListRow* AddPartition(BPartition* partition);
PartitionListRow* AddSpace(partition_id parent, PartitionListRow* AddSpace(partition_id parent,
partition_id id, off_t offset, off_t size); off_t offset, off_t size);
private: private:
int32 _InsertIndexForOffset(PartitionListRow* parent, int32 _InsertIndexForOffset(PartitionListRow* parent,