diff --git a/src/kits/interface/Dragger.cpp b/src/kits/interface/Dragger.cpp index 16ce76c428..3a0138d438 100644 --- a/src/kits/interface/Dragger.cpp +++ b/src/kits/interface/Dragger.cpp @@ -24,9 +24,6 @@ // Description: BDragger represents a replicant "handle". //------------------------------------------------------------------------------ -// Standard Includes ----------------------------------------------------------- - -// System Includes ------------------------------------------------------------- #include #include #include @@ -37,11 +34,8 @@ #include #include -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- +#include +#include // Globals --------------------------------------------------------------------- bool BDragger::sVisible; @@ -247,11 +241,11 @@ BDragger::MouseDown(BPoint where) archive.AddInt32("be:actions", B_TRASH_TARGET); - BBitmap *bitmap; + BPoint offset; - drawing_mode mode; - - if (bitmap = DragBitmap(&offset, &mode)) + drawing_mode mode; + BBitmap *bitmap = DragBitmap(&offset, &mode); + if (bitmap) DragMessage(&archive, bitmap, mode, offset, this); else DragMessage(&archive, @@ -281,8 +275,8 @@ void BDragger::MessageReceived(BMessage *msg) { if (msg->what == B_TRASH_TARGET) { - if(fShelf) - Window()->PostMessage(&BMessage('JAHA'), fTarget, NULL); + if (fShelf) + Window()->PostMessage('JAHA', fTarget, NULL); else (new BAlert("??", "Can't delete this replicant from its original application. Life goes on.", diff --git a/src/kits/interface/PopUpMenu.cpp b/src/kits/interface/PopUpMenu.cpp index e6687a2959..c0c0b763f9 100644 --- a/src/kits/interface/PopUpMenu.cpp +++ b/src/kits/interface/PopUpMenu.cpp @@ -25,13 +25,35 @@ // activate it. //------------------------------------------------------------------------------ -#include "PopUpMenu.h" -#include "MenuItem.h" +#include +#include +#include +#include +#include + + +struct popup_menu_data +{ + BPopUpMenu *object; + BWindow *window; + BMenuItem *selected; + + BPoint where; + BRect rect; + + bool async; + bool auto_invoke; + bool start_opened; + bool use_rect; + + sem_id lock; +}; BPopUpMenu::BPopUpMenu(const char *title, bool radioMode, bool autoRename, - menu_layout layout) - : BMenu(title, layout), + menu_layout layout) + : + BMenu(title, layout), fUseWhere(false), fAutoDestruct(false), fTrackThread(-1) @@ -45,7 +67,8 @@ BPopUpMenu::BPopUpMenu(const char *title, bool radioMode, bool autoRename, BPopUpMenu::BPopUpMenu(BMessage *archive) - : BMenu(archive), + : + BMenu(archive), fUseWhere(false), fAutoDestruct(false), fTrackThread(-1) @@ -55,10 +78,12 @@ BPopUpMenu::BPopUpMenu(BMessage *archive) BPopUpMenu::~BPopUpMenu() { - /*if (fTrackThread != 0) - { - while (wait_for_thread() == ); - }*/ + if (fTrackThread >= 0) { + status_t status; + while (wait_for_thread(fTrackThread, &status) == B_INTERRUPTED) + ; + + } } @@ -82,15 +107,7 @@ BPopUpMenu::Instantiate(BMessage *data) BMenuItem * BPopUpMenu::Go(BPoint where, bool delivers_message, bool open_anyway, bool async) { - //return _go(where, delivers_message, open_anyway, NULL, async); - - if (async) { - fWhere = where; - fUseWhere = true; - Show(); - } - - return NULL; + return _go(where, delivers_message, open_anyway, NULL, async); } @@ -98,9 +115,7 @@ BMenuItem * BPopUpMenu::Go(BPoint where, bool deliversMessage, bool openAnyway, BRect clickToOpen, bool async) { - //return _go(where, deliversMessage, openAnyway, clickToOpen, async); - - return NULL; + return _go(where, deliversMessage, openAnyway, &clickToOpen, async); } @@ -114,21 +129,21 @@ BPopUpMenu::MessageReceived(BMessage *msg) void BPopUpMenu::MouseDown(BPoint point) { - BMenu::MouseDown(point); + BView::MouseDown(point); } void BPopUpMenu::MouseUp(BPoint point) { - BMenu::MouseUp(point); + BView::MouseUp(point); } void BPopUpMenu::MouseMoved(BPoint point, uint32 code, const BMessage *msg) { - BMenu::MouseMoved(point, code, msg); + BView::MouseMoved(point, code, msg); } @@ -271,23 +286,130 @@ BPopUpMenu::operator=(const BPopUpMenu &) BMenuItem * BPopUpMenu::_go(BPoint where, bool autoInvoke, bool startOpened, - BRect *_specialRect, bool async) + BRect *_specialRect, bool async) { - return NULL; + BMenuItem *selected = NULL; + + // Can't use Window(), as the BPopUpMenu isn't attached + BLooper *looper = BLooper::LooperForThread(find_thread(NULL)); + BWindow *window = dynamic_cast(looper); + + popup_menu_data *data = new popup_menu_data; + sem_id sem = create_sem(0, "window close lock"); + + // Asynchronous menu: we set the BWindow semaphore + // and let BWindow do the job for us (??? this is what + // it's probably happening, _set_menu_sem_() is undocumented) + if (async) { + data->window = window; + _set_menu_sem_(window, sem); + } + + data->object = this; + data->auto_invoke = autoInvoke; + data->use_rect = _specialRect != NULL; + if (_specialRect != NULL) + data->rect = *_specialRect; + data->async = async; + data->where = where; + data->start_opened = startOpened; + data->window = NULL; + data->selected = selected; + data->lock = sem; + + // Spawn the tracking thread + thread_id thread = spawn_thread(entry, "popup", B_NORMAL_PRIORITY, data); + + if (thread >= 0) + resume_thread(thread); + else { + // Something went wrong. Cleanup and return NULL + delete_sem(sem); + if (async) + _set_menu_sem_(window, B_NO_MORE_SEMS); + delete data; + return NULL; + } + // Synchronous menu: we block on the sem till + // the other thread deletes it. + if (!async) { + if (window) { + while (acquire_sem_etc(sem, 1, B_TIMEOUT, 50000) != B_BAD_SEM_ID) + window->UpdateIfNeeded(); + } + + status_t unused; + while (wait_for_thread(thread, &unused) == B_INTERRUPTED) + ; + + selected = data->selected; + + delete data; + } + + return selected; } int32 -BPopUpMenu::entry(void *) +BPopUpMenu::entry(void *arg) { - return -1; + popup_menu_data *data = static_cast(arg); + BPopUpMenu *menu = data->object; + + BPoint where = data->where; + BRect *rect = NULL; + bool auto_invoke = data->auto_invoke; + bool start_opened = data->start_opened; + + if (data->use_rect) + rect = &data->rect; + + BMenuItem *selected = menu->start_track(where, auto_invoke, + start_opened, rect); + + // Put the selected item in the shared struct. + data->selected = selected; + + delete_sem(data->lock); + + // Reset the window menu semaphore + if (data->window) + _set_menu_sem_(data->window, B_NO_MORE_SEMS); + + // Commit suicide if needed + if (menu->fAutoDestruct) + delete menu; + + if (data->async) + delete data; + + return 0; } BMenuItem * BPopUpMenu::start_track(BPoint where, bool autoInvoke, - bool startOpened, BRect *_specialRect) + bool startOpened, BRect *_specialRect) { - return NULL; + BMenuItem *result = NULL; + + fUseWhere = true; + fWhere = where; + + // Show the menu's window + Show(); + + // Wait some time then track the menu + snooze(50000); + result = Track(startOpened, _specialRect); + if (result != NULL && autoInvoke) + result->Invoke(); + + fUseWhere = false; + + Hide(); + + return result; } diff --git a/src/kits/interface/Shelf.cpp b/src/kits/interface/Shelf.cpp index eaec840fc2..865f63baa2 100644 --- a/src/kits/interface/Shelf.cpp +++ b/src/kits/interface/Shelf.cpp @@ -42,6 +42,7 @@ #include +#include class _rep_data_ { _rep_data_(BMessage *message, BView *view, BDragger *dragger, @@ -75,7 +76,7 @@ static _rep_data_ *find(BList const *list, BMessage const *msg) { int32 i = 0; _rep_data_ *item; - while (item = (_rep_data_*)list->ItemAt(i++)) { + while ((item = (_rep_data_*)list->ItemAt(i++)) != NULL) { if (item->fMessage == msg) return item; } @@ -87,7 +88,7 @@ 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++)) { + while ((item = (_rep_data_*)list->ItemAt(i++)) != NULL) { if (item->fView == view) return item; @@ -102,7 +103,7 @@ static _rep_data_ *find(BList const *list, unsigned long id) { int32 i = 0; _rep_data_ *item; - while (item = (_rep_data_*)list->ItemAt(i++)) { + while ((item = (_rep_data_*)list->ItemAt(i++)) != NULL) { if (item->fId == id) return item; } @@ -114,7 +115,7 @@ static int32 index_of(BList const *list, BMessage const *msg) { int32 i = 0; _rep_data_ *item; - while (item = (_rep_data_*)list->ItemAt(i++)) { + while ((item = (_rep_data_*)list->ItemAt(i++)) != NULL) { if (item->fMessage == msg) return i; } @@ -126,7 +127,7 @@ 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++)) { + while ((item = (_rep_data_*)list->ItemAt(i++)) != NULL) { if (item->fView == view) return i; @@ -141,7 +142,7 @@ static int32 index_of(BList const *list, unsigned long id) { int32 i = 0; _rep_data_ *item; - while (item = (_rep_data_*)list->ItemAt(i++)) { + while ((item = (_rep_data_*)list->ItemAt(i++)) != NULL) { if (item->fId == id) return i; } @@ -807,7 +808,7 @@ BShelf::RealAddReplicant(BMessage *data, BPoint *loc, uint32 uid) image_id image = B_ERROR; image_id image2 = B_ERROR; _BZombieReplicantView_ *zombie = NULL; - bool wasDropped = data->WasDropped(); + //bool wasDropped = data->WasDropped(); const char *shelf_type = NULL; data->FindString("shelf_type", &shelf_type); @@ -841,12 +842,12 @@ BShelf::RealAddReplicant(BMessage *data, BPoint *loc, uint32 uid) if (data->FindString("class", &_class)) { if (data->FindString("add_on", &add_on)) { - int32 i; + int32 i = 0; _rep_data_ *item; const char *rep_class = NULL; const char *rep_add_on = NULL; - while (item = (_rep_data_*)fReplicants.ItemAt(i++)) { + while ((item = (_rep_data_*)fReplicants.ItemAt(i++)) !=NULL) { item->fMessage->FindString("class", &rep_class); item->fMessage->FindString("add_on", &rep_add_on); @@ -879,14 +880,14 @@ BShelf::RealAddReplicant(BMessage *data, BPoint *loc, uint32 uid) replicant = view; if (archivable2) { - if (dragger = dynamic_cast(archivable2)) { + if ((dragger = dynamic_cast(archivable2)) != NULL) { // Replicant is either a sibling or unknown dragger->SetViewToDrag(replicant); } } } else { // Replicant is child of the dragger - if (dragger = dynamic_cast(view)) + if ((dragger = dynamic_cast(view)) != NULL) dragger->SetViewToDrag(replicant = dragger->ChildAt(0)); else { // Replicant is parent of the dragger diff --git a/src/kits/interface/ZombieReplicantView.cpp b/src/kits/interface/ZombieReplicantView.cpp index 7c49c8dd18..82d262dbcc 100644 --- a/src/kits/interface/ZombieReplicantView.cpp +++ b/src/kits/interface/ZombieReplicantView.cpp @@ -30,7 +30,9 @@ #include +#include #include +#include const static rgb_color kZombieColor = {220, 220, 220, 255};