Adding some more or less complete classes from Marc Flerackers
(BDragger, BShelf and ZombieReplicantView). Not yet added to the build git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8231 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,54 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2004, Haiku
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: ZombieReplicantView.h
|
||||||
|
// Author: Marc Flerackers ([email protected])
|
||||||
|
// Description: Class for Zombie replicants
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef _ZOMBIE_REPLICANT_VIEW_H
|
||||||
|
#define _ZOMBIE_REPLICANT_VIEW_H
|
||||||
|
|
||||||
|
#include <BeBuild.h>
|
||||||
|
#include <Box.h>
|
||||||
|
|
||||||
|
|
||||||
|
// _BZombieReplicantView_ class ------------------------------------------------
|
||||||
|
class _BZombieReplicantView_ : public BBox {
|
||||||
|
|
||||||
|
public:
|
||||||
|
_BZombieReplicantView_(BRect frame, status_t error);
|
||||||
|
virtual ~_BZombieReplicantView_();
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage *msg);
|
||||||
|
|
||||||
|
virtual void Draw(BRect updateRect);
|
||||||
|
|
||||||
|
virtual void MouseDown(BPoint);
|
||||||
|
|
||||||
|
void SetArchive(BMessage *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t fError;
|
||||||
|
BMessage *fArchive;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _ZOMBIE_REPLICANT_VIEW_H */
|
||||||
@@ -0,0 +1,590 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2004, Haiku
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: Dragger.cpp
|
||||||
|
// Author: Marc Flerackers ([email protected])
|
||||||
|
// Description: BDragger represents a replicant "handle".
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <Beep.h>
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <Dragger.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <Shelf.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
bool BDragger::sVisible;
|
||||||
|
bool BDragger::sInited;
|
||||||
|
BLocker BDragger::sLock;
|
||||||
|
BList BDragger::sList;
|
||||||
|
|
||||||
|
static rgb_color kZombieColor = {220, 220, 220, 255};
|
||||||
|
|
||||||
|
const unsigned char kHandBitmap[] = { 255, 255, 0, 0, 0, 255, 255, 255,
|
||||||
|
255, 255, 0, 131, 131, 0, 255, 255,
|
||||||
|
0, 0, 0, 0, 131, 131, 0, 0,
|
||||||
|
0, 131, 0, 0, 131, 131, 0, 0,
|
||||||
|
0, 131, 131, 131, 131, 131, 0, 0,
|
||||||
|
255, 0, 131, 131, 131, 131, 0, 0,
|
||||||
|
255, 255, 0, 0, 0, 0, 0, 0,
|
||||||
|
255, 255, 255, 255, 255, 255, 0, 0};
|
||||||
|
|
||||||
|
|
||||||
|
BDragger::BDragger(BRect bounds, BView *target, uint32 rmask, uint32 flags)
|
||||||
|
: BView(bounds, "_dragger_", rmask, flags),
|
||||||
|
fTarget(target),
|
||||||
|
fRelation(TARGET_UNKNOWN),
|
||||||
|
fShelf(NULL),
|
||||||
|
fTransition(false),
|
||||||
|
fIsZombie(false),
|
||||||
|
fErrCount(0),
|
||||||
|
fPopUp(NULL)
|
||||||
|
{
|
||||||
|
fBitmap = new BBitmap(BRect(0.0f, 0.0f, 7.0f, 7.0f), B_CMAP8, false, false);
|
||||||
|
fBitmap->SetBits(kHandBitmap, fBitmap->BitsLength(), 0, B_CMAP8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BDragger::BDragger(BMessage *data)
|
||||||
|
: BView(data),
|
||||||
|
fTarget(NULL),
|
||||||
|
fRelation(TARGET_UNKNOWN),
|
||||||
|
fShelf(NULL),
|
||||||
|
fTransition(false),
|
||||||
|
fIsZombie(false),
|
||||||
|
fErrCount(0),
|
||||||
|
fPopUp(NULL)
|
||||||
|
{
|
||||||
|
data->FindInt32("_rel", (int32*)&fRelation);
|
||||||
|
|
||||||
|
fBitmap = new BBitmap(BRect(0.0f, 0.0f, 7.0f, 7.0f), B_CMAP8, false, false);
|
||||||
|
fBitmap->SetBits(kHandBitmap, fBitmap->BitsLength(), 0, B_CMAP8);
|
||||||
|
|
||||||
|
BMessage popupMsg;
|
||||||
|
|
||||||
|
if (data->FindMessage("_popup", &popupMsg) == B_OK) {
|
||||||
|
BArchivable *archivable = instantiate_object(&popupMsg);
|
||||||
|
|
||||||
|
if (archivable)
|
||||||
|
fPopUp = dynamic_cast<BPopUpMenu*>(archivable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BDragger::~BDragger()
|
||||||
|
{
|
||||||
|
SetPopUp(NULL);
|
||||||
|
|
||||||
|
delete fBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BArchivable *
|
||||||
|
BDragger::Instantiate(BMessage *data)
|
||||||
|
{
|
||||||
|
if (validate_instantiation(data, "BDragger"))
|
||||||
|
return new BDragger(data);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BDragger::Archive(BMessage *data, bool deep) const
|
||||||
|
{
|
||||||
|
BMessage popupMsg;
|
||||||
|
|
||||||
|
if (fPopUp) {
|
||||||
|
fPopUp->Archive(&popupMsg);
|
||||||
|
data->AddMessage("_popup", &popupMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->AddInt32("_rel", fRelation);
|
||||||
|
|
||||||
|
return BView::Archive(data, deep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::AttachedToWindow()
|
||||||
|
{
|
||||||
|
if (fIsZombie) {
|
||||||
|
SetLowColor(kZombieColor);
|
||||||
|
SetViewColor(kZombieColor);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
SetLowColor(B_TRANSPARENT_COLOR);
|
||||||
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
determine_relationship();
|
||||||
|
ListManage(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::DetachedFromWindow()
|
||||||
|
{
|
||||||
|
ListManage(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::Draw(BRect update)
|
||||||
|
{
|
||||||
|
BRect bounds(Bounds());
|
||||||
|
|
||||||
|
if (AreDraggersDrawn() && (!fShelf || fShelf->AllowsDragging())) {
|
||||||
|
SetDrawingMode(B_OP_OVER);
|
||||||
|
DrawBitmap(fBitmap, bounds.LeftTop());
|
||||||
|
SetDrawingMode(B_OP_COPY);
|
||||||
|
|
||||||
|
if (fIsZombie) {
|
||||||
|
// TODO: should draw it differently ?
|
||||||
|
}
|
||||||
|
} else if (IsVisibilityChanging()) {
|
||||||
|
if (Parent())
|
||||||
|
Parent()->Invalidate(Frame());
|
||||||
|
|
||||||
|
else {
|
||||||
|
SetHighColor(255, 255, 255);
|
||||||
|
FillRect(bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::MouseDown(BPoint where)
|
||||||
|
{
|
||||||
|
if (!fTarget || !AreDraggersDrawn())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 buttons;
|
||||||
|
|
||||||
|
Window()->CurrentMessage()->FindInt32("buttons", &buttons);
|
||||||
|
|
||||||
|
if (buttons & B_SECONDARY_MOUSE_BUTTON) {
|
||||||
|
if (!fShelf || !fTarget) {
|
||||||
|
beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowPopUp(fTarget, where);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// TODO code to determine drag or menu
|
||||||
|
/*bigtime_t time = system_time();
|
||||||
|
bigtime_t click_speed = 0;
|
||||||
|
|
||||||
|
get_click_speed(&click_speed);*/
|
||||||
|
|
||||||
|
bool drag = false;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
BPoint where2;
|
||||||
|
uint32 buttons;
|
||||||
|
|
||||||
|
GetMouse(&where2, &buttons);
|
||||||
|
|
||||||
|
if (!buttons)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (where2 != where) {
|
||||||
|
drag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
snooze(40000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drag) {
|
||||||
|
BMessage archive(B_ARCHIVED_OBJECT);
|
||||||
|
|
||||||
|
if (fRelation == TARGET_IS_PARENT)
|
||||||
|
fTarget->Archive(&archive);
|
||||||
|
else if (fRelation == TARGET_IS_CHILD)
|
||||||
|
Archive(&archive);
|
||||||
|
else {
|
||||||
|
if (fTarget->Archive(&archive)) {
|
||||||
|
BMessage widget(B_ARCHIVED_OBJECT);
|
||||||
|
|
||||||
|
if (Archive(&widget))
|
||||||
|
archive.AddMessage("__widget", &widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
archive.AddInt32("be:actions", B_TRASH_TARGET);
|
||||||
|
|
||||||
|
BBitmap *bitmap;
|
||||||
|
BPoint offset;
|
||||||
|
drawing_mode mode;
|
||||||
|
|
||||||
|
if (bitmap = DragBitmap(&offset, &mode))
|
||||||
|
DragMessage(&archive, bitmap, mode, offset, this);
|
||||||
|
else
|
||||||
|
DragMessage(&archive,
|
||||||
|
ConvertFromScreen(fTarget->ConvertToScreen(fTarget->Bounds())),
|
||||||
|
this);
|
||||||
|
} else
|
||||||
|
ShowPopUp(fTarget, where);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::MouseUp(BPoint pt)
|
||||||
|
{
|
||||||
|
BView::MouseUp(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::MouseMoved(BPoint pt, uint32 code, const BMessage *msg)
|
||||||
|
{
|
||||||
|
BView::MouseMoved(pt, code, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::MessageReceived(BMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg->what == B_TRASH_TARGET) {
|
||||||
|
if(fShelf)
|
||||||
|
Window()->PostMessage(&BMessage('JAHA'), fTarget, NULL);
|
||||||
|
else
|
||||||
|
(new BAlert("??",
|
||||||
|
"Can't delete this replicant from its original application. Life goes on.",
|
||||||
|
"OK", NULL, NULL, B_WIDTH_FROM_WIDEST, B_WARNING_ALERT))->Go(NULL);
|
||||||
|
|
||||||
|
} else if (msg->what == B_SCREEN_CHANGED) {
|
||||||
|
if (fRelation == TARGET_IS_CHILD) {
|
||||||
|
fTransition = true;
|
||||||
|
Draw(BRect());
|
||||||
|
fTransition = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if ((fShelf && (fShelf->AllowsDragging() && AreDraggersDrawn()))
|
||||||
|
|| AreDraggersDrawn())
|
||||||
|
Show();
|
||||||
|
else
|
||||||
|
Hide();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
BView::MessageReceived(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::FrameMoved(BPoint new_position)
|
||||||
|
{
|
||||||
|
BView::FrameMoved(new_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::FrameResized(float new_width, float new_height)
|
||||||
|
{
|
||||||
|
BView::FrameResized(new_width, new_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BDragger::ShowAllDraggers()
|
||||||
|
{
|
||||||
|
// TODO: Implement. Should ask the registrar or the app server
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BDragger::HideAllDraggers()
|
||||||
|
{
|
||||||
|
// TODO: Implement. Should ask the registrar or the app server
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BDragger::AreDraggersDrawn()
|
||||||
|
{
|
||||||
|
// TODO: Implement. Should ask the registrar or the app server
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BHandler *BDragger::ResolveSpecifier(BMessage *msg, int32 index,
|
||||||
|
BMessage *specifier, int32 form,
|
||||||
|
const char *property)
|
||||||
|
{
|
||||||
|
return BView::ResolveSpecifier(msg, index, specifier, form, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BDragger::GetSupportedSuites(BMessage *data)
|
||||||
|
{
|
||||||
|
return GetSupportedSuites(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BDragger::Perform(perform_code d, void *arg)
|
||||||
|
{
|
||||||
|
return Perform(d, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::ResizeToPreferred()
|
||||||
|
{
|
||||||
|
BView::ResizeToPreferred();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::GetPreferredSize(float *width, float *height)
|
||||||
|
{
|
||||||
|
BView::GetPreferredSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::MakeFocus(bool state)
|
||||||
|
{
|
||||||
|
BView::MakeFocus(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::AllAttached()
|
||||||
|
{
|
||||||
|
BView::AllAttached();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::AllDetached()
|
||||||
|
{
|
||||||
|
BView::AllDetached();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BDragger::SetPopUp(BPopUpMenu *context_menu)
|
||||||
|
{
|
||||||
|
if (fPopUp && fPopUp != context_menu)
|
||||||
|
delete fPopUp;
|
||||||
|
|
||||||
|
fPopUp = context_menu;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BPopUpMenu *
|
||||||
|
BDragger::PopUp() const
|
||||||
|
{
|
||||||
|
if (!fPopUp && fTarget)
|
||||||
|
const_cast<BDragger*>(this)->BuildDefaultPopUp();
|
||||||
|
|
||||||
|
return fPopUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BDragger::InShelf() const
|
||||||
|
{
|
||||||
|
return fShelf != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BView *
|
||||||
|
BDragger::Target() const
|
||||||
|
{
|
||||||
|
return fTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BBitmap *
|
||||||
|
BDragger::DragBitmap(BPoint *offset, drawing_mode *mode)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BDragger::IsVisibilityChanging() const
|
||||||
|
{
|
||||||
|
return fTransition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BDragger::_ReservedDragger2() {}
|
||||||
|
void BDragger::_ReservedDragger3() {}
|
||||||
|
void BDragger::_ReservedDragger4() {}
|
||||||
|
|
||||||
|
|
||||||
|
BDragger &
|
||||||
|
BDragger::operator=(const BDragger &)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::ListManage(bool add)
|
||||||
|
{
|
||||||
|
if (sLock.Lock()) {
|
||||||
|
bool drawn = AreDraggersDrawn();
|
||||||
|
|
||||||
|
if (add) {
|
||||||
|
bool dragging = true;
|
||||||
|
|
||||||
|
sList.AddItem(this);
|
||||||
|
|
||||||
|
if (fShelf)
|
||||||
|
dragging = fShelf->AllowsDragging();
|
||||||
|
|
||||||
|
if (!drawn && !dragging) {
|
||||||
|
if (fRelation != TARGET_IS_CHILD)
|
||||||
|
Hide();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
sList.RemoveItem(this);
|
||||||
|
|
||||||
|
sLock.Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BDragger::determine_relationship()
|
||||||
|
{
|
||||||
|
status_t err = B_OK;
|
||||||
|
|
||||||
|
if (fTarget) {
|
||||||
|
if (fTarget == Parent())
|
||||||
|
fRelation = TARGET_IS_PARENT;
|
||||||
|
else if (fTarget == ChildAt(0))
|
||||||
|
fRelation = TARGET_IS_CHILD;
|
||||||
|
else
|
||||||
|
fRelation = TARGET_IS_SIBLING;
|
||||||
|
} else {
|
||||||
|
if (fRelation == TARGET_IS_PARENT)
|
||||||
|
fTarget = Parent();
|
||||||
|
else if (fRelation == TARGET_IS_CHILD)
|
||||||
|
fTarget = ChildAt(0);
|
||||||
|
else
|
||||||
|
err = B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BDragger::SetViewToDrag(BView *target)
|
||||||
|
{
|
||||||
|
if (target->Window() != Window())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fTarget = target;
|
||||||
|
|
||||||
|
if (Window())
|
||||||
|
determine_relationship();
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::SetShelf(BShelf *shelf)
|
||||||
|
{
|
||||||
|
fShelf = shelf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::SetZombied(bool state)
|
||||||
|
{
|
||||||
|
fIsZombie = state;
|
||||||
|
|
||||||
|
SetLowColor(kZombieColor);
|
||||||
|
SetViewColor(kZombieColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::BuildDefaultPopUp()
|
||||||
|
{
|
||||||
|
fPopUp = new BPopUpMenu("Shelf", false, false, B_ITEMS_IN_COLUMN);
|
||||||
|
|
||||||
|
// About
|
||||||
|
BMessage *msg = new BMessage(B_ABOUT_REQUESTED);
|
||||||
|
|
||||||
|
const char *name = fTarget->Name();
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
msg->AddString("target", name);
|
||||||
|
|
||||||
|
// TODO: Fix this
|
||||||
|
char *about = (char*)malloc(6 + (name ? strlen(name) : 0) + 1);
|
||||||
|
sprintf(about, "About %s", name);
|
||||||
|
|
||||||
|
fPopUp->AddItem(new BMenuItem(about, msg));
|
||||||
|
|
||||||
|
free(about);
|
||||||
|
|
||||||
|
// Seperator
|
||||||
|
fPopUp->AddItem(new BSeparatorItem());
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
msg = new BMessage('JAHA');
|
||||||
|
|
||||||
|
fPopUp->AddItem(new BMenuItem("Delete", msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDragger::ShowPopUp(BView *target, BPoint where)
|
||||||
|
{
|
||||||
|
BPoint point = ConvertToScreen(where);
|
||||||
|
|
||||||
|
if (!fPopUp && fTarget)
|
||||||
|
BuildDefaultPopUp();
|
||||||
|
|
||||||
|
fPopUp->SetTargetForItems(fTarget);
|
||||||
|
|
||||||
|
fPopUp->Go(point, true, false, /*BRect(), */true);
|
||||||
|
}
|
||||||
@@ -0,0 +1,968 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2004, Haiku
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: Shelf.cpp
|
||||||
|
// Author: Marc Flerackers ([email protected])
|
||||||
|
// Description: BShelf stores replicant views that are dropped onto it
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
#include <Beep.h>
|
||||||
|
#include <Dragger.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <Looper.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <MessageFilter.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
#include <Point.h>
|
||||||
|
#include <Rect.h>
|
||||||
|
#include <Shelf.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#include <ZombieReplicantView.h>
|
||||||
|
|
||||||
|
|
||||||
|
class _rep_data_ {
|
||||||
|
_rep_data_(BMessage *message, BView *view, BDragger *dragger,
|
||||||
|
BDragger::relation relation, unsigned long id, image_id image)
|
||||||
|
:
|
||||||
|
fMessage(message),
|
||||||
|
fView(view),
|
||||||
|
fDragger(NULL),
|
||||||
|
fRelation(relation),
|
||||||
|
fId(id),
|
||||||
|
fImage(image),
|
||||||
|
fError(B_OK),
|
||||||
|
fView2(NULL)
|
||||||
|
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
_rep_data_()
|
||||||
|
:
|
||||||
|
fMessage(NULL),
|
||||||
|
fView(NULL),
|
||||||
|
fDragger(NULL),
|
||||||
|
fRelation(BDragger::TARGET_UNKNOWN),
|
||||||
|
fId(0),
|
||||||
|
fError(B_ERROR),
|
||||||
|
fView2(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static _rep_data_ *find(BList const *list, BMessage const *msg)
|
||||||
|
{
|
||||||
|
int32 i = 0;
|
||||||
|
_rep_data_ *item;
|
||||||
|
while (item = (_rep_data_*)list->ItemAt(i++)) {
|
||||||
|
if (item->fMessage == msg)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _rep_data_ *find(BList const *list, BView const *view, bool aBool)
|
||||||
|
{
|
||||||
|
int32 i = 0;
|
||||||
|
_rep_data_ *item;
|
||||||
|
while (item = (_rep_data_*)list->ItemAt(i++)) {
|
||||||
|
if (item->fView == view)
|
||||||
|
return item;
|
||||||
|
|
||||||
|
if (aBool && item->fView2 == view)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _rep_data_ *find(BList const *list, unsigned long id)
|
||||||
|
{
|
||||||
|
int32 i = 0;
|
||||||
|
_rep_data_ *item;
|
||||||
|
while (item = (_rep_data_*)list->ItemAt(i++)) {
|
||||||
|
if (item->fId == id)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 index_of(BList const *list, BMessage const *msg)
|
||||||
|
{
|
||||||
|
int32 i = 0;
|
||||||
|
_rep_data_ *item;
|
||||||
|
while (item = (_rep_data_*)list->ItemAt(i++)) {
|
||||||
|
if (item->fMessage == msg)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 index_of(BList const *list, BView const *view, bool aBool)
|
||||||
|
{
|
||||||
|
int32 i = 0;
|
||||||
|
_rep_data_ *item;
|
||||||
|
while (item = (_rep_data_*)list->ItemAt(i++)) {
|
||||||
|
if (item->fView == view)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
if (aBool && item->fView2 == view)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 index_of(BList const *list, unsigned long id)
|
||||||
|
{
|
||||||
|
int32 i = 0;
|
||||||
|
_rep_data_ *item;
|
||||||
|
while (item = (_rep_data_*)list->ItemAt(i++)) {
|
||||||
|
if (item->fId == id)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class BShelf;
|
||||||
|
|
||||||
|
BMessage *fMessage;
|
||||||
|
BView *fView;
|
||||||
|
BDragger *fDragger;
|
||||||
|
BDragger::relation fRelation;
|
||||||
|
unsigned long fId;
|
||||||
|
image_id fImage;
|
||||||
|
status_t fError;
|
||||||
|
BView *fView2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class _TContainerViewFilter_ : public BMessageFilter {
|
||||||
|
public:
|
||||||
|
_TContainerViewFilter_(BShelf *shelf, BView *view);
|
||||||
|
virtual ~_TContainerViewFilter_();
|
||||||
|
|
||||||
|
filter_result Filter(BMessage *msg, BHandler **handler);
|
||||||
|
filter_result ObjectDropFilter(BMessage *msg, BHandler **handler);
|
||||||
|
|
||||||
|
BShelf *fShelf;
|
||||||
|
BView *fView;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_TContainerViewFilter_::_TContainerViewFilter_(BShelf *shelf, BView *view)
|
||||||
|
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE)
|
||||||
|
{
|
||||||
|
fShelf = shelf;
|
||||||
|
fView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_TContainerViewFilter_::~_TContainerViewFilter_()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
filter_result
|
||||||
|
_TContainerViewFilter_::Filter(BMessage *msg, BHandler **handler)
|
||||||
|
{
|
||||||
|
filter_result filter = B_DISPATCH_MESSAGE;
|
||||||
|
|
||||||
|
if (msg->what == B_ARCHIVED_OBJECT ||
|
||||||
|
msg->what == B_ABOUT_REQUESTED)
|
||||||
|
return ObjectDropFilter(msg, handler);
|
||||||
|
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
filter_result
|
||||||
|
_TContainerViewFilter_::ObjectDropFilter(BMessage *msg, BHandler **_handler)
|
||||||
|
{
|
||||||
|
BView *mouseView;
|
||||||
|
|
||||||
|
if (*_handler)
|
||||||
|
mouseView = dynamic_cast<BView*>(*_handler);
|
||||||
|
else
|
||||||
|
mouseView = NULL;
|
||||||
|
|
||||||
|
if (msg->WasDropped()) {
|
||||||
|
if (!fShelf->fAllowDragging) {
|
||||||
|
printf("Dragging replicants isn't allowed to this shelf.");
|
||||||
|
beep();
|
||||||
|
return B_SKIP_MESSAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BPoint point;
|
||||||
|
BPoint offset;
|
||||||
|
|
||||||
|
if (msg->WasDropped()) {
|
||||||
|
point = msg->DropPoint(&offset);
|
||||||
|
|
||||||
|
point = mouseView->ConvertFromScreen(point - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
BHandler *handler;
|
||||||
|
BLooper *looper;
|
||||||
|
handler = msg->ReturnAddress().Target(&looper);
|
||||||
|
|
||||||
|
BDragger *dragger;
|
||||||
|
|
||||||
|
if (Looper() == looper) {
|
||||||
|
if (handler)
|
||||||
|
dragger = dynamic_cast<BDragger*>(handler);
|
||||||
|
else
|
||||||
|
dragger = NULL;
|
||||||
|
|
||||||
|
if (dragger->fRelation == BDragger::TARGET_IS_CHILD) {
|
||||||
|
BRect rect = dragger->Frame();
|
||||||
|
rect.OffsetTo(point);
|
||||||
|
point = fShelf->AdjustReplicantBy(rect, msg);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
BRect rect = dragger->fTarget->Frame();
|
||||||
|
rect.OffsetTo(point);
|
||||||
|
point = fShelf->AdjustReplicantBy(rect, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dragger->fRelation == BDragger::TARGET_IS_PARENT)
|
||||||
|
dragger->fTarget->MoveTo(point);
|
||||||
|
else if (dragger->fRelation == BDragger::TARGET_IS_CHILD)
|
||||||
|
dragger->MoveTo(point);
|
||||||
|
else {
|
||||||
|
//TODO: TARGET_UNKNOWN/TARGET_SIBLING
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (fShelf->RealAddReplicant(msg, &point, 0) == B_OK)
|
||||||
|
Looper()->DetachCurrentMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_SKIP_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class _TReplicantViewFilter_ : public BMessageFilter {
|
||||||
|
public:
|
||||||
|
_TReplicantViewFilter_(BShelf *shelf, BView *view)
|
||||||
|
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE)
|
||||||
|
{
|
||||||
|
fShelf = shelf;
|
||||||
|
fView = view;
|
||||||
|
}
|
||||||
|
virtual ~_TReplicantViewFilter_()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_result Filter(BMessage *, BHandler **)
|
||||||
|
{
|
||||||
|
return B_DISPATCH_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BShelf *fShelf;
|
||||||
|
BView *fView;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// **** BShelf ****
|
||||||
|
BShelf::BShelf(BView *view, bool allow_drags, const char *shelf_type)
|
||||||
|
: BHandler(shelf_type)
|
||||||
|
{
|
||||||
|
InitData(NULL, NULL, view, allow_drags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BShelf::BShelf(const entry_ref *ref, BView *view, bool allow_drags,
|
||||||
|
const char *shelf_type)
|
||||||
|
: BHandler(shelf_type)
|
||||||
|
{
|
||||||
|
InitData(new BEntry(ref), NULL, view, allow_drags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BShelf::BShelf(BDataIO *stream, BView *view, bool allow_drags,
|
||||||
|
const char *shelf_type)
|
||||||
|
: BHandler(shelf_type)
|
||||||
|
{
|
||||||
|
InitData(NULL, stream, view, allow_drags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BShelf::BShelf(BMessage *data)
|
||||||
|
: BHandler(data)
|
||||||
|
{
|
||||||
|
// TODO: Implement ?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BShelf::~BShelf()
|
||||||
|
{
|
||||||
|
Save();
|
||||||
|
|
||||||
|
delete fEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::Archive(BMessage *data, bool deep) const
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BArchivable *
|
||||||
|
BShelf::Instantiate(BMessage *data)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BShelf::MessageReceived(BMessage *msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::Save()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BShelf::SetDirty(bool state)
|
||||||
|
{
|
||||||
|
fDirty = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShelf::IsDirty() const
|
||||||
|
{
|
||||||
|
return fDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BHandler *
|
||||||
|
BShelf::ResolveSpecifier(BMessage *msg, int32 index,
|
||||||
|
BMessage *specifier, int32 form,
|
||||||
|
const char *property)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::GetSupportedSuites(BMessage *data)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::Perform(perform_code d, void *arg)
|
||||||
|
{
|
||||||
|
return BHandler::Perform(d, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShelf::AllowsDragging() const
|
||||||
|
{
|
||||||
|
return fAllowDragging;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BShelf::SetAllowsDragging(bool state)
|
||||||
|
{
|
||||||
|
fAllowDragging = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShelf::AllowsZombies() const
|
||||||
|
{
|
||||||
|
return fAllowZombies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BShelf::SetAllowsZombies(bool state)
|
||||||
|
{
|
||||||
|
fAllowZombies = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShelf::DisplaysZombies() const
|
||||||
|
{
|
||||||
|
return fDisplayZombies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BShelf::SetDisplaysZombies(bool state)
|
||||||
|
{
|
||||||
|
fDisplayZombies = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShelf::IsTypeEnforced() const
|
||||||
|
{
|
||||||
|
return fTypeEnforced;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BShelf::SetTypeEnforced(bool state)
|
||||||
|
{
|
||||||
|
fTypeEnforced = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::SetSaveLocation(BDataIO *data_io)
|
||||||
|
{
|
||||||
|
fDirty = true;
|
||||||
|
|
||||||
|
if (fEntry) {
|
||||||
|
delete fEntry;
|
||||||
|
fEntry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fStream = data_io;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::SetSaveLocation(const entry_ref *ref)
|
||||||
|
{
|
||||||
|
fDirty = true;
|
||||||
|
|
||||||
|
if (fEntry)
|
||||||
|
delete fEntry;
|
||||||
|
else
|
||||||
|
fStream = NULL;
|
||||||
|
|
||||||
|
fEntry = new BEntry(ref);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BDataIO *
|
||||||
|
BShelf::SaveLocation(entry_ref *ref) const
|
||||||
|
{
|
||||||
|
entry_ref entry;
|
||||||
|
|
||||||
|
if (fStream && ref) {
|
||||||
|
*ref = entry;
|
||||||
|
return fStream;
|
||||||
|
|
||||||
|
} else if (fEntry) {
|
||||||
|
fEntry->GetRef(&entry);
|
||||||
|
|
||||||
|
if (ref)
|
||||||
|
*ref = entry;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
*ref = entry;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::AddReplicant(BMessage *data, BPoint location)
|
||||||
|
{
|
||||||
|
return RealAddReplicant(data, &location, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::DeleteReplicant(BView *replicant)
|
||||||
|
{
|
||||||
|
int32 index = _rep_data_::index_of(&fReplicants, replicant, true);
|
||||||
|
|
||||||
|
_rep_data_ *item = (_rep_data_*)fReplicants.ItemAt(index);
|
||||||
|
|
||||||
|
if (!item)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
bool aBool;
|
||||||
|
|
||||||
|
item->fMessage->FindBool("", &aBool);
|
||||||
|
|
||||||
|
BView *view = item->fView;
|
||||||
|
|
||||||
|
if (!view)
|
||||||
|
view = item->fView2;
|
||||||
|
|
||||||
|
if (view)
|
||||||
|
view->RemoveSelf();
|
||||||
|
|
||||||
|
if (item->fDragger)
|
||||||
|
item->fDragger->RemoveSelf();
|
||||||
|
|
||||||
|
fReplicants.RemoveItem(item);
|
||||||
|
|
||||||
|
if (aBool && item->fImage >= 0)
|
||||||
|
unload_add_on(item->fImage);
|
||||||
|
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::DeleteReplicant(BMessage *data)
|
||||||
|
{
|
||||||
|
int32 index = _rep_data_::index_of(&fReplicants, data);
|
||||||
|
|
||||||
|
_rep_data_ *item = (_rep_data_*)fReplicants.ItemAt(index);
|
||||||
|
|
||||||
|
if (!item)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
bool aBool;
|
||||||
|
|
||||||
|
item->fMessage->FindBool("", &aBool);
|
||||||
|
|
||||||
|
BView *view = item->fView;
|
||||||
|
|
||||||
|
if (!view)
|
||||||
|
view = item->fView2;
|
||||||
|
|
||||||
|
if (view)
|
||||||
|
view->RemoveSelf();
|
||||||
|
|
||||||
|
if (item->fDragger)
|
||||||
|
item->fDragger->RemoveSelf();
|
||||||
|
|
||||||
|
fReplicants.RemoveItem(item);
|
||||||
|
|
||||||
|
if (aBool && item->fImage >= 0)
|
||||||
|
unload_add_on(item->fImage);
|
||||||
|
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::DeleteReplicant(int32 index)
|
||||||
|
{
|
||||||
|
_rep_data_ *item = (_rep_data_*)fReplicants.ItemAt(index);
|
||||||
|
|
||||||
|
if (!item)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
bool aBool;
|
||||||
|
|
||||||
|
item->fMessage->FindBool("", &aBool);
|
||||||
|
|
||||||
|
BView *view = item->fView;
|
||||||
|
|
||||||
|
if (!view)
|
||||||
|
view = item->fView2;
|
||||||
|
|
||||||
|
if (view)
|
||||||
|
view->RemoveSelf();
|
||||||
|
|
||||||
|
if (item->fDragger)
|
||||||
|
item->fDragger->RemoveSelf();
|
||||||
|
|
||||||
|
ReplicantDeleted(index, item->fMessage, item->fView);
|
||||||
|
|
||||||
|
fReplicants.RemoveItem(item);
|
||||||
|
|
||||||
|
if (aBool && item->fImage >= 0)
|
||||||
|
unload_add_on(item->fImage);
|
||||||
|
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BShelf::CountReplicants() const
|
||||||
|
{
|
||||||
|
return fReplicants.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMessage *
|
||||||
|
BShelf::ReplicantAt(int32 index, BView **view, uint32 *uid,
|
||||||
|
status_t *perr) const
|
||||||
|
{
|
||||||
|
status_t err = B_ERROR;
|
||||||
|
BMessage *message = NULL;
|
||||||
|
|
||||||
|
_rep_data_ *item = (_rep_data_*)fReplicants.ItemAt(index);
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
message = item->fMessage;
|
||||||
|
*view = item->fView;
|
||||||
|
*uid = item->fId;
|
||||||
|
*perr = item->fError;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
*view = NULL;
|
||||||
|
*uid = 0;
|
||||||
|
*perr = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BShelf::IndexOf(const BView *replicant_view) const
|
||||||
|
{
|
||||||
|
return _rep_data_::index_of(&fReplicants, replicant_view, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BShelf::IndexOf(const BMessage *archive) const
|
||||||
|
{
|
||||||
|
return _rep_data_::index_of(&fReplicants, archive);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BShelf::IndexOf(uint32 id) const
|
||||||
|
{
|
||||||
|
return _rep_data_::index_of(&fReplicants, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShelf::CanAcceptReplicantMessage(BMessage*) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BShelf::CanAcceptReplicantView(BRect, BView*, BMessage*) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BPoint
|
||||||
|
BShelf::AdjustReplicantBy(BRect, BMessage*) const
|
||||||
|
{
|
||||||
|
return B_ORIGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BShelf::ReplicantDeleted(int32 index, const BMessage *archive,
|
||||||
|
const BView *replicant)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BShelf::_ReservedShelf2() {}
|
||||||
|
void BShelf::_ReservedShelf3() {}
|
||||||
|
void BShelf::_ReservedShelf4() {}
|
||||||
|
void BShelf::_ReservedShelf5() {}
|
||||||
|
#if !_PR3_COMPATIBLE_
|
||||||
|
void BShelf::_ReservedShelf6() {}
|
||||||
|
void BShelf::_ReservedShelf7() {}
|
||||||
|
void BShelf::_ReservedShelf8() {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
BShelf::BShelf(const BShelf&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BShelf &
|
||||||
|
BShelf::operator=(const BShelf &)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::_Archive(BMessage *data) const
|
||||||
|
{
|
||||||
|
BHandler::Archive(data);
|
||||||
|
|
||||||
|
data->AddBool("_zom_dsp", DisplaysZombies());
|
||||||
|
data->AddBool("_zom_alw", AllowsZombies());
|
||||||
|
data->AddInt32("_sg_cnt", fGenCount);
|
||||||
|
|
||||||
|
BMessage archive('ARCV');
|
||||||
|
|
||||||
|
// TODO archive replicants
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BShelf::InitData(BEntry *entry, BDataIO *stream, BView *view,
|
||||||
|
bool allow_drags)
|
||||||
|
{
|
||||||
|
fContainerView = view;
|
||||||
|
fStream = NULL;
|
||||||
|
fEntry = entry;
|
||||||
|
fFilter = NULL;
|
||||||
|
fGenCount = 1;
|
||||||
|
fAllowDragging = allow_drags;
|
||||||
|
fDirty = true;
|
||||||
|
fDisplayZombies = false;
|
||||||
|
fAllowZombies = true;
|
||||||
|
fTypeEnforced = false;
|
||||||
|
|
||||||
|
if (entry)
|
||||||
|
fStream = new BFile(entry, B_READ_ONLY);
|
||||||
|
else
|
||||||
|
fStream = stream;
|
||||||
|
|
||||||
|
fFilter = new _TContainerViewFilter_(this, fContainerView);
|
||||||
|
|
||||||
|
fContainerView->AddFilter(fFilter);
|
||||||
|
fContainerView->set_shelf(this);
|
||||||
|
|
||||||
|
if (fStream) {
|
||||||
|
BMessage archive;
|
||||||
|
|
||||||
|
if (archive.Unflatten(fStream) == B_OK) {
|
||||||
|
bool aBool;
|
||||||
|
|
||||||
|
if (!archive.FindBool("_zom_dsp", &aBool))
|
||||||
|
aBool = false;
|
||||||
|
|
||||||
|
SetDisplaysZombies(aBool);
|
||||||
|
|
||||||
|
if (!archive.FindBool("_zom_alw", &aBool))
|
||||||
|
aBool = true;
|
||||||
|
|
||||||
|
SetAllowsZombies(aBool);
|
||||||
|
|
||||||
|
int32 genCount;
|
||||||
|
|
||||||
|
if (!archive.FindInt32("_sg_cnt", &genCount))
|
||||||
|
genCount = 1;
|
||||||
|
|
||||||
|
// TODO find archived replicants
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::RealAddReplicant(BMessage *data, BPoint *loc, uint32 uid)
|
||||||
|
{
|
||||||
|
BView *replicant = NULL;
|
||||||
|
BDragger *dragger = NULL;
|
||||||
|
BDragger::relation relation = BDragger::TARGET_UNKNOWN;
|
||||||
|
BMessage widget;
|
||||||
|
BMessage reply;
|
||||||
|
image_id image = B_ERROR;
|
||||||
|
image_id image2 = B_ERROR;
|
||||||
|
_BZombieReplicantView_ *zombie = NULL;
|
||||||
|
bool wasDropped = data->WasDropped();
|
||||||
|
const char *shelf_type = NULL;
|
||||||
|
|
||||||
|
data->FindString("shelf_type", &shelf_type);
|
||||||
|
|
||||||
|
// Check shelf types if needed
|
||||||
|
if (fTypeEnforced) {
|
||||||
|
if (shelf_type) {
|
||||||
|
if (Name() && strcmp(shelf_type, Name()) != 0) {
|
||||||
|
printf("Replicant was rejected by BShelf: The BShelf's type and the Replicant's type don't match.");
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Replicant was rejected by BShelf: Replicant indicated a <type> (%s), but the shelf does not.", shelf_type);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Replicant was rejected by BShelf: Replicant did not have a <type>");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we can accept this message
|
||||||
|
if (!CanAcceptReplicantMessage(data))
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// Check if we can create multiple instances
|
||||||
|
if (data->FindBool("be:load_each_time")) {
|
||||||
|
const char *_class = NULL;
|
||||||
|
const char *add_on = NULL;
|
||||||
|
|
||||||
|
if (data->FindString("class", &_class)) {
|
||||||
|
if (data->FindString("add_on", &add_on)) {
|
||||||
|
int32 i;
|
||||||
|
_rep_data_ *item;
|
||||||
|
const char *rep_class = NULL;
|
||||||
|
const char *rep_add_on = NULL;
|
||||||
|
|
||||||
|
while (item = (_rep_data_*)fReplicants.ItemAt(i++)) {
|
||||||
|
item->fMessage->FindString("class", &rep_class);
|
||||||
|
item->fMessage->FindString("add_on", &rep_add_on);
|
||||||
|
|
||||||
|
if (strcmp(_class, rep_class) == 0) {
|
||||||
|
if (add_on && rep_add_on && strcmp(_class, rep_class) == 0)
|
||||||
|
printf("Replicant was rejected. Unique replicant already exists. class=%s, signature=%s",
|
||||||
|
rep_class, rep_add_on);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instantiate the object, if this fails we have a zombie
|
||||||
|
BArchivable *archivable = instantiate_object(data, &image);
|
||||||
|
|
||||||
|
if (archivable) {
|
||||||
|
BView *view = dynamic_cast<BView*>(archivable);
|
||||||
|
BPoint point;
|
||||||
|
|
||||||
|
if (loc)
|
||||||
|
point = *loc;
|
||||||
|
else
|
||||||
|
point = view->Frame().LeftTop();
|
||||||
|
|
||||||
|
// Check if we have a dragger archived as "__widget" inside the message
|
||||||
|
if (data->FindMessage("__widget", &widget) == B_OK) {
|
||||||
|
BArchivable *archivable2 = instantiate_object(&widget, &image2);
|
||||||
|
|
||||||
|
replicant = view;
|
||||||
|
|
||||||
|
if (archivable2) {
|
||||||
|
if (dragger = dynamic_cast<BDragger*>(archivable2)) {
|
||||||
|
// Replicant is either a sibling or unknown
|
||||||
|
dragger->SetViewToDrag(replicant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Replicant is child of the dragger
|
||||||
|
if (dragger = dynamic_cast<BDragger*>(view))
|
||||||
|
dragger->SetViewToDrag(replicant = dragger->ChildAt(0));
|
||||||
|
else {
|
||||||
|
// Replicant is parent of the dragger
|
||||||
|
replicant = view;
|
||||||
|
dragger = dynamic_cast<BDragger*>(replicant->FindView("_dragger_"));
|
||||||
|
|
||||||
|
if (dragger)
|
||||||
|
dragger->SetViewToDrag(replicant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dragger->SetShelf(this);
|
||||||
|
|
||||||
|
AddFilter(new _TReplicantViewFilter_(this, replicant));
|
||||||
|
|
||||||
|
fContainerView->AddChild(view);
|
||||||
|
|
||||||
|
} else if (fDisplayZombies && fAllowZombies) {
|
||||||
|
BRect _frame;
|
||||||
|
|
||||||
|
if (data->FindRect("_frame", &_frame) != B_OK)
|
||||||
|
_frame = BRect();
|
||||||
|
|
||||||
|
if (data->WasDropped()) {
|
||||||
|
BPoint dropPoint, offset;
|
||||||
|
dropPoint = data->DropPoint(&offset);
|
||||||
|
|
||||||
|
_frame.OffsetTo(B_ORIGIN);
|
||||||
|
_frame.OffsetTo(fContainerView->ConvertFromScreen(dropPoint)-offset);
|
||||||
|
|
||||||
|
zombie = new _BZombieReplicantView_(_frame, B_ERROR);
|
||||||
|
|
||||||
|
_frame.OffsetTo(B_ORIGIN);
|
||||||
|
|
||||||
|
BDragger *dragger = new BDragger(_frame, zombie);
|
||||||
|
|
||||||
|
dragger->SetShelf(this);
|
||||||
|
dragger->SetZombied(true);
|
||||||
|
|
||||||
|
zombie->AddChild(dragger);
|
||||||
|
|
||||||
|
AddFilter(new _TReplicantViewFilter_(this, zombie));
|
||||||
|
|
||||||
|
fContainerView->AddChild(zombie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data->RemoveName("_drop_point_");
|
||||||
|
data->RemoveName("_drop_offset_");
|
||||||
|
|
||||||
|
_rep_data_ *item = new _rep_data_(data, replicant, dragger, relation, uid,
|
||||||
|
image);
|
||||||
|
|
||||||
|
item->fError = B_OK;
|
||||||
|
item->fView2 = zombie;
|
||||||
|
|
||||||
|
if (zombie)
|
||||||
|
zombie->SetArchive(data);
|
||||||
|
|
||||||
|
fReplicants.AddItem(item);
|
||||||
|
|
||||||
|
if (data->IsSourceWaiting()) {
|
||||||
|
reply.AddInt32("id", uid);
|
||||||
|
reply.AddInt32("error", B_OK);
|
||||||
|
data->SendReply(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BShelf::GetProperty(BMessage *msg, BMessage *reply)
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2004, Haiku
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// File Name: ZombieReplicantView.cpp
|
||||||
|
// Author: Marc Flerackers ([email protected])
|
||||||
|
// Description: Class for Zombie replicants
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <MimeType.h>
|
||||||
|
|
||||||
|
#include <ZombieReplicantView.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
const static rgb_color kZombieColor = {220, 220, 220, 255};
|
||||||
|
|
||||||
|
_BZombieReplicantView_::_BZombieReplicantView_(BRect frame, status_t error)
|
||||||
|
: BBox(frame, "<Zombie>", B_FOLLOW_NONE, B_WILL_DRAW)
|
||||||
|
{
|
||||||
|
fError = error;
|
||||||
|
|
||||||
|
BFont font(be_bold_font);
|
||||||
|
font.SetSize(9.0f); // TODO
|
||||||
|
SetFont(&font);
|
||||||
|
SetViewColor(kZombieColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_BZombieReplicantView_::~_BZombieReplicantView_()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_BZombieReplicantView_::MessageReceived(BMessage *msg)
|
||||||
|
{
|
||||||
|
switch (msg->what) {
|
||||||
|
case B_ABOUT_REQUESTED:
|
||||||
|
{
|
||||||
|
const char *add_on = NULL;
|
||||||
|
char description[B_MIME_TYPE_LENGTH];
|
||||||
|
|
||||||
|
if (fArchive->FindString("add_on", &add_on) == B_OK) {
|
||||||
|
BMimeType type(add_on);
|
||||||
|
type.GetShortDescription(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
char error[1024];
|
||||||
|
|
||||||
|
sprintf(error, "Can't create the \"%s\" replicant because the library is in the Trash. (%s)",
|
||||||
|
description, strerror(fError));
|
||||||
|
|
||||||
|
(new BAlert("Error", error, "OK", NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
BView::MessageReceived(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_BZombieReplicantView_::Draw(BRect updateRect)
|
||||||
|
{
|
||||||
|
BRect bounds(Bounds());
|
||||||
|
font_height fh;
|
||||||
|
|
||||||
|
GetFontHeight(&fh);
|
||||||
|
|
||||||
|
DrawChar('?', BPoint(bounds.Width() / 2.0f - StringWidth("?") / 2.0f,
|
||||||
|
bounds.Height() / 2.0f - fh.ascent / 2.0f));
|
||||||
|
|
||||||
|
BBox::Draw(updateRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_BZombieReplicantView_::MouseDown(BPoint)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_BZombieReplicantView_::SetArchive(BMessage *archive)
|
||||||
|
{
|
||||||
|
fArchive = archive;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user