/* * Copyright 2013-2015, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #include "ImageStopConfigView.h" #include #include #include #include #include #include #include #include #include "AppMessageCodes.h" #include "FunctionInstance.h" #include "Image.h" #include "ImageDebugInfo.h" #include "MessageCodes.h" #include "UserInterface.h" enum { MSG_SET_STOP_FOR_ALL_IMAGES = 'sfai', MSG_SET_STOP_FOR_CUSTOM_IMAGES = 'sfci', MSG_IMAGE_NAME_SELECTION_CHANGED = 'insc', MSG_ADD_IMAGE_NAME = 'anin', MSG_REMOVE_IMAGE_NAME = 'arin', MSG_IMAGE_NAME_INPUT_CHANGED = 'inic' }; static int SortStringItems(const void* a, const void* b) { BStringItem* item1 = *(BStringItem**)a; BStringItem* item2 = *(BStringItem**)b; return strcmp(item1->Text(), item2->Text()); } ImageStopConfigView::ImageStopConfigView(::Team* team, UserInterfaceListener* listener) : BGroupView(B_VERTICAL), fTeam(team), fListener(listener), fStopOnImageLoad(NULL), fStopImageConstraints(NULL), fStopImageNames(NULL), fStopImageNameInput(NULL), fAddImageNameButton(NULL), fRemoveImageNameButton(NULL), fCustomImageGroup(NULL), fStopOnLoadEnabled(false), fUseCustomImages(false) { SetName("Images"); fTeam->AddListener(this); } ImageStopConfigView::~ImageStopConfigView() { fTeam->RemoveListener(this); } ImageStopConfigView* ImageStopConfigView::Create(::Team* team, UserInterfaceListener* listener) { ImageStopConfigView* self = new ImageStopConfigView(team, listener); try { self->_Init(); } catch (...) { delete self; throw; } return self; } void ImageStopConfigView::AttachedToWindow() { fAddImageNameButton->SetEnabled(false); fRemoveImageNameButton->SetEnabled(false); fStopImageConstraints->Menu()->SetTargetForItems(this); fStopOnImageLoad->SetTarget(this); fAddImageNameButton->SetTarget(this); fRemoveImageNameButton->SetTarget(this); fStopImageNames->SetTarget(this); fStopImageNameInput->SetTarget(this); AutoLocker< ::Team> teamLocker(fTeam); _UpdateStopImageState(); BGroupView::AttachedToWindow(); } void ImageStopConfigView::MessageReceived(BMessage* message) { switch (message->what) { case MSG_SET_STOP_FOR_ALL_IMAGES: { fListener->SetStopOnImageLoadRequested( fStopOnImageLoad->Value() == B_CONTROL_ON, false); break; } case MSG_SET_STOP_FOR_CUSTOM_IMAGES: { fListener->SetStopOnImageLoadRequested( fStopOnImageLoad->Value() == B_CONTROL_ON, true); break; } case MSG_IMAGE_NAME_SELECTION_CHANGED: { if (!fUseCustomImages) break; fRemoveImageNameButton->SetEnabled( fStopImageNames->CurrentSelection() >= 0); break; } case MSG_IMAGE_NAME_INPUT_CHANGED: { BString imageName(fStopImageNameInput->Text()); imageName.Trim(); fAddImageNameButton->SetEnabled(!imageName.IsEmpty()); break; } case MSG_STOP_ON_IMAGE_LOAD: { fListener->SetStopOnImageLoadRequested( fStopOnImageLoad->Value() == B_CONTROL_ON, fUseCustomImages); break; } case MSG_STOP_IMAGE_SETTINGS_CHANGED: { _UpdateStopImageState(); break; } case MSG_ADD_IMAGE_NAME: { BString imageName(fStopImageNameInput->Text()); imageName.Trim(); AutoLocker< ::Team> teamLocker(fTeam); if (fTeam->StopImageNames().HasString(imageName)) break; fStopImageNameInput->SetText(""); fListener->AddStopImageNameRequested(imageName.String()); break; } case MSG_STOP_IMAGE_NAME_ADDED: { const char* imageName; if (message->FindString("name", &imageName) != B_OK) break; BStringItem* item = new(std::nothrow) BStringItem(imageName); if (item == NULL) break; ObjectDeleter itemDeleter(item); if (!fStopImageNames->AddItem(item)) { break; } itemDeleter.Detach(); fStopImageNames->SortItems(SortStringItems); break; } case MSG_REMOVE_IMAGE_NAME: { BStringItem* item; int32 selectedIndex; AutoLocker< ::Team> teamLocker(fTeam); int32 i = 0; while ((selectedIndex = fStopImageNames->CurrentSelection(i++)) >= 0) { item = (BStringItem*)fStopImageNames->ItemAt(selectedIndex); fListener->RemoveStopImageNameRequested(item->Text()); } break; } case MSG_STOP_IMAGE_NAME_REMOVED: { const char* imageName; if (message->FindString("name", &imageName) != B_OK) break; for (int32 i = 0; i < fStopImageNames->CountItems(); i++) { BStringItem* item = (BStringItem*)fStopImageNames->ItemAt(i); if (strcmp(item->Text(), imageName) == 0) { fStopImageNames->RemoveItem(i); delete item; } } break; } default: BGroupView::MessageReceived(message); break; } } void ImageStopConfigView::StopOnImageLoadSettingsChanged( const Team::ImageLoadEvent& event) { BMessage message(MSG_STOP_IMAGE_SETTINGS_CHANGED); message.AddBool("enabled", event.StopOnImageLoad()); message.AddBool("useNameList", event.StopImageNameListEnabled()); BMessenger(this).SendMessage(&message); } void ImageStopConfigView::StopOnImageLoadNameAdded( const Team::ImageLoadNameEvent& event) { BMessage message(MSG_STOP_IMAGE_NAME_ADDED); message.AddString("name", event.ImageName()); BMessenger(this).SendMessage(&message); } void ImageStopConfigView::StopOnImageLoadNameRemoved( const Team::ImageLoadNameEvent& event) { BMessage message(MSG_STOP_IMAGE_NAME_REMOVED); message.AddString("name", event.ImageName()); BMessenger(this).SendMessage(&message); } void ImageStopConfigView::_Init() { BMenu* stopImageMenu = new BMenu("stopImageTypesMenu"); stopImageMenu->AddItem(new BMenuItem("All", new BMessage(MSG_SET_STOP_FOR_ALL_IMAGES))); stopImageMenu->AddItem(new BMenuItem("Custom", new BMessage(MSG_SET_STOP_FOR_CUSTOM_IMAGES))); fStopImageNames = new BListView("customImageList", B_MULTIPLE_SELECTION_LIST); fStopImageNames->SetSelectionMessage( new BMessage(MSG_IMAGE_NAME_SELECTION_CHANGED)); fCustomImageGroup = new BGroupView(); BLayoutBuilder::Group<>(fCustomImageGroup, B_VERTICAL, 0.0) .Add(new BScrollView("stopImageScroll", fStopImageNames, 0, false, true)) .Add(fStopImageNameInput = new BTextControl("stopImageName", "Image:", NULL, NULL)) .AddGroup(B_HORIZONTAL) .SetInsets(B_USE_SMALL_SPACING) .AddGlue() .Add(fAddImageNameButton = new BButton("Add", new BMessage(MSG_ADD_IMAGE_NAME))) .Add(fRemoveImageNameButton = new BButton("Remove", new BMessage(MSG_REMOVE_IMAGE_NAME))) .End(); BLayoutBuilder::Group<>(this, B_VERTICAL) .SetInsets(B_USE_SMALL_SPACING) .Add(fStopOnImageLoad = new BCheckBox("stopOnImage", "Stop when an image is loaded", new BMessage(MSG_STOP_ON_IMAGE_LOAD))) .Add(fStopImageConstraints = new BMenuField( "stopTypes", "Types:", stopImageMenu)) .Add(fCustomImageGroup); font_height fontHeight; be_plain_font->GetHeight(&fontHeight); float minListHeight = 5 * (fontHeight.ascent + fontHeight.descent + fontHeight.leading); fStopImageNames->SetExplicitMinSize(BSize(B_SIZE_UNSET, minListHeight)); stopImageMenu->SetLabelFromMarked(true); fStopImageNameInput->SetModificationMessage( new BMessage(MSG_IMAGE_NAME_INPUT_CHANGED)); } void ImageStopConfigView::_UpdateStopImageState() { fStopOnLoadEnabled = fTeam->StopOnImageLoad(); fStopOnImageLoad->SetValue( fStopOnLoadEnabled ? B_CONTROL_ON : B_CONTROL_OFF); fUseCustomImages = fTeam->StopImageNameListEnabled(); fStopImageConstraints->Menu() ->ItemAt(fUseCustomImages ? 1 : 0)->SetMarked(true); fStopImageNames->MakeEmpty(); const BStringList& imageNames = fTeam->StopImageNames(); for (int32 i = 0; i < imageNames.CountStrings(); i++) { BStringItem* item = new(std::nothrow) BStringItem( imageNames.StringAt(i)); if (item == NULL) return; item->SetEnabled(fUseCustomImages); ObjectDeleter itemDeleter(item); if (!fStopImageNames->AddItem(item)) return; itemDeleter.Detach(); } fStopImageConstraints->SetEnabled(fStopOnLoadEnabled); fStopImageNameInput->SetEnabled(fUseCustomImages); }