Forgot to add new files to the last checkin
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20114 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e61a091fd0
commit
22c6ae6951
729
src/apps/resedit/BitmapView.cpp
Normal file
729
src/apps/resedit/BitmapView.cpp
Normal file
@ -0,0 +1,729 @@
|
||||
#include "BitmapView.h"
|
||||
#include <Entry.h>
|
||||
#include <TranslationUtils.h>
|
||||
#include <TranslatorRoster.h>
|
||||
#include <TranslatorFormats.h>
|
||||
#include <Clipboard.h>
|
||||
#include <BitmapStream.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Font.h>
|
||||
#include <Alert.h>
|
||||
|
||||
// TODO: Add support for labels
|
||||
|
||||
#define M_REMOVE_IMAGE 'mrmi'
|
||||
#define M_PASTE_IMAGE 'mpsi'
|
||||
|
||||
enum
|
||||
{
|
||||
CLIP_NONE=0,
|
||||
CLIP_BEOS=1,
|
||||
CLIP_SHOWIMAGE=2,
|
||||
CLIP_PRODUCTIVE=3
|
||||
};
|
||||
|
||||
inline void SetRGBColor(rgb_color *col,uint8 r, uint8 g, uint8 b, uint8 a=255);
|
||||
|
||||
void SetRGBColor(rgb_color *col,uint8 r, uint8 g, uint8 b, uint8 a)
|
||||
{
|
||||
if(col)
|
||||
{
|
||||
col->red=r;
|
||||
col->green=g;
|
||||
col->blue=b;
|
||||
col->alpha=a;
|
||||
}
|
||||
}
|
||||
|
||||
BitmapView::BitmapView(BRect frame, const char *name, BMessage *mod, BBitmap *bitmap,
|
||||
const char *label, border_style borderstyle,int32 resize,int32 flags)
|
||||
: BView(frame, name, resize, flags)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
if(bitmap && bitmap->IsValid())
|
||||
fBitmap=bitmap;
|
||||
else
|
||||
fBitmap=NULL;
|
||||
|
||||
if(mod)
|
||||
SetMessage(mod);
|
||||
|
||||
fLabel=label;
|
||||
fBorderStyle=borderstyle;
|
||||
fFixedSize=false;
|
||||
fEnabled=true;
|
||||
fRemovableBitmap=false;
|
||||
fAcceptDrops=true;
|
||||
fAcceptPaste=true;
|
||||
fConstrainDrops=true;
|
||||
fMaxWidth=100;
|
||||
fMaxHeight=100;
|
||||
|
||||
fPopUpMenu=new BPopUpMenu("deletepopup",false,false);
|
||||
fPopUpMenu->AddItem(new BMenuItem("Close This Menu",new BMessage(B_CANCEL)));
|
||||
fPopUpMenu->AddSeparatorItem();
|
||||
|
||||
fPasteItem=new BMenuItem("Paste Photo from Clipboard",new BMessage(M_PASTE_IMAGE));
|
||||
fPopUpMenu->AddItem(fPasteItem);
|
||||
|
||||
fPopUpMenu->AddSeparatorItem();
|
||||
|
||||
fRemoveItem=new BMenuItem("Remove Photo",new BMessage(M_REMOVE_IMAGE));
|
||||
fPopUpMenu->AddItem(fRemoveItem);
|
||||
|
||||
CalculateBitmapRect();
|
||||
|
||||
// Calculate the offsets for each of the words -- the phrase will be center justified
|
||||
fNoPhotoWidths[0]=StringWidth("Drop");
|
||||
fNoPhotoWidths[1]=StringWidth("a");
|
||||
fNoPhotoWidths[2]=StringWidth("Photo");
|
||||
fNoPhotoWidths[3]=StringWidth("Here");
|
||||
|
||||
font_height fh;
|
||||
GetFontHeight(&fh);
|
||||
float totalheight=fh.ascent+fh.descent+fh.leading;
|
||||
float yoffset=(Bounds().Height()-10-(totalheight*4))/2;
|
||||
fNoPhotoOffsets[0].Set( (Bounds().Width()-fNoPhotoWidths[0])/2,totalheight+yoffset);
|
||||
fNoPhotoOffsets[1].Set( (Bounds().Width()-fNoPhotoWidths[1])/2,fNoPhotoOffsets[0].y+totalheight);
|
||||
fNoPhotoOffsets[2].Set( (Bounds().Width()-fNoPhotoWidths[2])/2,fNoPhotoOffsets[1].y+totalheight);
|
||||
fNoPhotoOffsets[3].Set( (Bounds().Width()-fNoPhotoWidths[3])/2,fNoPhotoOffsets[2].y+totalheight);
|
||||
}
|
||||
|
||||
BitmapView::~BitmapView(void)
|
||||
{
|
||||
delete fPopUpMenu;
|
||||
}
|
||||
|
||||
void BitmapView::AttachedToWindow(void)
|
||||
{
|
||||
SetTarget((BHandler*)Window());
|
||||
fPopUpMenu->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
void BitmapView::SetBitmap(BBitmap *bitmap)
|
||||
{
|
||||
if(bitmap && bitmap->IsValid())
|
||||
{
|
||||
if(fBitmap==bitmap)
|
||||
return;
|
||||
|
||||
fBitmap=bitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fBitmap==NULL)
|
||||
return;
|
||||
|
||||
fBitmap=NULL;
|
||||
}
|
||||
|
||||
CalculateBitmapRect();
|
||||
if(!IsHidden())
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void BitmapView::SetEnabled(bool value)
|
||||
{
|
||||
if(fEnabled!=value)
|
||||
{
|
||||
fEnabled=value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void BitmapView::SetLabel(const char *label)
|
||||
{
|
||||
if(fLabel.Compare(label)!=0)
|
||||
{
|
||||
fLabel=label;
|
||||
|
||||
CalculateBitmapRect();
|
||||
if(!IsHidden())
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void BitmapView::SetStyle(border_style style)
|
||||
{
|
||||
if(fBorderStyle!=style)
|
||||
{
|
||||
fBorderStyle=style;
|
||||
|
||||
CalculateBitmapRect();
|
||||
if(!IsHidden())
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void BitmapView::SetFixedSize(bool isfixed)
|
||||
{
|
||||
if(fFixedSize!=isfixed)
|
||||
{
|
||||
fFixedSize=isfixed;
|
||||
|
||||
CalculateBitmapRect();
|
||||
if(!IsHidden())
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void BitmapView::MessageReceived(BMessage *msg)
|
||||
{
|
||||
if(msg->WasDropped() && AcceptsDrops())
|
||||
{
|
||||
// We'll handle two types of drops: those from Tracker and those from ShowImage
|
||||
if(msg->what==B_SIMPLE_DATA)
|
||||
{
|
||||
int32 actions;
|
||||
if(msg->FindInt32("be:actions",&actions)==B_OK)
|
||||
{
|
||||
// ShowImage drop. This is a negotiated drag&drop, so send a reply
|
||||
BMessage reply(B_COPY_TARGET), response;
|
||||
reply.AddString("be:types","image/jpeg");
|
||||
reply.AddString("be:types","image/png");
|
||||
|
||||
msg->SendReply(&reply,&response);
|
||||
|
||||
// now, we've gotten the response
|
||||
if(response.what==B_MIME_DATA)
|
||||
{
|
||||
// Obtain and translate the received data
|
||||
uint8 *imagedata;
|
||||
ssize_t datasize;
|
||||
|
||||
// Try JPEG first
|
||||
if(response.FindData("image/jpeg",B_MIME_DATA,(const void **)&imagedata,&datasize)!=B_OK)
|
||||
{
|
||||
// Try PNG next and piddle out if unsuccessful
|
||||
if(response.FindData("image/png",B_PNG_FORMAT,(const void **)&imagedata,&datasize)!=B_OK)
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up to decode into memory
|
||||
BMemoryIO memio(imagedata,datasize);
|
||||
BTranslatorRoster *roster=BTranslatorRoster::Default();
|
||||
BBitmapStream bstream;
|
||||
|
||||
if(roster->Translate(&memio,NULL,NULL,&bstream, B_TRANSLATOR_BITMAP)==B_OK)
|
||||
{
|
||||
BBitmap *bmp;
|
||||
if(bstream.DetachBitmap(&bmp)!=B_OK)
|
||||
return;
|
||||
|
||||
SetBitmap(bmp);
|
||||
|
||||
if(fConstrainDrops)
|
||||
ConstrainBitmap();
|
||||
|
||||
Invoke();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
entry_ref ref;
|
||||
if(msg->FindRef("refs",&ref)==B_OK)
|
||||
{
|
||||
// Tracker drop
|
||||
BBitmap *bmp=BTranslationUtils::GetBitmap(&ref);
|
||||
if(bmp)
|
||||
{
|
||||
SetBitmap(bmp);
|
||||
|
||||
if(fConstrainDrops)
|
||||
ConstrainBitmap();
|
||||
|
||||
Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch(msg->what)
|
||||
{
|
||||
case M_REMOVE_IMAGE:
|
||||
{
|
||||
BAlert *alert=new BAlert("Mr. Peeps!","This cannot be undone. Remove the image?","Remove",
|
||||
"Cancel");
|
||||
int32 value=alert->Go();
|
||||
if(value==0)
|
||||
{
|
||||
SetBitmap(NULL);
|
||||
|
||||
if(Target())
|
||||
{
|
||||
BMessenger msgr(Target());
|
||||
|
||||
msgr.SendMessage(new BMessage(M_BITMAP_REMOVED));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
case M_PASTE_IMAGE:
|
||||
{
|
||||
PasteBitmap();
|
||||
|
||||
Invoke();
|
||||
}
|
||||
}
|
||||
BView::MessageReceived(msg);
|
||||
}
|
||||
|
||||
void BitmapView::Draw(BRect rect)
|
||||
{
|
||||
if(fBitmap)
|
||||
DrawBitmap(fBitmap,fBitmap->Bounds(),fBitmapRect);
|
||||
else
|
||||
{
|
||||
SetHighColor(0,0,0,80);
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
DrawString("Drop",fNoPhotoOffsets[0]);
|
||||
DrawString("a",fNoPhotoOffsets[1]);
|
||||
DrawString("Photo",fNoPhotoOffsets[2]);
|
||||
DrawString("Here",fNoPhotoOffsets[3]);
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
}
|
||||
|
||||
if(fBorderStyle==B_FANCY_BORDER)
|
||||
{
|
||||
rgb_color base= {216,216,216,255};
|
||||
rgb_color work;
|
||||
|
||||
SetHighColor(base);
|
||||
StrokeRect(Bounds().InsetByCopy(2,2));
|
||||
|
||||
BeginLineArray(12);
|
||||
|
||||
BRect r(Bounds());
|
||||
|
||||
work=tint_color(base,B_DARKEN_2_TINT);
|
||||
AddLine(r.LeftTop(),r.RightTop(),work);
|
||||
AddLine(r.LeftTop(),r.LeftBottom(),work);
|
||||
r.left++;
|
||||
|
||||
work=tint_color(base,B_DARKEN_4_TINT);
|
||||
AddLine(r.RightTop(),r.RightBottom(),work);
|
||||
AddLine(r.LeftBottom(),r.RightBottom(),work);
|
||||
|
||||
r.right--;
|
||||
r.top++;
|
||||
r.bottom--;
|
||||
|
||||
|
||||
work=tint_color(base,B_LIGHTEN_MAX_TINT);
|
||||
AddLine(r.LeftTop(),r.RightTop(),work);
|
||||
AddLine(r.LeftTop(),r.LeftBottom(),work);
|
||||
r.left++;
|
||||
|
||||
work=tint_color(base,B_DARKEN_3_TINT);
|
||||
AddLine(r.RightTop(),r.RightBottom(),work);
|
||||
AddLine(r.LeftBottom(),r.RightBottom(),work);
|
||||
|
||||
// this rect handled by the above StrokeRect, so inset a total of 2 pixels
|
||||
r.left++;
|
||||
r.right-=2;
|
||||
r.top+=2;
|
||||
r.bottom-=2;
|
||||
|
||||
|
||||
work=tint_color(base,B_DARKEN_3_TINT);
|
||||
AddLine(r.LeftTop(),r.RightTop(),work);
|
||||
AddLine(r.LeftTop(),r.LeftBottom(),work);
|
||||
r.left++;
|
||||
|
||||
work=tint_color(base,B_LIGHTEN_MAX_TINT);
|
||||
AddLine(r.RightTop(),r.RightBottom(),work);
|
||||
AddLine(r.LeftBottom(),r.RightBottom(),work);
|
||||
|
||||
r.right--;
|
||||
r.top++;
|
||||
r.bottom--;
|
||||
EndLineArray();
|
||||
|
||||
SetHighColor(tint_color(base,B_DARKEN_2_TINT));
|
||||
StrokeRect(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plain border
|
||||
SetHighColor(0,0,0);
|
||||
StrokeRect(fBitmapRect);
|
||||
}
|
||||
}
|
||||
|
||||
void BitmapView::MouseDown(BPoint pt)
|
||||
{
|
||||
BPoint mousept;
|
||||
uint32 buttons;
|
||||
|
||||
GetMouse(&mousept,&buttons);
|
||||
if(buttons & B_SECONDARY_MOUSE_BUTTON)
|
||||
{
|
||||
ConvertToScreen(&mousept);
|
||||
|
||||
mousept.x= (mousept.x>5) ? mousept.x-5 : 0;
|
||||
mousept.y= (mousept.y>5) ? mousept.y-5 : 0;
|
||||
|
||||
if(AcceptsPaste() && ClipboardHasBitmap())
|
||||
fPasteItem->SetEnabled(true);
|
||||
else
|
||||
fPasteItem->SetEnabled(false);
|
||||
|
||||
if(fRemovableBitmap && fBitmap)
|
||||
fRemoveItem->SetEnabled(true);
|
||||
else
|
||||
fRemoveItem->SetEnabled(false);
|
||||
|
||||
fPopUpMenu->Go(mousept,true,true,true);
|
||||
}
|
||||
}
|
||||
|
||||
void BitmapView::FrameResized(float w, float h)
|
||||
{
|
||||
CalculateBitmapRect();
|
||||
}
|
||||
|
||||
void BitmapView::CalculateBitmapRect(void)
|
||||
{
|
||||
if(!fBitmap || fFixedSize)
|
||||
{
|
||||
fBitmapRect=Bounds().InsetByCopy(1,1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* // Dynamic sizing algorithm
|
||||
// 1) Check to see if either dimension is bigger than the view's display area
|
||||
// 2) If smaller along both axes, make bitmap rect centered and return
|
||||
// 3) Check to see if scaling is to be horizontal or vertical on basis of longer axis
|
||||
// 4) Calculate scaling factor
|
||||
// 5) Scale both axes down by scaling factor, accounting for border width
|
||||
// 6) Center the rectangle in the direction of the smaller axis
|
||||
|
||||
|
||||
uint8 borderwidth=(fBorderStyle==B_FANCY_BORDER)?5:1;
|
||||
|
||||
BRect r(Bounds());
|
||||
r.InsetBy(borderwidth,borderwidth);
|
||||
|
||||
if( (fBitmap->Bounds().Width()<=r.Width()) &&
|
||||
(fBitmap->Bounds().Height()<=r.Height()) )
|
||||
{
|
||||
// Smaller than view, so just center and return
|
||||
fBitmapRect=fBitmap->Bounds();
|
||||
fBitmapRect.OffsetBy( borderwidth+
|
||||
((r.Width()-fBitmapRect.Width()-(borderwidth<<2))/2),
|
||||
((r.Height()-fBitmapRect.Height()-(borderwidth<<2))/2) );
|
||||
return;
|
||||
}
|
||||
|
||||
float multiplier=fBitmap->Bounds().Width()/fBitmap->Bounds().Height();
|
||||
float offset;
|
||||
if(multiplier>1)
|
||||
{
|
||||
// Landscape orientation
|
||||
|
||||
// Scale rectangle to bounds width and center height
|
||||
r.bottom=r.top+(r.Width()/multiplier);
|
||||
|
||||
offset= ((Bounds().Height()-(borderwidth<<1)) - r.Height())/2;
|
||||
r.OffsetBy(0,offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Portrait orientation
|
||||
|
||||
// Scale rectangle to bounds height and center width
|
||||
r.right=r.left+(r.Height()*multiplier);
|
||||
|
||||
offset= ((Bounds().Width()-(borderwidth<<1)) - r.Width())/2;
|
||||
r.OffsetBy(offset,0);
|
||||
}
|
||||
fBitmapRect=r;
|
||||
*/
|
||||
|
||||
uint8 borderwidth=(fBorderStyle==B_FANCY_BORDER)?5:1;
|
||||
|
||||
BRect r(Bounds());
|
||||
fBitmapRect= ScaleRectToFit(fBitmap->Bounds(),r.InsetByCopy(borderwidth,borderwidth));
|
||||
}
|
||||
|
||||
void BitmapView::SetAcceptDrops(bool accept)
|
||||
{
|
||||
fAcceptDrops=accept;
|
||||
}
|
||||
|
||||
void BitmapView::SetAcceptPaste(bool accept)
|
||||
{
|
||||
fAcceptPaste=accept;
|
||||
}
|
||||
|
||||
void BitmapView::SetConstrainDrops(bool value)
|
||||
{
|
||||
fConstrainDrops=value;
|
||||
}
|
||||
|
||||
void BitmapView::MaxBitmapSize(float *width, float *height) const
|
||||
{
|
||||
*width=fMaxWidth;
|
||||
*height=fMaxHeight;
|
||||
}
|
||||
|
||||
void BitmapView::SetMaxBitmapSize(const float &width, const float &height)
|
||||
{
|
||||
fMaxWidth=width;
|
||||
fMaxHeight=height;
|
||||
|
||||
ConstrainBitmap();
|
||||
}
|
||||
|
||||
void BitmapView::SetBitmapRemovable(bool isremovable)
|
||||
{
|
||||
fRemovableBitmap=isremovable;
|
||||
}
|
||||
|
||||
void BitmapView::ConstrainBitmap(void)
|
||||
{
|
||||
if(!fBitmap || fMaxWidth < 1 || fMaxHeight < 1)
|
||||
return;
|
||||
|
||||
BRect r=ScaleRectToFit(fBitmap->Bounds(),BRect(0,0,fMaxWidth-1,fMaxHeight-1));
|
||||
r.OffsetTo(0,0);
|
||||
|
||||
BBitmap *scaled=new BBitmap(r,fBitmap->ColorSpace(),true);
|
||||
BView *view=new BView(r,"drawview",0,0);
|
||||
|
||||
scaled->Lock();
|
||||
scaled->AddChild(view);
|
||||
view->DrawBitmap(fBitmap,fBitmap->Bounds(),scaled->Bounds());
|
||||
scaled->Unlock();
|
||||
|
||||
delete fBitmap;
|
||||
fBitmap=new BBitmap(scaled,false);
|
||||
}
|
||||
|
||||
bool BitmapView::ClipboardHasBitmap(void)
|
||||
{
|
||||
BMessage *clip=NULL,flattened;
|
||||
uint8 clipval=CLIP_NONE;
|
||||
bool returnval;
|
||||
|
||||
if(be_clipboard->Lock())
|
||||
{
|
||||
clip=be_clipboard->Data();
|
||||
if(!clip->IsEmpty())
|
||||
{
|
||||
returnval=(clip->FindMessage("image/bitmap",&flattened)==B_OK);
|
||||
if(returnval)
|
||||
clipval=CLIP_BEOS;
|
||||
else
|
||||
{
|
||||
BString string;
|
||||
returnval=(clip->FindString("class",&string)==B_OK && string=="BBitmap");
|
||||
|
||||
// Try method Gobe Productive uses if that, too, didn't work
|
||||
if(returnval)
|
||||
clipval=CLIP_SHOWIMAGE;
|
||||
else
|
||||
{
|
||||
returnval=(clip->FindMessage("image/x-vnd.Be-bitmap",&flattened)==B_OK);
|
||||
if(returnval)
|
||||
clipval=CLIP_SHOWIMAGE;
|
||||
else
|
||||
clipval=CLIP_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
return (clipval!=CLIP_NONE)?true:false;
|
||||
}
|
||||
|
||||
BBitmap *BitmapView::BitmapFromClipboard(void)
|
||||
{
|
||||
BMessage *clip=NULL,flattened;
|
||||
BBitmap *bitmap;
|
||||
|
||||
if(!be_clipboard->Lock())
|
||||
return NULL;
|
||||
|
||||
clip=be_clipboard->Data();
|
||||
if(!clip)
|
||||
return NULL;
|
||||
|
||||
uint8 clipval=CLIP_NONE;
|
||||
|
||||
// Try ArtPaint-style storage
|
||||
status_t status=clip->FindMessage("image/bitmap",&flattened);
|
||||
|
||||
// If that didn't work, try ShowImage-style
|
||||
if(status!=B_OK)
|
||||
{
|
||||
BString string;
|
||||
status=clip->FindString("class",&string);
|
||||
|
||||
// Try method Gobe Productive uses if that, too, didn't work
|
||||
if(status==B_OK && string=="BBitmap")
|
||||
clipval=CLIP_SHOWIMAGE;
|
||||
else
|
||||
{
|
||||
status=clip->FindMessage("image/x-vnd.Be-bitmap",&flattened);
|
||||
if(status==B_OK)
|
||||
clipval=CLIP_PRODUCTIVE;
|
||||
else
|
||||
clipval=CLIP_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
clipval=CLIP_BEOS;
|
||||
|
||||
be_clipboard->Unlock();
|
||||
|
||||
switch(clipval)
|
||||
{
|
||||
case CLIP_SHOWIMAGE:
|
||||
{
|
||||
// Showimage does it a slightly different way -- it dumps the BBitmap
|
||||
// data directly to the clipboard message instead of packaging it in
|
||||
// a bitmap like everyone else.
|
||||
|
||||
if(!be_clipboard->Lock())
|
||||
return NULL;
|
||||
|
||||
BMessage datamsg(*be_clipboard->Data());
|
||||
|
||||
be_clipboard->Unlock();
|
||||
|
||||
const void *buffer;
|
||||
int32 bufferLength;
|
||||
|
||||
BRect frame;
|
||||
color_space cspace=B_NO_COLOR_SPACE;
|
||||
|
||||
status=datamsg.FindRect("_frame",&frame);
|
||||
if(status!=B_OK)
|
||||
return NULL;
|
||||
|
||||
status=datamsg.FindInt32("_cspace",(int32)cspace);
|
||||
if(status!=B_OK)
|
||||
return NULL;
|
||||
cspace=B_RGBA32;
|
||||
bitmap=new BBitmap(frame,cspace,true);
|
||||
|
||||
status=datamsg.FindData("_data",B_RAW_TYPE,(const void **)&buffer, &bufferLength);
|
||||
if(status!=B_OK)
|
||||
{
|
||||
delete bitmap;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(bitmap->Bits(), buffer, bufferLength);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
case CLIP_PRODUCTIVE:
|
||||
// Productive doesn't name the packaged BBitmap data message the same, but
|
||||
// uses exactly the same data format.
|
||||
|
||||
case CLIP_BEOS:
|
||||
{
|
||||
const void *buffer;
|
||||
int32 bufferLength;
|
||||
|
||||
BRect frame;
|
||||
color_space cspace=B_NO_COLOR_SPACE;
|
||||
|
||||
status=flattened.FindRect("_frame",&frame);
|
||||
if(status!=B_OK)
|
||||
return NULL;
|
||||
|
||||
status=flattened.FindInt32("_cspace",(int32)cspace);
|
||||
if(status!=B_OK)
|
||||
return NULL;
|
||||
cspace=B_RGBA32;
|
||||
bitmap=new BBitmap(frame,cspace,true);
|
||||
|
||||
status=flattened.FindData("_data",B_RAW_TYPE,(const void **)&buffer, &bufferLength);
|
||||
if(status!=B_OK)
|
||||
{
|
||||
delete bitmap;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(bitmap->Bits(), buffer, bufferLength);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// shut the compiler up
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BRect ScaleRectToFit(const BRect &from, const BRect &to)
|
||||
{
|
||||
// Dynamic sizing algorithm
|
||||
// 1) Check to see if either dimension is bigger than the view's display area
|
||||
// 2) If smaller along both axes, make bitmap rect centered and return
|
||||
// 3) Check to see if scaling is to be horizontal or vertical on basis of longer axis
|
||||
// 4) Calculate scaling factor
|
||||
// 5) Scale both axes down by scaling factor, accounting for border width
|
||||
// 6) Center the rectangle in the direction of the smaller axis
|
||||
|
||||
if(!to.IsValid())
|
||||
return from;
|
||||
if(!from.IsValid())
|
||||
return to;
|
||||
|
||||
BRect r(to);
|
||||
|
||||
if( (from.Width()<=r.Width()) &&
|
||||
(from.Height()<=r.Height()) )
|
||||
{
|
||||
// Smaller than view, so just center and return
|
||||
r=from;
|
||||
r.OffsetBy( (to.Width()-r.Width())/2, (to.Height()-r.Height())/2 );
|
||||
return r;
|
||||
}
|
||||
|
||||
float multiplier=from.Width()/from.Height();
|
||||
if(multiplier>1)
|
||||
{
|
||||
// Landscape orientation
|
||||
|
||||
// Scale rectangle to bounds width and center height
|
||||
r.bottom=r.top+(r.Width()/multiplier);
|
||||
|
||||
r.OffsetBy(0,(to.Height() - r.Height())/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Portrait orientation
|
||||
|
||||
// Scale rectangle to bounds height and center width
|
||||
r.right=r.left+(r.Height()*multiplier);
|
||||
|
||||
r.OffsetBy((to.Width() - r.Width())/2,0);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void BitmapView::RemoveBitmap(void)
|
||||
{
|
||||
SetBitmap(NULL);
|
||||
}
|
||||
|
||||
void BitmapView::PasteBitmap(void)
|
||||
{
|
||||
BBitmap *bmp=BitmapFromClipboard();
|
||||
if(bmp)
|
||||
SetBitmap(bmp);
|
||||
|
||||
if(fConstrainDrops)
|
||||
ConstrainBitmap();
|
||||
}
|
93
src/apps/resedit/BitmapView.h
Normal file
93
src/apps/resedit/BitmapView.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef BMPVIEW_H
|
||||
#define BMPVIEW_H
|
||||
|
||||
#include <Message.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Invoker.h>
|
||||
#include <String.h>
|
||||
#include <View.h>
|
||||
#include <PopUpMenu.h>
|
||||
|
||||
enum
|
||||
{
|
||||
M_BITMAP_ADDED='mbma',
|
||||
M_BITMAP_REMOVED='mbmr'
|
||||
};
|
||||
|
||||
class BitmapView : public BView, public BInvoker
|
||||
{
|
||||
public:
|
||||
BitmapView(BRect frame, const char *name, BMessage *mod, BBitmap *bitmap,
|
||||
const char *label = NULL, border_style = B_PLAIN_BORDER,
|
||||
int32 resize = B_FOLLOW_LEFT | B_FOLLOW_TOP, int32 flags = B_WILL_DRAW);
|
||||
~BitmapView(void);
|
||||
virtual void AttachedToWindow(void);
|
||||
|
||||
virtual void Draw(BRect rect);
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
virtual void MouseDown(BPoint pt);
|
||||
virtual void FrameResized(float w, float h);
|
||||
|
||||
virtual void SetBitmap(BBitmap *bitmap);
|
||||
BBitmap *GetBitmap(void) const { return fBitmap; }
|
||||
|
||||
bool IsEnabled(void) const { return fEnabled; }
|
||||
virtual void SetEnabled(bool value);
|
||||
|
||||
// const char *Label(void) const { return fLabel.String(); }
|
||||
// virtual void SetLabel(const char *label);
|
||||
|
||||
border_style Style(void) const { return fBorderStyle; }
|
||||
virtual void SetStyle(border_style style);
|
||||
|
||||
bool IsFixedSize(void) const { return fFixedSize; }
|
||||
void SetFixedSize(bool isfixed);
|
||||
|
||||
bool AcceptsDrops(void) const { return fAcceptDrops; }
|
||||
virtual void SetAcceptDrops(bool accept);
|
||||
|
||||
bool AcceptsPaste(void) const { return fAcceptPaste; }
|
||||
virtual void SetAcceptPaste(bool accept);
|
||||
|
||||
bool ConstrainsDrops(void) const { return fConstrainDrops; }
|
||||
virtual void SetConstrainDrops(bool value);
|
||||
|
||||
void MaxBitmapSize(float *width, float *height) const;
|
||||
virtual void SetMaxBitmapSize(const float &width, const float &height);
|
||||
|
||||
bool IsBitmapRemovable(void) const { return fRemovableBitmap; }
|
||||
void SetBitmapRemovable(bool isremovable);
|
||||
|
||||
void RemoveBitmap(void);
|
||||
void PasteBitmap(void);
|
||||
|
||||
private:
|
||||
void CalculateBitmapRect(void);
|
||||
void ConstrainBitmap(void);
|
||||
|
||||
bool ClipboardHasBitmap(void);
|
||||
BBitmap *BitmapFromClipboard(void);
|
||||
|
||||
float fNoPhotoWidths[4];
|
||||
BPoint fNoPhotoOffsets[4];
|
||||
|
||||
BBitmap *fBitmap;
|
||||
BRect fBitmapRect;
|
||||
bool fEnabled;
|
||||
BString fLabel;
|
||||
border_style fBorderStyle;
|
||||
bool fFixedSize;
|
||||
bool fAcceptDrops;
|
||||
bool fAcceptPaste;
|
||||
bool fConstrainDrops;
|
||||
float fMaxWidth, fMaxHeight;
|
||||
bool fRemovableBitmap;
|
||||
BPopUpMenu *fPopUpMenu;
|
||||
uint32 fMouseButtons;
|
||||
BMenuItem *fPasteItem;
|
||||
BMenuItem *fRemoveItem;
|
||||
};
|
||||
|
||||
BRect ScaleRectToFit(const BRect &from, const BRect &to);
|
||||
|
||||
#endif
|
113
src/apps/resedit/ImageEditor.cpp
Normal file
113
src/apps/resedit/ImageEditor.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
#include "InternalEditors.h"
|
||||
#include "BitmapView.h"
|
||||
#include "ResourceData.h"
|
||||
#include <TranslationUtils.h>
|
||||
#include <DataIO.h>
|
||||
|
||||
#define M_IMAGE_CHANGED 'imch'
|
||||
|
||||
ImageEditor::ImageEditor(const BRect &frame, ResourceData *data, BHandler *owner)
|
||||
: Editor(frame, data, owner)
|
||||
{
|
||||
SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_ZOOMABLE);
|
||||
SetTitle(data->GetName());
|
||||
|
||||
// Set up the image and the viewer for such
|
||||
BMemoryIO memio(data->GetData(),data->GetLength());
|
||||
fImage = BTranslationUtils::GetBitmap(&memio);
|
||||
|
||||
BRect imgsize;
|
||||
if (fImage)
|
||||
imgsize = ScaleRectToFit(fImage->Bounds(),BRect(0,0,200,200));
|
||||
else
|
||||
imgsize.Set(0,0,200,200);
|
||||
|
||||
BView *back = new BView(Bounds(),"back",B_FOLLOW_ALL,B_WILL_DRAW);
|
||||
back->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
AddChild(back);
|
||||
|
||||
BRect r;
|
||||
|
||||
float labelwidth = be_plain_font->StringWidth("ID: ");
|
||||
float strwidth = be_plain_font->StringWidth("(attr) ");
|
||||
|
||||
font_height fh;
|
||||
be_plain_font->GetHeight(&fh);
|
||||
float strheight = fh.ascent + fh.descent + fh.leading + 5;
|
||||
|
||||
fIDBox = new BTextControl(BRect(10,10,10 + (strwidth + labelwidth) + 15,
|
||||
10 + strheight),
|
||||
"id","ID: ",data->GetIDString(), NULL);
|
||||
fIDBox->SetDivider(labelwidth + 5);
|
||||
back->AddChild(fIDBox);
|
||||
|
||||
r = fIDBox->Frame();
|
||||
r.OffsetBy(r.Width() + 10, 0);
|
||||
r.right = Bounds().right - 10;
|
||||
fNameBox = new BTextControl(r,"name","Name: ",data->GetName(), NULL,
|
||||
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
|
||||
fNameBox->SetDivider(be_plain_font->StringWidth("Name: ") + 5);
|
||||
back->AddChild(fNameBox);
|
||||
|
||||
r = imgsize;
|
||||
|
||||
r.OffsetTo( (Bounds().Width() - r.Width()) / 2,fNameBox->Frame().bottom + 10);
|
||||
fImageView = new BitmapView(r,"imageview",new BMessage(M_IMAGE_CHANGED),fImage,
|
||||
NULL, B_PLAIN_BORDER, B_FOLLOW_NONE,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS);
|
||||
back->AddChild(fImageView);
|
||||
fImageView->SetConstrainDrops(false);
|
||||
|
||||
// No limit on bitmap size
|
||||
fImageView->SetMaxBitmapSize(0,0);
|
||||
fImageView->SetBitmapRemovable(false);
|
||||
|
||||
fOK = new BButton(BRect(10,10,11,11),"ok","Cancel",new BMessage(M_UPDATE_RESOURCE),
|
||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||
fOK->ResizeToPreferred();
|
||||
fOK->SetLabel("OK");
|
||||
fOK->MakeDefault(true);
|
||||
back->AddChild(fOK);
|
||||
|
||||
fOK->MoveTo(Bounds().right - fOK->Bounds().Width() - 10,
|
||||
Bounds().bottom - fOK->Bounds().Height() - 10);
|
||||
r = fOK->Frame();
|
||||
|
||||
r.OffsetBy(-r.Width() - 10, 0);
|
||||
fCancel = new BButton(r,"cancel","Cancel",new BMessage(B_QUIT_REQUESTED),
|
||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||
back->AddChild(fCancel);
|
||||
|
||||
ResizeTo(MAX(fImageView->Frame().right, fNameBox->Frame().right) + 20,
|
||||
fImageView->Frame().bottom + fOK->Frame().Height() + 20);
|
||||
}
|
||||
|
||||
|
||||
ImageEditor::~ImageEditor(void)
|
||||
{
|
||||
delete fImage;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ImageEditor::MessageReceived(BMessage *msg)
|
||||
{
|
||||
if (msg->WasDropped()) {
|
||||
fImageView->MessageReceived(msg);
|
||||
} else if (msg->what == M_IMAGE_CHANGED) {
|
||||
fImage = fImageView->GetBitmap();
|
||||
BRect r = ScaleRectToFit(fImage->Bounds(), BRect(0,0,200,200));
|
||||
fImageView->ResizeTo(r.Width(),r.Height());
|
||||
ResizeTo(MAX(fImageView->Frame().right, fNameBox->Frame().right) + 20,
|
||||
fImageView->Frame().bottom + fOK->Frame().Height() + 20);
|
||||
} else
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ImageEditor::FrameResized(float w, float h)
|
||||
{
|
||||
fImageView->MoveTo( (w - fImageView->Bounds().Width()) / 2,
|
||||
fNameBox->Frame().bottom + 10);
|
||||
}
|
94
src/apps/resedit/InlineEditor.cpp
Normal file
94
src/apps/resedit/InlineEditor.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include "InlineEditor.h"
|
||||
#include <MessageFilter.h>
|
||||
#include <Handler.h>
|
||||
|
||||
class EditFilter : public BMessageFilter
|
||||
{
|
||||
public:
|
||||
EditFilter(BTextControl *textbox)
|
||||
: BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE,B_KEY_DOWN)
|
||||
{
|
||||
fTextBox = textbox;
|
||||
}
|
||||
|
||||
~EditFilter(void)
|
||||
{
|
||||
}
|
||||
|
||||
filter_result Filter(BMessage *msg, BHandler **target)
|
||||
{
|
||||
int32 rawchar;
|
||||
msg->FindInt32("raw_char",&rawchar);
|
||||
|
||||
if (rawchar == B_ESCAPE) {
|
||||
BLooper *loop = (*target)->Looper();
|
||||
if (loop) {
|
||||
BMessenger msgr(loop);
|
||||
msgr.SendMessage(B_QUIT_REQUESTED);
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
} else if (rawchar == B_ENTER) {
|
||||
fTextBox->Invoke();
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
|
||||
private:
|
||||
BTextControl *fTextBox;
|
||||
|
||||
};
|
||||
|
||||
InlineEditor::InlineEditor(BMessenger target, const BRect &frame,
|
||||
const char *text)
|
||||
: BWindow(frame,"InlineEditor",B_NO_BORDER_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
|
||||
B_ASYNCHRONOUS_CONTROLS),
|
||||
fMessenger(target),
|
||||
fCommand(M_INLINE_TEXT)
|
||||
{
|
||||
fTextBox = new BTextControl(BRect(0,0,1,1), "inlinebox",NULL, text,
|
||||
new BMessage(fCommand), B_FOLLOW_ALL,
|
||||
B_WILL_DRAW);
|
||||
AddChild(fTextBox);
|
||||
fTextBox->SetDivider(0);
|
||||
fTextBox->MakeFocus(true);
|
||||
|
||||
fTextBox->ResizeToPreferred();
|
||||
fTextBox->ResizeTo(Bounds().Width(),fTextBox->Bounds().Height());
|
||||
ResizeTo(Bounds().Width(), fTextBox->Bounds().Height());
|
||||
|
||||
AddCommonFilter(new EditFilter(fTextBox));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
InlineEditor::QuitRequested(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InlineEditor::SetMessage(BMessage *msg)
|
||||
{
|
||||
fCommand = msg ? msg->what : 0;
|
||||
fTextBox->SetMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InlineEditor::MessageReceived(BMessage *msg)
|
||||
{
|
||||
if (msg->what == fCommand) {
|
||||
fMessenger.SendMessage(msg);
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InlineEditor::WindowActivated(bool active)
|
||||
{
|
||||
if (!active)
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
27
src/apps/resedit/InlineEditor.h
Normal file
27
src/apps/resedit/InlineEditor.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef INLINE_EDITOR
|
||||
#define INLINE_EDITOR
|
||||
|
||||
#include <Window.h>
|
||||
#include <TextControl.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#define M_INLINE_TEXT 'intx'
|
||||
|
||||
class InlineEditor : public BWindow
|
||||
{
|
||||
public:
|
||||
InlineEditor(BMessenger target, const BRect &frame,
|
||||
const char *text);
|
||||
bool QuitRequested(void);
|
||||
void SetMessage(BMessage *msg);
|
||||
void MessageReceived(BMessage *msg);
|
||||
void WindowActivated(bool active);
|
||||
|
||||
private:
|
||||
BTextControl *fTextBox;
|
||||
BMessenger fMessenger;
|
||||
uint32 fCommand;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
85
src/apps/resedit/InternalEditors.h
Normal file
85
src/apps/resedit/InternalEditors.h
Normal file
@ -0,0 +1,85 @@
|
||||
#ifndef INTERNALEDITORS_H
|
||||
#define INTERNALEDITORS_H
|
||||
|
||||
#include <View.h>
|
||||
#include <TextControl.h>
|
||||
#include <Button.h>
|
||||
#include "Editor.h"
|
||||
|
||||
class StringEditView : public BView
|
||||
{
|
||||
public:
|
||||
StringEditView(const BRect &frame);
|
||||
~StringEditView(void);
|
||||
|
||||
void AttachedToWindow(void);
|
||||
|
||||
const char * GetID(void) const { return fIDBox->Text(); }
|
||||
void SetID(const char *idstring) { fIDBox->SetText(idstring); }
|
||||
|
||||
const char * GetName(void) const { return fNameBox->Text(); }
|
||||
void SetName(const char *name) { fNameBox->SetText(name); }
|
||||
|
||||
const char * GetValue(void) const { return fValueBox->Text(); }
|
||||
void SetValue(const char *value) { fValueBox->SetText(value); }
|
||||
|
||||
void EnableID(const bool &value) { fIDBox->SetEnabled(value); }
|
||||
bool IsIDEnabled(void) const { return fIDBox->IsEnabled(); }
|
||||
|
||||
float GetPreferredWidth(void) const;
|
||||
float GetPreferredHeight(void) const;
|
||||
|
||||
private:
|
||||
BTextControl *fIDBox,
|
||||
*fNameBox,
|
||||
*fValueBox;
|
||||
|
||||
BButton *fCancel,
|
||||
*fOK;
|
||||
};
|
||||
|
||||
class DoubleEditor : public Editor
|
||||
{
|
||||
public:
|
||||
DoubleEditor(const BRect &frame, ResourceData *data,
|
||||
BHandler *owner);
|
||||
void MessageReceived(BMessage *msg);
|
||||
|
||||
private:
|
||||
StringEditView *fView;
|
||||
};
|
||||
|
||||
class StringEditor : public Editor
|
||||
{
|
||||
public:
|
||||
StringEditor(const BRect &frame, ResourceData *data,
|
||||
BHandler *owner);
|
||||
void MessageReceived(BMessage *msg);
|
||||
|
||||
private:
|
||||
StringEditView *fView;
|
||||
};
|
||||
|
||||
class BitmapView;
|
||||
|
||||
class ImageEditor : public Editor
|
||||
{
|
||||
public:
|
||||
ImageEditor(const BRect &frame, ResourceData *data,
|
||||
BHandler *owner);
|
||||
~ImageEditor(void);
|
||||
void MessageReceived(BMessage *msg);
|
||||
void FrameResized(float w, float h);
|
||||
|
||||
private:
|
||||
BTextControl *fIDBox;
|
||||
BTextControl *fNameBox;
|
||||
|
||||
BButton *fOK,
|
||||
*fCancel;
|
||||
|
||||
BBitmap *fImage;
|
||||
BitmapView *fImageView;
|
||||
};
|
||||
|
||||
#endif
|
153
src/apps/resedit/MiscEditors.cpp
Normal file
153
src/apps/resedit/MiscEditors.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include "InternalEditors.h"
|
||||
#include "ResourceData.h"
|
||||
#include <Messenger.h>
|
||||
#include <Message.h>
|
||||
#include <String.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
StringEditor::StringEditor(const BRect &frame, ResourceData *data,
|
||||
BHandler *owner)
|
||||
: Editor(frame, data, owner)
|
||||
{
|
||||
if (data->GetName())
|
||||
SetTitle(data->GetName());
|
||||
|
||||
fView = new StringEditView(Bounds());
|
||||
AddChild(fView);
|
||||
|
||||
if (data->IsAttribute())
|
||||
fView->EnableID(false);
|
||||
else
|
||||
fView->SetID(data->GetIDString());
|
||||
fView->SetName(data->GetName());
|
||||
fView->SetValue(data->GetData());
|
||||
|
||||
SetFlags(Flags() | B_NOT_V_RESIZABLE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringEditor::MessageReceived(BMessage *msg)
|
||||
{
|
||||
if (msg->what == M_UPDATE_RESOURCE) {
|
||||
// We have to have an ID, so if the squirrely developer didn't give us
|
||||
// one, don't do anything
|
||||
if (fView->GetID()) {
|
||||
int32 newid = atol(fView->GetID());
|
||||
GetData()->SetID(newid);
|
||||
}
|
||||
GetData()->SetName(fView->GetName());
|
||||
GetData()->SetData(fView->GetValue(),strlen(fView->GetValue()));
|
||||
|
||||
BMessage updatemsg(M_UPDATE_RESOURCE);
|
||||
updatemsg.AddPointer("item",GetData());
|
||||
BMessenger msgr(GetOwner());
|
||||
msgr.SendMessage(&updatemsg);
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
|
||||
} else {
|
||||
Editor::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Editor::Editor(const BRect &frame, ResourceData *data, BHandler *owner)
|
||||
: BWindow(frame, "Untitled", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS),
|
||||
fResData(data),
|
||||
fOwner(owner)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Editor::~Editor(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StringEditView::StringEditView(const BRect &frame)
|
||||
: BView(frame, "edit", B_FOLLOW_ALL, B_WILL_DRAW)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
BRect r;
|
||||
|
||||
float labelwidth = be_plain_font->StringWidth("ID: ");
|
||||
float strwidth = be_plain_font->StringWidth("(attr) ");
|
||||
|
||||
font_height fh;
|
||||
be_plain_font->GetHeight(&fh);
|
||||
float strheight = fh.ascent + fh.descent + fh.leading + 5;
|
||||
|
||||
fIDBox = new BTextControl(BRect(10,10,10 + (strwidth + labelwidth) + 15,
|
||||
10 + strheight),
|
||||
"id","ID: ","", NULL);
|
||||
fIDBox->SetDivider(labelwidth + 5);
|
||||
AddChild(fIDBox);
|
||||
|
||||
r = fIDBox->Frame();
|
||||
r.OffsetBy(r.Width() + 10, 0);
|
||||
r.right = Bounds().right - 10;
|
||||
fNameBox = new BTextControl(r,"name","Name: ","", NULL,
|
||||
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
|
||||
fNameBox->SetDivider(be_plain_font->StringWidth("Name: ") + 5);
|
||||
AddChild(fNameBox);
|
||||
|
||||
r.OffsetBy(0,r.Height() + 10);
|
||||
r.left = 10;
|
||||
fValueBox = new BTextControl(r,"value","Value: ","", NULL,
|
||||
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
|
||||
fValueBox->SetDivider(be_plain_font->StringWidth("Value: ") + 5);
|
||||
AddChild(fValueBox);
|
||||
|
||||
fOK = new BButton(BRect(10,10,11,11),"ok","Cancel",new BMessage(M_UPDATE_RESOURCE),
|
||||
B_FOLLOW_RIGHT);
|
||||
fOK->ResizeToPreferred();
|
||||
fOK->SetLabel("OK");
|
||||
fOK->MakeDefault(true);
|
||||
AddChild(fOK);
|
||||
|
||||
fOK->MoveTo(r.right - fOK->Bounds().Width(), r.bottom + 10);
|
||||
r = fOK->Frame();
|
||||
r.OffsetBy(-r.Width() - 10, 0);
|
||||
fCancel = new BButton(r,"cancel","Cancel",new BMessage(B_QUIT_REQUESTED),
|
||||
B_FOLLOW_RIGHT);
|
||||
AddChild(fCancel);
|
||||
}
|
||||
|
||||
|
||||
StringEditView::~StringEditView(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringEditView::AttachedToWindow(void)
|
||||
{
|
||||
if (Bounds().Height() < fCancel->Frame().bottom + 10)
|
||||
Window()->ResizeTo(Window()->Bounds().Width(), fCancel->Frame().bottom + 10);
|
||||
|
||||
Window()->SetSizeLimits(Window()->Bounds().Width(), 30000,
|
||||
Window()->Bounds().Height(), 30000);
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
StringEditView::GetPreferredWidth(void) const
|
||||
{
|
||||
float idwidth = be_plain_font->StringWidth("ID: ") +
|
||||
be_plain_font->StringWidth("(attr) ") + 15;
|
||||
float namewidth = be_plain_font->StringWidth("Name: ") +
|
||||
be_plain_font->StringWidth(fNameBox->Text()) + 15;
|
||||
return idwidth + namewidth + 30;
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
StringEditView::GetPreferredHeight(void) const
|
||||
{
|
||||
font_height fh;
|
||||
be_plain_font->GetHeight(&fh);
|
||||
float strheight = fh.ascent + fh.descent + fh.leading + 5;
|
||||
return fOK->Frame().Height() + (strheight * 2) + 40;
|
||||
}
|
||||
|
48
src/apps/resedit/NumberEditors.cpp
Normal file
48
src/apps/resedit/NumberEditors.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "InternalEditors.h"
|
||||
#include "ResourceData.h"
|
||||
#include <Messenger.h>
|
||||
#include <Message.h>
|
||||
#include <String.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
DoubleEditor::DoubleEditor(const BRect &frame, ResourceData *data,
|
||||
BHandler *owner)
|
||||
: Editor(frame, data, owner)
|
||||
{
|
||||
if (data->GetName())
|
||||
SetTitle(data->GetName());
|
||||
|
||||
fView = new StringEditView(Bounds());
|
||||
AddChild(fView);
|
||||
|
||||
fView->SetID(data->GetIDString());
|
||||
fView->SetName(data->GetName());
|
||||
fView->SetValue(data->GetData());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DoubleEditor::MessageReceived(BMessage *msg)
|
||||
{
|
||||
if (msg->what == M_UPDATE_RESOURCE) {
|
||||
// We have to have an ID, so if the squirrely developer didn't give us
|
||||
// one, don't do anything
|
||||
if (fView->GetID()) {
|
||||
int32 newid = atol(fView->GetID());
|
||||
GetData()->SetID(newid);
|
||||
}
|
||||
|
||||
GetData()->SetName(fView->GetName());
|
||||
GetData()->SetData(fView->GetValue(),strlen(fView->GetValue()));
|
||||
|
||||
BMessage updatemsg(M_UPDATE_RESOURCE);
|
||||
updatemsg.AddPointer("item",GetData());
|
||||
BMessenger msgr(GetOwner());
|
||||
msgr.SendMessage(&updatemsg);
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
|
||||
} else {
|
||||
Editor::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
177
src/apps/resedit/ResFields.cpp
Normal file
177
src/apps/resedit/ResFields.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
#include "ResFields.h"
|
||||
#include "ResourceData.h"
|
||||
#include <DataIO.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
TypeCodeField::TypeCodeField(const type_code &code, ResourceData *data)
|
||||
: BStringField(MakeTypeString(code).String()),
|
||||
fTypeCode(code),
|
||||
fData(data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PreviewField::PreviewField(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PreviewField::~PreviewField(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BitmapPreviewField::BitmapPreviewField(BBitmap *bitmap)
|
||||
{
|
||||
fBitmap = bitmap;
|
||||
}
|
||||
|
||||
|
||||
BitmapPreviewField::~BitmapPreviewField(void)
|
||||
{
|
||||
delete fBitmap;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BitmapPreviewField::DrawField(BRect rect, BView *parent)
|
||||
{
|
||||
if (fBitmap) {
|
||||
// Scale the fBitmap down to completely fit within the field's height
|
||||
BRect drawrect(fBitmap->Bounds().OffsetToCopy(rect.LeftTop()));
|
||||
if (drawrect.Height() > rect.Height()) {
|
||||
drawrect = rect;
|
||||
drawrect.right = drawrect.left +
|
||||
(fBitmap->Bounds().Width() *
|
||||
(rect.Height() / fBitmap->Bounds().Height()));
|
||||
}
|
||||
|
||||
parent->SetDrawingMode(B_OP_ALPHA);
|
||||
parent->DrawBitmap(fBitmap, fBitmap->Bounds(), drawrect);
|
||||
parent->SetDrawingMode(B_OP_COPY);
|
||||
|
||||
BString out;
|
||||
out << fBitmap->Bounds().IntegerWidth() << " x "
|
||||
<< fBitmap->Bounds().IntegerHeight() << " x "
|
||||
<< (int32(fBitmap->BytesPerRow() / fBitmap->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());
|
||||
parent->DrawString(out.String(), stringrect.LeftTop());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BitmapPreviewField::SetData(char *data, const size_t &length)
|
||||
{
|
||||
BMemoryIO memio(data,length);
|
||||
fBitmap = BTranslationUtils::GetBitmap(&memio);
|
||||
}
|
||||
|
||||
|
||||
IntegerPreviewField::IntegerPreviewField(const int64 &value)
|
||||
{
|
||||
fValue = value;
|
||||
}
|
||||
|
||||
|
||||
IntegerPreviewField::~IntegerPreviewField(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IntegerPreviewField::DrawField(BRect rect, BView *parent)
|
||||
{
|
||||
BPoint point(rect.LeftBottom());
|
||||
point.y -= 2;
|
||||
|
||||
BString string;
|
||||
string << fValue;
|
||||
parent->TruncateString(&string, B_TRUNCATE_MIDDLE, rect.Width() - 14);
|
||||
parent->DrawString(string.String(), point);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IntegerPreviewField::SetData(char *data, const size_t &length)
|
||||
{
|
||||
switch(length) {
|
||||
case 8: {
|
||||
fValue = *((int8*)data);
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
fValue = *((int16*)data);
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
fValue = *((int32*)data);
|
||||
break;
|
||||
}
|
||||
case 64: {
|
||||
fValue = *((int32*)data);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StringPreviewField::StringPreviewField(const char *string)
|
||||
{
|
||||
fClipped = fString = string;
|
||||
}
|
||||
|
||||
|
||||
StringPreviewField::~StringPreviewField(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringPreviewField::DrawField(BRect rect, BView *parent)
|
||||
{
|
||||
BPoint point(rect.LeftBottom());
|
||||
point.y -= 2;
|
||||
|
||||
fClipped = fString;
|
||||
parent->TruncateString(&fClipped, B_TRUNCATE_END, rect.Width() - 14);
|
||||
parent->DrawString(fClipped.String(), point);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringPreviewField::SetData(char *data, const size_t &length)
|
||||
{
|
||||
char *temp = fString.LockBuffer(length + 2);
|
||||
if (temp)
|
||||
memcpy(temp, data, length);
|
||||
temp[length] = '\0';
|
||||
fString.UnlockBuffer();
|
||||
fClipped = fString;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
MakeTypeString(int32 type)
|
||||
{
|
||||
char typestring[7];
|
||||
char *typeptr = (char *) &type;
|
||||
typestring[0] = '\'';
|
||||
typestring[1] = typeptr[3];
|
||||
typestring[2] = typeptr[2];
|
||||
typestring[3] = typeptr[1];
|
||||
typestring[4] = typeptr[0];
|
||||
typestring[5] = '\'';
|
||||
typestring[6] = '\0';
|
||||
return BString(typestring);
|
||||
}
|
75
src/apps/resedit/ResFields.h
Normal file
75
src/apps/resedit/ResFields.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef RESFIELDS_H
|
||||
#define RESFIELDS_H
|
||||
|
||||
#include <ColumnTypes.h>
|
||||
#include <Resources.h>
|
||||
|
||||
class ResourceData;
|
||||
|
||||
class TypeCodeField : public BStringField
|
||||
{
|
||||
public:
|
||||
TypeCodeField(const type_code &code, ResourceData *data);
|
||||
type_code GetTypeCode(void) const { return fTypeCode; }
|
||||
ResourceData * GetResourceData(void) const { return fData; }
|
||||
|
||||
private:
|
||||
type_code fTypeCode;
|
||||
ResourceData *fData;
|
||||
};
|
||||
|
||||
// This is the base class for fields displaying the preview in the Data
|
||||
// column of the main window. Each child class must implement all methods
|
||||
class PreviewField : public BField
|
||||
{
|
||||
public:
|
||||
PreviewField(void);
|
||||
virtual ~PreviewField(void);
|
||||
virtual void DrawField(BRect rect, BView* parent) = 0;
|
||||
virtual void SetData(char *data, const size_t &length) = 0;
|
||||
};
|
||||
|
||||
// Unlike the BBitmapField class, this one actually takes ownership of the
|
||||
// bitmap passed to it. This is good because the bitmap given to it is
|
||||
// allocated by the Translation Kit.
|
||||
class BitmapPreviewField : public PreviewField
|
||||
{
|
||||
public:
|
||||
BitmapPreviewField(BBitmap *bitmap);
|
||||
virtual ~BitmapPreviewField(void);
|
||||
virtual void DrawField(BRect rect, BView* parent);
|
||||
virtual void SetData(char *data, const size_t &length);
|
||||
|
||||
private:
|
||||
BBitmap *fBitmap;
|
||||
};
|
||||
|
||||
class IntegerPreviewField : public PreviewField
|
||||
{
|
||||
public:
|
||||
IntegerPreviewField(const int64 &value);
|
||||
virtual ~IntegerPreviewField(void);
|
||||
virtual void DrawField(BRect rect, BView* parent);
|
||||
virtual void SetData(char *data, const size_t &length);
|
||||
|
||||
private:
|
||||
int64 fValue;
|
||||
};
|
||||
|
||||
|
||||
class StringPreviewField : public PreviewField
|
||||
{
|
||||
public:
|
||||
StringPreviewField(const char *string);
|
||||
virtual ~StringPreviewField(void);
|
||||
virtual void DrawField(BRect rect, BView* parent);
|
||||
virtual void SetData(char *data, const size_t &length);
|
||||
|
||||
private:
|
||||
BString fString;
|
||||
BString fClipped;
|
||||
};
|
||||
|
||||
BString MakeTypeString(int32 type);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user