Still a work-in-progress, but now basic editing can be done.

Added an ImageEditor object, but edits aren't saved... yet


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20113 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm
2007-02-07 22:15:21 +00:00
parent a68270fe2c
commit e61a091fd0
11 changed files with 224 additions and 161 deletions
+9 -1
View File
@@ -17,7 +17,6 @@ main(void)
return 0; return 0;
} }
App::App(void) App::App(void)
: BApplication("application/x-vnd.Haiku-ResEdit"), : BApplication("application/x-vnd.Haiku-ResEdit"),
fWindowCount(0) fWindowCount(0)
@@ -37,10 +36,19 @@ App::~App(void)
void void
App::ReadyToRun(void) App::ReadyToRun(void)
{ {
/*
if (fWindowCount < 1) { if (fWindowCount < 1) {
ResWindow *win = new ResWindow(BRect(50,100,600,400)); ResWindow *win = new ResWindow(BRect(50,100,600,400));
win->Show(); win->Show();
} }
*/
if (fWindowCount < 1) {
BEntry entry("/boot/develop/projects/ResEdit/CapitalBe.rsrc");
entry_ref ref;
entry.GetRef(&ref);
ResWindow *win = new ResWindow(BRect(50,100,600,400),&ref);
win->Show();
}
} }
+16 -5
View File
@@ -8,14 +8,25 @@
#ifndef EDITOR_H #ifndef EDITOR_H
#define EDITOR_H #define EDITOR_H
class Editor #include <Window.h>
#include <Handler.h>
class ResourceData;
#define M_UPDATE_RESOURCE 'uprs'
class Editor : public BWindow
{ {
public: public:
Editor(void); Editor(const BRect &frame, ResourceData *data,
BHandler *owner);
virtual ~Editor(void); virtual ~Editor(void);
virtual BView * GetConfigView(void);
virtual void LoadData(unsigned char *data, const size_t &length); ResourceData * GetData(void) const { return fResData; }
virtual unsigned char * SaveData(size_t *data); BHandler * GetOwner(void) const { return fOwner; }
private:
ResourceData *fResData;
BHandler *fOwner;
}; };
#endif #endif
+6
View File
@@ -15,7 +15,13 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits interface ] ;
Application ResEdit : Application ResEdit :
$(columnViewSources) $(columnViewSources)
App.cpp App.cpp
BitmapView.cpp
ImageEditor.cpp
InlineEditor.cpp
MiscEditors.cpp
NumberEditors.cpp
PreviewColumn.cpp PreviewColumn.cpp
ResFields.cpp
ResourceData.cpp ResourceData.cpp
ResourceRoster.cpp ResourceRoster.cpp
ResView.cpp ResView.cpp
+9 -52
View File
@@ -6,6 +6,7 @@
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
*/ */
#include "PreviewColumn.h" #include "PreviewColumn.h"
#include "ResFields.h"
#include <stdio.h> #include <stdio.h>
PreviewColumn::PreviewColumn(const char *title, float width, PreviewColumn::PreviewColumn(const char *title, float width,
@@ -17,56 +18,12 @@ PreviewColumn::PreviewColumn(const char *title, float width,
void void
PreviewColumn::DrawField(BField* field, BRect rect, BView* parent) PreviewColumn::DrawField(BField* field, BRect rect, BView* parent)
{ {
BIntegerField *intField = dynamic_cast<BIntegerField*>(field); PreviewField *pField = (PreviewField*)field;
BStringField *strField = dynamic_cast<BStringField*>(field); pField->DrawField(rect,parent);
BBitmapField *bmpField = dynamic_cast<BBitmapField*>(field); }
if (intField) { bool
float width = rect.Width() - 16; PreviewColumn::AcceptsField(const BField* field) const
BString string; {
string << intField->Value(); return dynamic_cast<const PreviewField*>(field);
parent->TruncateString(&string, B_TRUNCATE_MIDDLE, width + 2);
DrawString(string.String(), parent, rect);
} else if (strField) {
float width = rect.Width() - 16;
if (width != strField->Width()) {
BString out_string(strField->String());
parent->TruncateString(&out_string, B_TRUNCATE_END, width + 2);
strField->SetClippedString(out_string.String());
strField->SetWidth(width);
}
DrawString(strField->ClippedString(), parent, rect);
} else if (bmpField) {
const BBitmap *bitmap = bmpField->Bitmap();
if (bitmap != NULL) {
// Scale the bitmap down to completely fit within the field's height
BRect drawrect(bitmap->Bounds().OffsetToCopy(rect.LeftTop()));
if (drawrect.Height() > rect.Height()) {
drawrect = rect;
drawrect.right = drawrect.left +
(bitmap->Bounds().Width() *
(rect.Height() / bitmap->Bounds().Height()));
}
parent->SetDrawingMode(B_OP_ALPHA);
parent->DrawBitmap(bitmap, bitmap->Bounds(), drawrect);
parent->SetDrawingMode(B_OP_COPY);
BString out;
out << bitmap->Bounds().IntegerWidth() << " x "
<< bitmap->Bounds().IntegerHeight() << " x "
<< (int32(bitmap->BytesPerRow() / bitmap->Bounds().Width()) * 8);
BRect stringrect = rect;
stringrect.right -= 10;
stringrect.left = stringrect.right - parent->StringWidth(out.String());
if (stringrect.left < drawrect.right + 5)
stringrect.left = drawrect.right + 5;
parent->TruncateString(&out, B_TRUNCATE_END, stringrect.Width());
DrawString(out.String(), parent, stringrect);
}
}
} }
+1
View File
@@ -16,6 +16,7 @@ public:
PreviewColumn(const char *title, float width, PreviewColumn(const char *title, float width,
float minWidth, float maxWidth); float minWidth, float maxWidth);
void DrawField(BField* field, BRect rect, BView* parent); void DrawField(BField* field, BRect rect, BView* parent);
bool AcceptsField(const BField* field) const;
}; };
#endif #endif
+85 -50
View File
@@ -17,8 +17,10 @@
#include "App.h" #include "App.h"
#include "ResourceData.h" #include "ResourceData.h"
#include "ResFields.h"
#include "ResWindow.h" #include "ResWindow.h"
#include "PreviewColumn.h" #include "PreviewColumn.h"
#include "Editor.h"
static int32 sUntitled = 1; static int32 sUntitled = 1;
@@ -29,7 +31,8 @@ enum {
M_OPEN_FILE, M_OPEN_FILE,
M_SAVE_FILE, M_SAVE_FILE,
M_SAVE_FILE_AS, M_SAVE_FILE_AS,
M_QUIT M_QUIT,
M_EDIT_RESOURCE
}; };
ResView::ResView(const BRect &frame, const char *name, const int32 &resize, ResView::ResView(const BRect &frame, const char *name, const int32 &resize,
@@ -78,6 +81,7 @@ ResView::ResView(const BRect &frame, const char *name, const int32 &resize,
fListView->AddColumn(new BStringColumn("Type",width,width,100,B_TRUNCATE_END),1); fListView->AddColumn(new BStringColumn("Type",width,width,100,B_TRUNCATE_END),1);
fListView->AddColumn(new BStringColumn("Name",150,50,300,B_TRUNCATE_END),2); fListView->AddColumn(new BStringColumn("Name",150,50,300,B_TRUNCATE_END),2);
fListView->AddColumn(new PreviewColumn("Data",150,50,300),3); fListView->AddColumn(new PreviewColumn("Data",150,50,300),3);
fListView->SetInvocationMessage(new BMessage(M_EDIT_RESOURCE));
width = be_plain_font->StringWidth("1000 bytes") + 20; width = be_plain_font->StringWidth("1000 bytes") + 20;
fListView->AddColumn(new BSizeColumn("Size",width,10,100),4); fListView->AddColumn(new BSizeColumn("Size",width,10,100),4);
@@ -89,6 +93,7 @@ ResView::ResView(const BRect &frame, const char *name, const int32 &resize,
ResView::~ResView(void) ResView::~ResView(void)
{ {
EmptyDataList();
delete fRef; delete fRef;
} }
@@ -98,12 +103,18 @@ ResView::AttachedToWindow(void)
{ {
for(int32 i = 0; i < fBar->CountItems(); i++) for(int32 i = 0; i < fBar->CountItems(); i++)
fBar->SubmenuAt(i)->SetTargetForItems(this); fBar->SubmenuAt(i)->SetTargetForItems(this);
fListView->SetTarget(this);
} }
void void
ResView::MessageReceived(BMessage *msg) ResView::MessageReceived(BMessage *msg)
{ {
if (msg->WasDropped()) {
be_app->PostMessage(msg);
return;
}
switch (msg->what) { switch (msg->what) {
case M_NEW_FILE: { case M_NEW_FILE: {
BRect r(100,100,400,400); BRect r(100,100,400,400);
@@ -121,6 +132,28 @@ ResView::MessageReceived(BMessage *msg)
be_app->PostMessage(B_QUIT_REQUESTED); be_app->PostMessage(B_QUIT_REQUESTED);
break; break;
} }
case M_EDIT_RESOURCE: {
BRow *row = fListView->CurrentSelection();
TypeCodeField *field = (TypeCodeField*)row->GetField(1);
gResRoster.SpawnEditor(field->GetResourceData(),this);
break;
}
case M_UPDATE_RESOURCE: {
ResourceData *item;
if (msg->FindPointer("item",(void **)&item) != B_OK)
break;
for (int32 i = 0; i < fListView->CountRows(); i++) {
BRow *row = fListView->RowAt(i);
TypeCodeField *field = (TypeCodeField*)row->GetField(1);
if (!field || field->GetResourceData() != item)
continue;
UpdateRow(row);
break;
}
break;
}
default: default:
BView::MessageReceived(msg); BView::MessageReceived(msg);
} }
@@ -133,86 +166,88 @@ ResView::OpenFile(const entry_ref &ref)
// Add all the 133t resources and attributes of the file // Add all the 133t resources and attributes of the file
BFile file(&ref, B_READ_ONLY); BFile file(&ref, B_READ_ONLY);
if (fResources.SetTo(&file) != B_OK) BResources resources;
if (resources.SetTo(&file) != B_OK)
return; return;
file.Unset(); file.Unset();
fResources.PreloadResourceType(); resources.PreloadResourceType();
int32 index = 0; int32 index = 0;
ResourceData data;
BRow *row; BRow *row;
while (data.SetFromResource(index, fResources)) { ResourceData *resData = new ResourceData();
while (resData->SetFromResource(index, resources)) {
row = new BRow(); row = new BRow();
row->SetField(new BStringField(data.GetIDString()),0); row->SetField(new BStringField(resData->GetIDString()),0);
row->SetField(new BStringField(data.GetTypeString()),1); row->SetField(new TypeCodeField(resData->GetType(),resData),1);
row->SetField(new BStringField(data.GetName()),2); row->SetField(new BStringField(resData->GetName()),2);
BField *field = gResRoster.MakeFieldForType(data.GetType(), BField *field = gResRoster.MakeFieldForType(resData->GetType(),
data.GetData(), resData->GetData(),
data.GetLength()); resData->GetLength());
if (field) if (field)
row->SetField(field,3); row->SetField(field,3);
row->SetField(new BSizeField(data.GetLength()),4); row->SetField(new BSizeField(resData->GetLength()),4);
fListView->AddRow(row); fListView->AddRow(row);
fDataList.AddItem(resData);
resData = new ResourceData();
index++; index++;
} }
delete resData;
//debugger("");
BNode node; BNode node;
if (node.SetTo(&ref) == B_OK) { if (node.SetTo(&ref) == B_OK) {
char attrName[B_ATTR_NAME_LENGTH]; char attrName[B_ATTR_NAME_LENGTH];
node.RewindAttrs(); node.RewindAttrs();
resData = new ResourceData();
while (node.GetNextAttrName(attrName) == B_OK) { while (node.GetNextAttrName(attrName) == B_OK) {
if (data.SetFromAttribute(attrName, node)) { if (resData->SetFromAttribute(attrName, node)) {
row = new BRow(); row = new BRow();
row->SetField(new BStringField(data.GetIDString()),0); row->SetField(new BStringField(resData->GetIDString()),0);
row->SetField(new BStringField(data.GetTypeString()),1); row->SetField(new TypeCodeField(resData->GetType(),resData),1);
row->SetField(new BStringField(data.GetName()),2); row->SetField(new BStringField(resData->GetName()),2);
BField *field = gResRoster.MakeFieldForType(data.GetType(), BField *field = gResRoster.MakeFieldForType(resData->GetType(),
data.GetData(), resData->GetData(),
data.GetLength()); resData->GetLength());
if (field) if (field)
row->SetField(field,3); row->SetField(field,3);
row->SetField(new BSizeField(data.GetLength()),4); row->SetField(new BSizeField(resData->GetLength()),4);
fListView->AddRow(row); fListView->AddRow(row);
fDataList.AddItem(resData);
resData = new ResourceData();
} }
} }
delete resData;
} }
} }
const void * void
ResView::LoadResource(const type_code &type, const int32 &id, size_t *out_size) ResView::EmptyDataList(void)
{ {
return fResources.LoadResource(type, id, out_size); for (int32 i = 0; i < fDataList.CountItems(); i++) {
ResourceData *data = (ResourceData*) fDataList.ItemAt(i);
delete data;
}
fDataList.MakeEmpty();
} }
const void * void
ResView::LoadResource(const type_code &type, const char *name, size_t *out_size) ResView::UpdateRow(BRow *row)
{ {
return fResources.LoadResource(type, name, out_size); TypeCodeField *typeField = (TypeCodeField*) row->GetField(1);
ResourceData *resData = typeField->GetResourceData();
BStringField *strField = (BStringField *)row->GetField(0);
if (strcmp("(attr)", strField->String()) != 0)
strField->SetString(resData->GetIDString());
strField = (BStringField *)row->GetField(2);
strField->SetString(resData->GetName());
PreviewField *preField = (PreviewField*)row->GetField(3);
preField->SetData(resData->GetData(), resData->GetLength());
BSizeField *sizeField = (BSizeField*)row->GetField(4);
sizeField->SetSize(resData->GetLength());
} }
status_t
ResView::AddResource(const type_code &type, const int32 &id, const void *data,
const size_t &data_size, const char *name)
{
return fResources.AddResource(type, id, data, data_size, name);
}
bool
ResView::HasResource(const type_code &type, const int32 &id)
{
return fResources.HasResource(type, id);
}
bool
ResView::HasResource(const type_code &type, const char *name)
{
return fResources.HasResource(type, name);
}
+5 -13
View File
@@ -13,6 +13,7 @@
#include <Entry.h> #include <Entry.h>
#include <String.h> #include <String.h>
#include <ListItem.h> #include <ListItem.h>
#include <List.h>
#include <Resources.h> #include <Resources.h>
#include "ResourceRoster.h" #include "ResourceRoster.h"
@@ -31,25 +32,16 @@ public:
void OpenFile(const entry_ref &ref); void OpenFile(const entry_ref &ref);
// BResources mirror API
const void * LoadResource(const type_code &type, const int32 &id,
size_t *out_size);
const void * LoadResource(const type_code &type, const char *name,
size_t *out_size);
status_t AddResource(const type_code &type, const int32 &id,
const void *data, const size_t &data_size,
const char *name = NULL);
bool HasResource(const type_code &type, const int32 &id);
bool HasResource(const type_code &type, const char *name);
private: private:
void EmptyDataList(void);
void UpdateRow(BRow *row);
BColumnListView *fListView; BColumnListView *fListView;
entry_ref *fRef; entry_ref *fRef;
BString fFileName; BString fFileName;
BMenuBar *fBar; BMenuBar *fBar;
bool fIsDirty; bool fIsDirty;
BList fDataList;
BResources fResources;
}; };
extern ResourceRoster gResRoster; extern ResourceRoster gResRoster;
+45 -30
View File
@@ -6,6 +6,7 @@
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
*/ */
#include "ResourceData.h" #include "ResourceData.h"
#include "ResFields.h"
#include <stdlib.h> #include <stdlib.h>
ResourceData::ResourceData(void) ResourceData::ResourceData(void)
@@ -16,7 +17,7 @@ ResourceData::ResourceData(void)
fName(""), fName(""),
fData(NULL), fData(NULL),
fLength(0), fLength(0),
fFree(false) fAttr(false)
{ {
} }
@@ -29,11 +30,11 @@ ResourceData::ResourceData(const type_code &code, const int32 &id,
fName(name), fName(name),
fData(data), fData(data),
fLength(length), fLength(length),
fFree(false) fAttr(false)
{ {
fIDString = ""; fIDString = "";
fIDString << fID; fIDString << fID;
MakeTypeString(); fTypeString = MakeTypeString(code);
} }
@@ -45,8 +46,7 @@ ResourceData::ResourceData(const ResourceData &data)
ResourceData::~ResourceData(void) ResourceData::~ResourceData(void)
{ {
if (fFree) free(fData);
free(fData);
} }
@@ -58,13 +58,9 @@ ResourceData::operator=(const ResourceData &data)
fID = data.fID; fID = data.fID;
fIDString = data.fIDString; fIDString = data.fIDString;
fName = data.fName; fName = data.fName;
fLength = data.fLength; fAttr = data.fAttr;
fFree = data.fFree; SetData(data.fData, data.fLength);
// This is an attribute, so we need to allocate and free the data
if (fFree) {
fData = data.fData;
}
return *this; return *this;
} }
@@ -78,11 +74,12 @@ ResourceData::SetFromResource(const int32 &index, BResources &res)
return false; return false;
} }
fName = name; fName = name;
MakeTypeString(); fTypeString = MakeTypeString(fType);
fIDString = ""; fIDString = "";
fIDString << fID; fIDString << fID;
fFree = false; fAttr = false;
fData = (char *)res.LoadResource(fType,fID,&fLength); char *data = (char *)res.LoadResource(fType,fID,&fLength);
SetData(data,fLength);
return true; return true;
} }
@@ -102,9 +99,9 @@ ResourceData::SetFromAttribute(const char *name, BNode &node)
fIDString = "(attr)"; fIDString = "(attr)";
fName = name; fName = name;
fLength = info.size; fLength = info.size;
fFree = true; fAttr = true;
MakeTypeString(); fTypeString = MakeTypeString(fType);
fData = (char *)malloc(fLength); fData = (char *)malloc(fLength);
if (fData) { if (fData) {
@@ -125,27 +122,45 @@ ResourceData::SetTo(const type_code &code, const int32 &id,
const char *name, char *data, const size_t &length) const char *name, char *data, const size_t &length)
{ {
fType = code; fType = code;
fTypeString = MakeTypeString(code);
fID = id; fID = id;
fIDString = "";
fIDString << fID;
fName = name; fName = name;
fData = data; SetData(data,length);
fLength = length;
MakeTypeString();
} }
void void
ResourceData::MakeTypeString(void) ResourceData::SetType(const type_code &code)
{ {
char typestring[7]; fType = code;
char *typeptr = (char *) &fType; fTypeString = MakeTypeString(code);
typestring[0] = '\''; }
typestring[1] = typeptr[3];
typestring[2] = typeptr[2];
typestring[3] = typeptr[1]; void
typestring[4] = typeptr[0]; ResourceData::SetID(const int32 &id)
typestring[5] = '\''; {
typestring[6] = '\0'; fID = id;
fTypeString = typestring; fIDString = "";
fIDString << fID;
}
void
ResourceData::SetData(const char *data, const size_t &size)
{
free(fData);
fLength = size;
if (size > 0) {
fData = (char *)malloc(size);
memcpy(fData,data,size);
}
else
fData = NULL;
} }
+10 -4
View File
@@ -31,17 +31,23 @@ public:
type_code GetType(void) const { return fType; } type_code GetType(void) const { return fType; }
const char * GetTypeString(void) const { return fTypeString.String(); } const char * GetTypeString(void) const { return fTypeString.String(); }
void SetType(const type_code &code);
int32 GetID(void) const { return fID; } int32 GetID(void) const { return fID; }
const char * GetIDString(void) const { return fIDString.String(); } const char * GetIDString(void) const { return fIDString.String(); }
void SetID(const int32 &id);
const char * GetName(void) const { return fName.String(); } const char * GetName(void) const { return fName.String(); }
void SetName(const char *name) { fName = name; }
char * GetData(void) { return fData; } char * GetData(void) { return fData; }
size_t GetLength(void) const { return fLength; } size_t GetLength(void) const { return fLength; }
void SetData(const char *data, const size_t &size);
bool IsAttribute(void) const { return fFree; } bool IsAttribute(void) const { return fAttr; }
void SetAttribute(const bool &value) { fAttr = value; }
private: private:
void MakeTypeString(void);
int32 fType; int32 fType;
BString fTypeString; BString fTypeString;
int32 fID; int32 fID;
@@ -49,7 +55,7 @@ private:
BString fName; BString fName;
char *fData; char *fData;
size_t fLength; size_t fLength;
bool fFree; bool fAttr;
}; };
#endif #endif
+34 -4
View File
@@ -15,6 +15,10 @@
#include <Directory.h> #include <Directory.h>
#include <Bitmap.h> #include <Bitmap.h>
#include "ResourceData.h"
#include "InternalEditors.h"
#include "ResFields.h"
// For the MakeFieldForType temp code // For the MakeFieldForType temp code
#include <TranslatorFormats.h> #include <TranslatorFormats.h>
#include <TranslationUtils.h> #include <TranslationUtils.h>
@@ -77,7 +81,7 @@ ResourceRoster::MakeFieldForType(const int32 &type, const char *data,
// temporary code until editors are done // temporary code until editors are done
switch (type) { switch (type) {
case B_MIME_STRING_TYPE: case B_MIME_STRING_TYPE:
return new BStringField(data); return new StringPreviewField(data);
case B_GIF_FORMAT: case B_GIF_FORMAT:
case B_PPM_FORMAT: case B_PPM_FORMAT:
case B_TGA_FORMAT: case B_TGA_FORMAT:
@@ -88,9 +92,7 @@ ResourceRoster::MakeFieldForType(const int32 &type, const char *data,
BMemoryIO memio(data,length); BMemoryIO memio(data,length);
BBitmap *bitmap = BTranslationUtils::GetBitmap(&memio); BBitmap *bitmap = BTranslationUtils::GetBitmap(&memio);
if (bitmap) { if (bitmap) {
// XXX WARNING! WARNING! Known memory leak BitmapPreviewField *field = new BitmapPreviewField(bitmap);
// This is temp code, so it's OK for the moment
BBitmapField *field = new BBitmapField(bitmap);
return field; return field;
} }
break; break;
@@ -144,3 +146,31 @@ ResourceRoster::LoadEditors(void)
} }
} }
void
ResourceRoster::SpawnEditor(ResourceData *data, BHandler *handler)
{
// temporary code until editors are done
switch (data->GetType()) {
case B_MIME_STRING_TYPE: {
StringEditor *strEd = new StringEditor(BRect(100,100,300,200),
data, handler);
strEd->Show();
break;
}
case B_GIF_FORMAT:
case B_PPM_FORMAT:
case B_TGA_FORMAT:
case B_BMP_FORMAT:
case B_TIFF_FORMAT:
case B_PNG_FORMAT:
case B_JPEG_FORMAT: {
ImageEditor *imgEd = new ImageEditor(BRect(100,100,300,200),
data, handler);
imgEd->Show();
break;
}
default:
break;
}
}
+4 -2
View File
@@ -13,6 +13,7 @@
#include <ColumnListView.h> #include <ColumnListView.h>
class Editor; class Editor;
class ResourceData;
class ResourceRoster class ResourceRoster
{ {
@@ -21,9 +22,10 @@ public:
~ResourceRoster(void); ~ResourceRoster(void);
BField * MakeFieldForType(const int32 &type, const char *data, BField * MakeFieldForType(const int32 &type, const char *data,
const size_t &length); const size_t &length);
void SpawnEditor(ResourceData *data, BHandler *handler);
private: private:
void LoadEditors(void); void LoadEditors(void);
BList fList; BList fList;
}; };