* rewrote the DiskView display, it is now based on BViews and the layout
management * added labels for partitions in the DiskView * added selection via clicking a partition in the DiskView * indicated menu items for unimplemented features * added help message for freshly opened DriveSetup * added TODO file with some of my ideas for the next steps * refactored adoption of current disk/partition, the disk is not unnecessarily deleted and recreated anymore * gone is the colorfulness, the partitions are colored in greys according to their level in the hierarchy git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23633 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -6,9 +6,12 @@
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
#include "DiskView.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include <DiskDeviceVisitor.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <HashMap.h>
|
||||
#include <String.h>
|
||||
|
||||
using BPrivate::HashMap;
|
||||
using BPrivate::HashKey32;
|
||||
@@ -16,145 +19,225 @@ using BPrivate::HashKey32;
|
||||
|
||||
static const pattern kStripes = { { 0xc7, 0x8f, 0x1f, 0x3e,
|
||||
0x7c, 0xf8, 0xf1, 0xe3 } };
|
||||
static const rgb_color kInvalidColor = { 0, 0, 0, 0 };
|
||||
static const rgb_color kStripesHigh = { 112, 112, 112, 255 };
|
||||
static const rgb_color kStripesLow = { 104, 104, 104, 255 };
|
||||
|
||||
static const int32 kMaxPartitionColors = 256;
|
||||
static rgb_color kPartitionColors[kMaxPartitionColors];
|
||||
static const float kLayoutInset = 6;
|
||||
|
||||
|
||||
struct PartitionBox {
|
||||
PartitionBox()
|
||||
: frame(0, 0, -1, -1)
|
||||
, color(kInvalidColor)
|
||||
class PartitionView : public BView {
|
||||
public:
|
||||
PartitionView(const char* name, float weight, int32 level, partition_id id)
|
||||
: BView(name, B_WILL_DRAW | B_SUPPORTS_LAYOUT | B_FULL_UPDATE_ON_RESIZE)
|
||||
, fID(id)
|
||||
, fWeight(weight)
|
||||
, fSelected(false)
|
||||
, fMouseOver(false)
|
||||
, fGroupLayout(new BGroupLayout(B_HORIZONTAL, kLayoutInset))
|
||||
{
|
||||
SetLayout(fGroupLayout);
|
||||
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||
base = tint_color(base, B_LIGHTEN_2_TINT);
|
||||
base = tint_color(base, 1 + 0.13 * level);
|
||||
SetLowColor(base);
|
||||
SetHighColor(tint_color(base, B_DARKEN_1_TINT));
|
||||
|
||||
BFont font;
|
||||
GetFont(&font);
|
||||
font.SetSize(ceilf(font.Size() * 0.85));
|
||||
font.SetRotation(90.0);
|
||||
SetFont(&font);
|
||||
|
||||
fGroupLayout->SetInsets(kLayoutInset, kLayoutInset + font.Size(),
|
||||
kLayoutInset, kLayoutInset);
|
||||
|
||||
SetExplicitMinSize(BSize(font.Size() + 6, 30));
|
||||
}
|
||||
|
||||
PartitionBox(const BRect& frame, const rgb_color& color)
|
||||
: frame(frame)
|
||||
, color(color)
|
||||
virtual void MouseDown(BPoint where)
|
||||
{
|
||||
BMessage message(MSG_SELECTED_PARTITION_ID);
|
||||
message.AddInt32("partition_id", fID);
|
||||
Window()->PostMessage(&message);
|
||||
}
|
||||
|
||||
PartitionBox(const PartitionBox& other)
|
||||
: frame(other.frame)
|
||||
, color(other.color)
|
||||
virtual void MouseMoved(BPoint where, uint32 transit, const BMessage*)
|
||||
{
|
||||
uint32 buttons;
|
||||
if (Window()->CurrentMessage()->FindInt32("buttons",
|
||||
(int32*)&buttons) < B_OK)
|
||||
buttons = 0;
|
||||
|
||||
_SetMouseOver(buttons == 0
|
||||
&& (transit == B_ENTERED_VIEW || transit == B_INSIDE_VIEW));
|
||||
}
|
||||
|
||||
~PartitionBox()
|
||||
virtual void Draw(BRect updateRect)
|
||||
{
|
||||
if (fMouseOver) {
|
||||
float tint = (B_NO_TINT + B_LIGHTEN_1_TINT) / 2.0;
|
||||
SetHighColor(tint_color(HighColor(), tint));
|
||||
SetLowColor(tint_color(LowColor(), tint));
|
||||
}
|
||||
|
||||
BRect b(Bounds());
|
||||
if (fSelected) {
|
||||
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
|
||||
StrokeRect(b, B_SOLID_HIGH);
|
||||
b.InsetBy(1, 1);
|
||||
}
|
||||
StrokeRect(b, B_SOLID_HIGH);
|
||||
b.InsetBy(1, 1);
|
||||
|
||||
FillRect(b, B_SOLID_LOW);
|
||||
if (!fSelected)
|
||||
b.InsetBy(1, 1);
|
||||
|
||||
float width;
|
||||
BFont font;
|
||||
GetFont(&font);
|
||||
|
||||
font_height fh;
|
||||
font.GetHeight(&fh);
|
||||
|
||||
// draw the partition label, but only if we have no child partition
|
||||
// views
|
||||
BPoint textOffset;
|
||||
if (CountChildren() > 0) {
|
||||
font.SetRotation(0.0);
|
||||
SetFont(&font);
|
||||
width = b.Width();
|
||||
textOffset = b.LeftTop();
|
||||
textOffset.x += 3;
|
||||
textOffset.y += ceilf(fh.ascent);
|
||||
} else {
|
||||
width = b.Height();
|
||||
textOffset = b.LeftBottom();
|
||||
textOffset.x += ceilf(fh.ascent);
|
||||
}
|
||||
|
||||
BString name(Name());
|
||||
font.TruncateString(&name, B_TRUNCATE_END, width);
|
||||
|
||||
SetHighColor(tint_color(LowColor(), B_DARKEN_4_TINT));
|
||||
DrawString(name.String(), textOffset);
|
||||
}
|
||||
|
||||
PartitionBox& operator=(const PartitionBox& other)
|
||||
float Weight() const
|
||||
{
|
||||
frame = other.frame;
|
||||
color = other.color;
|
||||
return *this;
|
||||
return fWeight;
|
||||
}
|
||||
|
||||
BRect frame;
|
||||
rgb_color color;
|
||||
BGroupLayout* GroupLayout() const
|
||||
{
|
||||
return fGroupLayout;
|
||||
}
|
||||
|
||||
void SetSelected(bool selected)
|
||||
{
|
||||
if (fSelected == selected)
|
||||
return;
|
||||
|
||||
fSelected = selected;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
private:
|
||||
void _SetMouseOver(bool mouseOver)
|
||||
{
|
||||
if (fMouseOver == mouseOver)
|
||||
return;
|
||||
fMouseOver = mouseOver;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
private:
|
||||
partition_id fID;
|
||||
float fWeight;
|
||||
bool fSelected;
|
||||
bool fMouseOver;
|
||||
BGroupLayout* fGroupLayout;
|
||||
};
|
||||
|
||||
|
||||
class DiskView::PartitionDrawer : public BDiskDeviceVisitor {
|
||||
class DiskView::PartitionLayout : public BDiskDeviceVisitor {
|
||||
public:
|
||||
PartitionDrawer(BView* view)
|
||||
PartitionLayout(BView* view)
|
||||
: fView(view)
|
||||
, fBoxMap()
|
||||
, fColorIndex(0)
|
||||
, fViewMap()
|
||||
, fSelectedPartition(-1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Visit(BDiskDevice* device)
|
||||
{
|
||||
fBoxMap.Put(device->ID(), PartitionBox(fView->Bounds(), _NextColor()));
|
||||
PartitionView* view = new PartitionView("Device", 1.0, 0, device->ID());
|
||||
fViewMap.Put(device->ID(), view);
|
||||
fView->GetLayout()->AddView(view);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool Visit(BPartition* partition, int32 level)
|
||||
{
|
||||
if (!partition->Parent() || !fBoxMap.ContainsKey(partition->Parent()->ID()))
|
||||
if (!partition->Parent() || !fViewMap.ContainsKey(partition->Parent()->ID()))
|
||||
return false;
|
||||
|
||||
PartitionBox parent = fBoxMap.Get(partition->Parent()->ID());
|
||||
BRect frame = parent.frame;
|
||||
// calculate frame within parent frame
|
||||
off_t offset = partition->Offset();
|
||||
// calculate size factor within parent frame
|
||||
// TODO: support gaps view these offsets:
|
||||
// off_t offset = partition->Offset();
|
||||
// off_t parentOffset = partition->Parent()->Offset();
|
||||
off_t size = partition->Size();
|
||||
off_t parentOffset = partition->Parent()->Offset();
|
||||
off_t parentSize = partition->Parent()->Size();
|
||||
float width = frame.Width() * size / parentSize;
|
||||
frame.left = roundf(frame.left + frame.Width()
|
||||
* (offset - parentOffset) / parentSize);
|
||||
frame.right = frame.left + width;
|
||||
double scale = (double)size / parentSize;
|
||||
|
||||
frame.InsetBy(4, 4);
|
||||
if (frame.right < frame.left)
|
||||
frame.right = frame.left;
|
||||
BString name = partition->ContentName();
|
||||
if (name.Length() == 0) {
|
||||
if (partition->CountChildren() > 0)
|
||||
name << partition->Type();
|
||||
else
|
||||
name << "Partition " << partition->ID();
|
||||
}
|
||||
partition_id id = partition->ID();
|
||||
PartitionView* view = new PartitionView(name.String(), scale, level, id);
|
||||
view->SetSelected(id == fSelectedPartition);
|
||||
PartitionView* parent = fViewMap.Get(partition->Parent()->ID());
|
||||
BGroupLayout* layout = parent->GroupLayout();
|
||||
layout->AddView(view, scale);
|
||||
|
||||
rgb_color color = _NextColor();
|
||||
fBoxMap.Put(partition->ID(), PartitionBox(frame, color));
|
||||
fViewMap.Put(partition->ID(), view);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetSelectedPartition(partition_id id)
|
||||
{
|
||||
fSelectedPartition = id;
|
||||
}
|
||||
if (fSelectedPartition == id)
|
||||
return;
|
||||
|
||||
void Draw(BView* view)
|
||||
{
|
||||
PartitionBoxMap::Iterator iterator = fBoxMap.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
PartitionBoxMap::Entry entry = iterator.Next();
|
||||
PartitionBox box = entry.value;
|
||||
BRect frame = box.frame;
|
||||
if (entry.key == fSelectedPartition) {
|
||||
fView->SetHighColor(80, 80, 80);
|
||||
frame.InsetBy(-2, -2);
|
||||
fView->StrokeRect(frame);
|
||||
frame.InsetBy(1, 1);
|
||||
fView->StrokeRect(frame);
|
||||
frame.InsetBy(1, 1);
|
||||
} else {
|
||||
fView->SetHighColor(tint_color(box.color, B_DARKEN_2_TINT));
|
||||
frame.InsetBy(-1, -1);
|
||||
fView->StrokeRect(frame);
|
||||
frame.InsetBy(1, 1);
|
||||
}
|
||||
|
||||
fView->SetHighColor(box.color);
|
||||
fView->FillRect(frame);
|
||||
if (fViewMap.ContainsKey(fSelectedPartition)) {
|
||||
PartitionView* view = fViewMap.Get(fSelectedPartition);
|
||||
view->SetSelected(false);
|
||||
}
|
||||
|
||||
fSelectedPartition = id;
|
||||
|
||||
if (fViewMap.ContainsKey(fSelectedPartition)) {
|
||||
PartitionView* view = fViewMap.Get(fSelectedPartition);
|
||||
view->SetSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Unset()
|
||||
{
|
||||
fColorIndex = 0;
|
||||
fBoxMap.Clear();
|
||||
fViewMap.Clear();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
rgb_color _NextColor()
|
||||
{
|
||||
fColorIndex++;
|
||||
if (fColorIndex > kMaxPartitionColors)
|
||||
fColorIndex = 0;
|
||||
return kPartitionColors[fColorIndex];
|
||||
}
|
||||
|
||||
typedef HashKey32<partition_id> PartitionKey;
|
||||
typedef HashMap<PartitionKey, PartitionBox > PartitionBoxMap;
|
||||
typedef HashMap<PartitionKey, PartitionView* > PartitionViewMap;
|
||||
|
||||
BView* fView;
|
||||
PartitionBoxMap fBoxMap;
|
||||
int32 fColorIndex;
|
||||
PartitionViewMap fViewMap;
|
||||
partition_id fSelectedPartition;
|
||||
};
|
||||
|
||||
@@ -165,22 +248,58 @@ public:
|
||||
DiskView::DiskView(const BRect& frame, uint32 resizeMode)
|
||||
: Inherited(frame, "diskview", resizeMode,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS)
|
||||
, fDiskCount(0)
|
||||
, fDisk(NULL)
|
||||
, fPartitionDrawer(new PartitionDrawer(this))
|
||||
, fPartitionLayout(new PartitionLayout(this))
|
||||
{
|
||||
for (int32 i = 0; i < kMaxPartitionColors; i++) {
|
||||
kPartitionColors[i].red = 90 + ((i * 1675) & 160);
|
||||
kPartitionColors[i].green = 90 + ((i * 318) & 160);
|
||||
kPartitionColors[i].blue = 90 + ((i * 9328) & 160);
|
||||
kPartitionColors[i].alpha = 255;
|
||||
}
|
||||
BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL, kLayoutInset);
|
||||
layout->SetInsets(2, 2, 2, 2);
|
||||
SetLayout(layout);
|
||||
|
||||
rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||
SetHighColor(tint_color(base, B_DARKEN_2_TINT));
|
||||
SetLowColor(tint_color(base, (B_DARKEN_2_TINT + B_DARKEN_1_TINT) / 2));
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_LIBBE_TEST
|
||||
PartitionView* view;
|
||||
float scale = 1.0;
|
||||
view = new PartitionView("Disk", scale, 0, -1);
|
||||
layout->AddView(view, scale);
|
||||
|
||||
layout = view->GroupLayout();
|
||||
|
||||
scale = 0.3;
|
||||
view = new PartitionView("Primary", scale, 1, -1);
|
||||
layout->AddView(view, scale);
|
||||
scale = 0.7;
|
||||
view = new PartitionView("Extended", scale, 1, -1);
|
||||
layout->AddView(view, scale);
|
||||
|
||||
layout = view->GroupLayout();
|
||||
|
||||
scale = 0.2;
|
||||
view = new PartitionView("Logical", scale, 2, -1);
|
||||
layout->AddView(view, scale);
|
||||
|
||||
scale = 0.5;
|
||||
view = new PartitionView("Logical", scale, 2, -1);
|
||||
layout->AddView(view, scale);
|
||||
|
||||
scale = 0.005;
|
||||
view = new PartitionView("Logical", scale, 2, -1);
|
||||
layout->AddView(view, scale);
|
||||
|
||||
scale = 0.295;
|
||||
view = new PartitionView("Logical", scale, 2, -1);
|
||||
layout->AddView(view, scale);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
DiskView::~DiskView()
|
||||
{
|
||||
SetDisk(NULL, -1);
|
||||
delete fPartitionDrawer;
|
||||
delete fPartitionLayout;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,30 +308,56 @@ DiskView::Draw(BRect updateRect)
|
||||
{
|
||||
BRect bounds(Bounds());
|
||||
|
||||
if (!fDisk) {
|
||||
SetHighColor(kStripesHigh);
|
||||
SetLowColor(kStripesLow);
|
||||
FillRect(bounds, kStripes);
|
||||
if (fDisk)
|
||||
return;
|
||||
}
|
||||
|
||||
fPartitionDrawer->Draw(this);
|
||||
FillRect(bounds, kStripes);
|
||||
|
||||
const char* helpfulMessage;
|
||||
if (fDiskCount == 0)
|
||||
helpfulMessage = "No disk devices have been recognized.";
|
||||
else
|
||||
helpfulMessage = "Select a partition from the list below.";
|
||||
|
||||
float width = StringWidth(helpfulMessage);
|
||||
font_height fh;
|
||||
GetFontHeight(&fh);
|
||||
BRect messageBounds(bounds);
|
||||
messageBounds.InsetBy((bounds.Width() - width - fh.ascent * 2) / 2.0,
|
||||
(bounds.Height() - (fh.ascent + fh.descent) * 2) / 2.0);
|
||||
|
||||
FillRoundRect(messageBounds, 4, 4, B_SOLID_LOW);
|
||||
SetHighColor(tint_color(HighColor(), B_DARKEN_4_TINT));
|
||||
BPoint textOffset;
|
||||
textOffset.x = messageBounds.left + fh.ascent;
|
||||
textOffset.y = (messageBounds.top + messageBounds.bottom
|
||||
- fh.ascent - fh.descent) / 2 + fh.ascent;
|
||||
DrawString(helpfulMessage, textOffset);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DiskView::FrameResized(float width, float height)
|
||||
{
|
||||
_UpdateLayout();
|
||||
// DoLayout();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DiskView::SetDiskCount(int32 count)
|
||||
{
|
||||
fDiskCount = count;
|
||||
}
|
||||
|
||||
void
|
||||
DiskView::SetDisk(BDiskDevice* disk, partition_id selectedPartition)
|
||||
{
|
||||
fDisk = disk;
|
||||
fPartitionDrawer->SetSelectedPartition(selectedPartition);
|
||||
_UpdateLayout();
|
||||
fPartitionLayout->SetSelectedPartition(selectedPartition);
|
||||
|
||||
if (fDisk != disk) {
|
||||
fDisk = disk;
|
||||
_UpdateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,10 +367,15 @@ DiskView::SetDisk(BDiskDevice* disk, partition_id selectedPartition)
|
||||
void
|
||||
DiskView::_UpdateLayout()
|
||||
{
|
||||
fPartitionDrawer->Unset();
|
||||
while (BView* view = ChildAt(0)) {
|
||||
view->RemoveSelf();
|
||||
delete view;
|
||||
}
|
||||
|
||||
fPartitionLayout->Unset();
|
||||
|
||||
if (fDisk)
|
||||
fDisk->VisitEachDescendant(fPartitionDrawer);
|
||||
fDisk->VisitEachDescendant(fPartitionLayout);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
@@ -21,15 +21,17 @@ public:
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void FrameResized(float width, float height);
|
||||
|
||||
void SetDiskCount(int32 count);
|
||||
void SetDisk(BDiskDevice* disk,
|
||||
partition_id selectedPartition);
|
||||
private:
|
||||
void _UpdateLayout();
|
||||
|
||||
int32 fDiskCount;
|
||||
BDiskDevice* fDisk;
|
||||
|
||||
class PartitionDrawer;
|
||||
PartitionDrawer* fPartitionDrawer;
|
||||
class PartitionLayout;
|
||||
PartitionLayout* fPartitionLayout;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -32,9 +32,11 @@
|
||||
|
||||
class ListPopulatorVisitor : public BDiskDeviceVisitor {
|
||||
public:
|
||||
ListPopulatorVisitor(PartitionListView* list)
|
||||
ListPopulatorVisitor(PartitionListView* list, int32& diskCount)
|
||||
: fPartitionList(list)
|
||||
, fDiskCount(diskCount)
|
||||
{
|
||||
fDiskCount = 0;
|
||||
// start with an empty list
|
||||
int32 rows = fPartitionList->CountRows();
|
||||
for (int32 i = rows - 1; i >= 0; i--) {
|
||||
@@ -46,6 +48,7 @@ public:
|
||||
|
||||
virtual bool Visit(BDiskDevice* device)
|
||||
{
|
||||
fDiskCount++;
|
||||
fPartitionList->AddPartition(device);
|
||||
return false; // Don't stop yet!
|
||||
}
|
||||
@@ -57,7 +60,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
PartitionListView* fPartitionList;
|
||||
PartitionListView* fPartitionList;
|
||||
int32& fDiskCount;
|
||||
};
|
||||
|
||||
|
||||
@@ -92,6 +96,7 @@ enum {
|
||||
MSG_CREATE_EXTENDED = 'crex',
|
||||
MSG_CREATE_LOGICAL = 'crlg',
|
||||
MSG_INITIALIZE = 'init',
|
||||
MSG_DELETE = 'delt',
|
||||
MSG_EJECT = 'ejct',
|
||||
MSG_SURFACE_TEST = 'sfct',
|
||||
MSG_RESCAN = 'rscn',
|
||||
@@ -108,9 +113,9 @@ MainWindow::MainWindow(BRect frame)
|
||||
BMenuBar* menuBar = new BMenuBar(Bounds(), "root menu");
|
||||
|
||||
// create all the menu items
|
||||
fFormatMI = new BMenuItem("Format", new BMessage(MSG_FORMAT));
|
||||
fFormatMI = new BMenuItem("Format (not implemented)", new BMessage(MSG_FORMAT));
|
||||
fEjectMI = new BMenuItem("Eject", new BMessage(MSG_EJECT), 'E');
|
||||
fSurfaceTestMI = new BMenuItem("Surface Test",
|
||||
fSurfaceTestMI = new BMenuItem("Surface Test (not implemented)",
|
||||
new BMessage(MSG_SURFACE_TEST));
|
||||
fRescanMI = new BMenuItem("Rescan", new BMessage(MSG_RESCAN));
|
||||
|
||||
@@ -121,6 +126,10 @@ MainWindow::MainWindow(BRect frame)
|
||||
fCreateLogicalMI = new BMenuItem("Logical",
|
||||
new BMessage(MSG_CREATE_LOGICAL));
|
||||
|
||||
fDeleteMI = new BMenuItem("Delete (not implemented)",
|
||||
new BMessage(MSG_DELETE));
|
||||
fDeleteMI->SetEnabled(false);
|
||||
|
||||
fMountMI = new BMenuItem("Mount", new BMessage(MSG_MOUNT), 'M');
|
||||
fUnmountMI = new BMenuItem("Unmount", new BMessage(MSG_UNMOUNT), 'U');
|
||||
fMountAllMI = new BMenuItem("Mount All",
|
||||
@@ -139,7 +148,7 @@ MainWindow::MainWindow(BRect frame)
|
||||
|
||||
// Parition menu
|
||||
fPartitionMenu = new BMenu("Partition");
|
||||
fCreateMenu = new BMenu("Create");
|
||||
fCreateMenu = new BMenu("Create (not implemented)");
|
||||
fCreateMenu->AddItem(fCreatePrimaryMI);
|
||||
fCreateMenu->AddItem(fCreateExtendedMI);
|
||||
fCreateMenu->AddItem(fCreateLogicalMI);
|
||||
@@ -148,6 +157,8 @@ MainWindow::MainWindow(BRect frame)
|
||||
fInitMenu = new BMenu("Initialize");
|
||||
fPartitionMenu->AddItem(fInitMenu);
|
||||
|
||||
fPartitionMenu->AddItem(fDeleteMI);
|
||||
|
||||
fPartitionMenu->AddSeparatorItem();
|
||||
|
||||
fPartitionMenu->AddItem(fMountMI);
|
||||
@@ -231,6 +242,10 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_DELETE:
|
||||
printf("MSG_DELETE\n");
|
||||
break;
|
||||
|
||||
case MSG_EJECT:
|
||||
// TODO: completely untested, especially interesting
|
||||
// if partition list behaves when partitions disappear
|
||||
@@ -248,8 +263,21 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
break;
|
||||
|
||||
case MSG_PARTITION_ROW_SELECTED:
|
||||
// selection of partitions via list view
|
||||
_AdaptToSelectedPartition();
|
||||
break;
|
||||
case MSG_SELECTED_PARTITION_ID: {
|
||||
// selection of partitions via disk view
|
||||
partition_id id;
|
||||
if (message->FindInt32("partition_id", &id) == B_OK) {
|
||||
if (BRow* row = fListView->FindRow(id)) {
|
||||
fListView->DeselectAll();
|
||||
fListView->AddToSelection(row);
|
||||
_AdaptToSelectedPartition();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
@@ -312,8 +340,10 @@ MainWindow::RestoreSettings(BMessage* archive)
|
||||
void
|
||||
MainWindow::_ScanDrives()
|
||||
{
|
||||
ListPopulatorVisitor driveVisitor(fListView);
|
||||
int32 diskCount = 0;
|
||||
ListPopulatorVisitor driveVisitor(fListView, diskCount);
|
||||
fDDRoster.VisitEachPartition(&driveVisitor);
|
||||
fDiskView->SetDiskCount(diskCount);
|
||||
}
|
||||
|
||||
|
||||
@@ -343,40 +373,50 @@ MainWindow::_ScanFileSystems()
|
||||
void
|
||||
MainWindow::_AdaptToSelectedPartition()
|
||||
{
|
||||
delete fCurrentDisk;
|
||||
fCurrentDisk = NULL;
|
||||
fCurrentPartitionID = -1;
|
||||
partition_id disk = -1;
|
||||
partition_id partition = -1;
|
||||
|
||||
BRow* _selectedRow = fListView->CurrentSelection();
|
||||
if (!_selectedRow) {
|
||||
fDiskView->SetDisk(NULL, -1);
|
||||
_EnabledDisableMenuItems(NULL, -1);
|
||||
return;
|
||||
if (_selectedRow) {
|
||||
// go up to top level row
|
||||
BRow* _topLevelRow = _selectedRow;
|
||||
BRow* parent = NULL;
|
||||
while (fListView->FindParent(_topLevelRow, &parent, NULL))
|
||||
_topLevelRow = parent;
|
||||
|
||||
PartitionListRow* topLevelRow
|
||||
= dynamic_cast<PartitionListRow*>(_topLevelRow);
|
||||
PartitionListRow* selectedRow
|
||||
= dynamic_cast<PartitionListRow*>(_selectedRow);
|
||||
|
||||
if (topLevelRow)
|
||||
disk = topLevelRow->ID();
|
||||
if (selectedRow)
|
||||
partition = selectedRow->ID();
|
||||
}
|
||||
|
||||
// recurse to top level row
|
||||
BRow* _topLevelRow = _selectedRow;
|
||||
BRow* parent = NULL;
|
||||
while (fListView->FindParent(_topLevelRow, &parent, NULL))
|
||||
_topLevelRow = parent;
|
||||
_SetToDiskAndPartition(disk, partition);
|
||||
}
|
||||
|
||||
PartitionListRow* topLevelRow
|
||||
= dynamic_cast<PartitionListRow*>(_topLevelRow);
|
||||
PartitionListRow* selectedRow
|
||||
= dynamic_cast<PartitionListRow*>(_selectedRow);
|
||||
|
||||
if (!topLevelRow || !selectedRow)
|
||||
return;
|
||||
|
||||
fCurrentDisk = new BDiskDevice();
|
||||
status_t ret = fCurrentDisk->SetTo(topLevelRow->ID());
|
||||
if (ret < B_OK) {
|
||||
printf("error switching disks: %s\n", strerror(ret));
|
||||
void
|
||||
MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition)
|
||||
{
|
||||
if (!fCurrentDisk || fCurrentDisk->ID() != disk) {
|
||||
delete fCurrentDisk;
|
||||
fCurrentDisk = NULL;
|
||||
return;
|
||||
if (disk >= 0) {
|
||||
BDiskDevice* newDisk = new BDiskDevice();
|
||||
status_t ret = newDisk->SetTo(disk);
|
||||
if (ret < B_OK) {
|
||||
printf("error switching disks: %s\n", strerror(ret));
|
||||
delete newDisk;
|
||||
} else
|
||||
fCurrentDisk = newDisk;
|
||||
}
|
||||
}
|
||||
fCurrentPartitionID = selectedRow->ID();
|
||||
|
||||
fCurrentPartitionID = partition;
|
||||
|
||||
fDiskView->SetDisk(fCurrentDisk, fCurrentPartitionID);
|
||||
_EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID);
|
||||
@@ -395,21 +435,25 @@ MainWindow::_EnabledDisableMenuItems(BDiskDevice* disk,
|
||||
fPartitionMenu->SetEnabled(false);
|
||||
} else {
|
||||
// fFormatMI->SetEnabled(true);
|
||||
fFormatMI->SetEnabled(false);
|
||||
fEjectMI->SetEnabled(disk->IsRemovableMedia());
|
||||
// fSurfaceTestMI->SetEnabled(true);
|
||||
fSurfaceTestMI->SetEnabled(false);
|
||||
|
||||
fPartitionMenu->SetEnabled(true);
|
||||
fCreatePrimaryMI->SetEnabled(false);
|
||||
fCreateExtendedMI->SetEnabled(false);
|
||||
fCreateLogicalMI->SetEnabled(false);
|
||||
// fCreateMenu->SetEnabled(/*empty space selected*/);
|
||||
fCreateMenu->SetEnabled(false);
|
||||
|
||||
BPartition* partition = disk->FindDescendant(selectedPartition);
|
||||
if (partition) {
|
||||
fInitMenu->SetEnabled(!partition->IsMounted());
|
||||
// fDeleteMI->SetEnabled(!partition->IsMounted());
|
||||
fDeleteMI->SetEnabled(false);
|
||||
fMountMI->SetEnabled(!partition->IsMounted());
|
||||
fUnmountMI->SetEnabled(partition->IsMounted());
|
||||
} else {
|
||||
fInitMenu->SetEnabled(false);
|
||||
fDeleteMI->SetEnabled(false);
|
||||
fMountMI->SetEnabled(false);
|
||||
fUnmountMI->SetEnabled(false);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ class DiskView;
|
||||
class PartitionListView;
|
||||
|
||||
|
||||
enum {
|
||||
MSG_SELECTED_PARTITION_ID = 'spid'
|
||||
};
|
||||
|
||||
|
||||
class MainWindow : public BWindow {
|
||||
public:
|
||||
MainWindow(BRect frame);
|
||||
@@ -40,6 +45,8 @@ private:
|
||||
void _ScanFileSystems();
|
||||
|
||||
void _AdaptToSelectedPartition();
|
||||
void _SetToDiskAndPartition(partition_id disk,
|
||||
partition_id partition);
|
||||
void _EnabledDisableMenuItems(BDiskDevice* disk,
|
||||
partition_id selectedPartition);
|
||||
|
||||
@@ -78,6 +85,7 @@ private:
|
||||
BMenuItem* fCreatePrimaryMI;
|
||||
BMenuItem* fCreateExtendedMI;
|
||||
BMenuItem* fCreateLogicalMI;
|
||||
BMenuItem* fDeleteMI;
|
||||
BMenuItem* fMountMI;
|
||||
BMenuItem* fUnmountMI;
|
||||
BMenuItem* fMountAllMI;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
* Create an icon.
|
||||
|
||||
* The offsets of partitions should be used to detect free space on container partition types (disks and extended partitions). Items for these free spaces should be placed into the partition list and disk view, so that they can be selected. Only if such a space item is selected should the Partition->Create menu be enabled. If the space is on a disk, the "Primary" and "Extended" items could be enabled. If the space is on an extended partition, the "Logical" item could be enabled. Maybe the Disk Device API allows to query for the ability to create either partition type on the parent device, depending on the partitioning system in use, so that DriveSetup remains neutral towards the partitioning system.
|
||||
|
||||
* When the Partition->Create menu items are invoked on free space items, DriveSetup would show a simple panel asking for the size of the to be created partition.
|
||||
|
||||
* Support of more advanced options, partiticularily the option to resize (shrink) existing partitions to free up space.
|
||||
Reference in New Issue
Block a user