void LocaleWindow::_EnableDisableLanguages() { DisableUpdates(); for (int32 i = 0; i < fLanguageListView->FullListCountItems(); i++) { LanguageListItem* item = static_cast<LanguageListItem*>( fLanguageListView->FullListItemAt(i)); bool enable = fPreferredListView->ItemForLanguageID(item->ID()) == NULL; if (item->IsEnabled() != enable) { item->SetEnabled(enable); int32 visibleIndex = fLanguageListView->IndexOf(item); if (visibleIndex >= 0) { if (!enable) fLanguageListView->Deselect(visibleIndex); fLanguageListView->InvalidateItem(visibleIndex); } } } SettingsChanged(); EnableUpdates(); }
/** Creates and feeds a LanguageListItem for a single language node * * The created LanguageListItem sin't push_back here. It is passed * to treatLanguageCountries to be pushed back later as each * Language/Country pair is a new entry in the language list * */ void RainbruRPG::Options::xmlLanguage::treatOneLanguage(TiXmlElement* e){ LanguageListItem lli; lli.setLanguageCode(getCommonCode(e)); lli.setLanguageText(getCommonText(e)); treatLanguageCountries(e, lli); }
static int compare_typed_list_items(const BListItem* _a, const BListItem* _b) { // TODO: sort them using collators. LanguageListItem* a = (LanguageListItem*)_a; LanguageListItem* b = (LanguageListItem*)_b; return strcasecmp(a->Text(), b->Text()); }
static int compare_typed_list_items(const BListItem* _a, const BListItem* _b) { static BCollator collator; LanguageListItem* a = (LanguageListItem*)_a; LanguageListItem* b = (LanguageListItem*)_b; return collator.Compare(a->Text(), b->Text()); }
LanguageListItem::LanguageListItem(const LanguageListItem& other) : BStringItem(other.Text()), fID(other.fID), fCode(other.fCode) { }
LanguageListItem* LanguageListView::ItemForLanguageCode(const char* code, int32* _index) const { for (int32 index = 0; index < FullListCountItems(); index++) { LanguageListItem* item = static_cast<LanguageListItem*>(FullListItemAt(index)); if (item->Code() == code) { if (_index != NULL) *_index = index; return item; } } return NULL; }
void LocaleWindow::_PreferredLanguagesChanged() { BMessage preferredLanguages; int index = 0; while (index < fPreferredListView->FullListCountItems()) { // only include subitems: we can guess the superitem from them anyway LanguageListItem* item = static_cast<LanguageListItem*>( fPreferredListView->FullListItemAt(index)); if (item != NULL) preferredLanguages.AddString("language", item->ID()); index++; } MutableLocaleRoster::Default()->SetPreferredLanguages(&preferredLanguages); _EnableDisableLanguages(); }
void LocaleWindow::_PreferredLanguagesChanged() { BMessage update(kMsgSettingsChanged); int index = 0; while (index < fPreferredListView->FullListCountItems()) { // only include subitems: we can guess the superitem // from them anyway LanguageListItem* item = static_cast<LanguageListItem*>( fPreferredListView->FullListItemAt(index)); if (item != NULL) update.AddString("language", item->ID()); index++; } be_app_messenger.SendMessage(&update); _EnableDisableLanguages(); }
LocaleWindow::LocaleWindow() : BWindow(BRect(0, 0, 0, 0), B_TRANSLATE_SYSTEM_NAME("Locale"), B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE | B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), fInitialConventionsItem(NULL), fDefaultConventionsItem(NULL), fFilesystemTranslationCheckbox(NULL) { SetLayout(new BGroupLayout(B_HORIZONTAL)); float spacing = be_control_look->DefaultItemSpacing(); BTabView* tabView = new BTabView("tabview"); BGroupView* languageTab = new BGroupView(B_TRANSLATE("Language"), B_HORIZONTAL, spacing); // first list: available languages fLanguageListView = new LanguageListView("available", B_MULTIPLE_SELECTION_LIST); BScrollView* scrollView = new BScrollView("scroller", fLanguageListView, B_WILL_DRAW | B_FRAME_EVENTS, true, true); fLanguageListView->SetInvocationMessage(new BMessage(kMsgLanguageInvoked)); fLanguageListView->SetDragMessage(new BMessage(kMsgLanguageDragged)); BFont font; fLanguageListView->GetFont(&font); // Fill the language list from the LocaleRoster data BMessage availableLanguages; if (BLocaleRoster::Default()->GetAvailableLanguages(&availableLanguages) == B_OK) { BString currentID; LanguageListItem* lastAddedCountryItem = NULL; for (int i = 0; availableLanguages.FindString("language", i, ¤tID) == B_OK; i++) { // Now get the human-readable, native name for each language BString name; BLanguage currentLanguage(currentID.String()); currentLanguage.GetNativeName(name); // TODO: the following block fails to detect a couple of language // names as containing glyphs we can't render. Why's that? bool hasGlyphs[name.CountChars()]; font.GetHasGlyphs(name.String(), name.CountChars(), hasGlyphs); for (int32 i = 0; i < name.CountChars(); ++i) { if (!hasGlyphs[i]) { // replace by name translated to current language currentLanguage.GetName(name); break; } } LanguageListItem* item = new LanguageListItem(name, currentID.String(), currentLanguage.Code(), currentLanguage.CountryCode()); if (currentLanguage.IsCountrySpecific() && lastAddedCountryItem != NULL && lastAddedCountryItem->Code() == item->Code()) { fLanguageListView->AddUnder(item, lastAddedCountryItem); } else { // This is a language variant, add it at top-level fLanguageListView->AddItem(item); if (!currentLanguage.IsCountrySpecific()) { item->SetExpanded(false); lastAddedCountryItem = item; } } } fLanguageListView->FullListSortItems(compare_typed_list_items); } else { BAlert* alert = new BAlert("Error", B_TRANSLATE("Unable to find the available languages! You can't " "use this preflet!"), B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_STOP_ALERT); alert->Go(); } // Second list: active languages fPreferredListView = new LanguageListView("preferred", B_MULTIPLE_SELECTION_LIST); BScrollView* scrollViewEnabled = new BScrollView("scroller", fPreferredListView, B_WILL_DRAW | B_FRAME_EVENTS, true, true); fPreferredListView->SetInvocationMessage( new BMessage(kMsgPreferredLanguageInvoked)); fPreferredListView->SetDeleteMessage( new BMessage(kMsgPreferredLanguageDeleted)); fPreferredListView->SetDragMessage( new BMessage(kMsgPreferredLanguageDragged)); BLayoutBuilder::Group<>(languageTab) .AddGroup(B_VERTICAL, spacing) .Add(new BStringView("", B_TRANSLATE("Available languages"))) .Add(scrollView) .End() .AddGroup(B_VERTICAL, spacing) .Add(new BStringView("", B_TRANSLATE("Preferred languages"))) .Add(scrollViewEnabled) .End() .SetInsets(spacing, spacing, spacing, spacing); BView* countryTab = new BView(B_TRANSLATE("Formatting"), B_WILL_DRAW); countryTab->SetLayout(new BGroupLayout(B_VERTICAL, 0)); fConventionsListView = new LanguageListView("formatting", B_SINGLE_SELECTION_LIST); scrollView = new BScrollView("scroller", fConventionsListView, B_WILL_DRAW | B_FRAME_EVENTS, true, true); fConventionsListView->SetSelectionMessage( new BMessage(kMsgConventionsSelection)); // get all available formatting conventions (by language) BFormattingConventions defaultConventions; BLocale::Default()->GetFormattingConventions(&defaultConventions); BString conventionID; fInitialConventionsItem = NULL; LanguageListItem* lastAddedConventionsItem = NULL; for (int i = 0; availableLanguages.FindString("language", i, &conventionID) == B_OK; i++) { BFormattingConventions convention(conventionID); BString conventionName; convention.GetName(conventionName); LanguageListItem* item = new LanguageListItem(conventionName, conventionID, convention.LanguageCode(), convention.CountryCode()); if (!strcmp(conventionID, "en_US")) fDefaultConventionsItem = item; if (conventionID.FindFirst('_') >= 0 && lastAddedConventionsItem != NULL && lastAddedConventionsItem->Code() == item->Code()) { if (!strcmp(conventionID, defaultConventions.ID())) { fConventionsListView->Expand(lastAddedConventionsItem); fInitialConventionsItem = item; } fConventionsListView->AddUnder(item, lastAddedConventionsItem); } else { // This conventions-item isn't country-specific, add it at top-level fConventionsListView->AddItem(item); if (conventionID.FindFirst('_') < 0) { item->SetExpanded(false); lastAddedConventionsItem = item; } if (!strcmp(conventionID, defaultConventions.ID())) fInitialConventionsItem = item; } } fConventionsListView->FullListSortItems(compare_typed_list_items); if (fInitialConventionsItem != NULL) { fConventionsListView->Select(fConventionsListView->IndexOf( fInitialConventionsItem)); } fConventionsListView->SetExplicitMinSize(BSize(20 * be_plain_font->Size(), B_SIZE_UNSET)); fFormatView = new FormatSettingsView(); countryTab->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL, spacing) .AddGroup(B_VERTICAL, 3) .Add(scrollView) .End() .Add(fFormatView) .SetInsets(spacing, spacing, spacing, spacing)); BView* optionsTab = new BView(B_TRANSLATE("Options"), B_WILL_DRAW); optionsTab->SetLayout(new BGroupLayout(B_VERTICAL, 0)); fFilesystemTranslationCheckbox = new BCheckBox("filesystemTranslation", B_TRANSLATE("Translate application and folder names in Deskbar and Tracker."), new BMessage(kMsgFilesystemTranslationChanged)); fFilesystemTranslationCheckbox->SetValue( BLocaleRoster::Default()->IsFilesystemTranslationPreferred()); optionsTab->AddChild(BLayoutBuilder::Group<>(B_VERTICAL, spacing) .Add(fFilesystemTranslationCheckbox) .AddGlue() .SetInsets(spacing, spacing, spacing, spacing)); tabView->AddTab(languageTab); tabView->AddTab(countryTab); tabView->AddTab(optionsTab); BButton* button = new BButton(B_TRANSLATE("Defaults"), new BMessage(kMsgDefaults)); fRevertButton = new BButton(B_TRANSLATE("Revert"), new BMessage(kMsgRevert)); fRevertButton->SetEnabled(false); BLayoutBuilder::Group<>(this, B_VERTICAL, spacing) .Add(tabView) .AddGroup(B_HORIZONTAL, spacing) .Add(button) .Add(fRevertButton) .AddGlue() .End() .SetInsets(spacing, spacing, spacing, spacing) .End(); _Refresh(true); _SettingsReverted(); CenterOnScreen(); }
void LocaleWindow::MessageReceived(BMessage* message) { switch (message->what) { case kMsgDefaults: _Defaults(); break; case kMsgRevert: { _Revert(); fFormatView->Revert(); fConventionsListView->DeselectAll(); if (fInitialConventionsItem != NULL) { BListItem* superitem = fConventionsListView->Superitem(fInitialConventionsItem); if (superitem != NULL) superitem->SetExpanded(true); fConventionsListView->Select(fConventionsListView->IndexOf( fInitialConventionsItem)); fConventionsListView->ScrollToSelection(); } _SettingsReverted(); break; } case kMsgSettingsChanged: _SettingsChanged(); break; case kMsgLanguageDragged: { void* target = NULL; if (message->FindPointer("drop_target", &target) != B_OK || target != fPreferredListView) break; // Add from available languages to preferred languages int32 dropIndex; if (message->FindInt32("drop_index", &dropIndex) != B_OK) dropIndex = fPreferredListView->CountItems(); int32 index = 0; for (int32 i = 0; message->FindInt32("index", i, &index) == B_OK; i++) { LanguageListItem* item = static_cast<LanguageListItem*>( fLanguageListView->FullListItemAt(index)); _InsertPreferredLanguage(item, dropIndex++); } break; } case kMsgLanguageInvoked: { int32 index = 0; for (int32 i = 0; message->FindInt32("index", i, &index) == B_OK; i++) { LanguageListItem* item = static_cast<LanguageListItem*>( fLanguageListView->ItemAt(index)); _InsertPreferredLanguage(item); } break; } case kMsgPreferredLanguageDragged: { void* target = NULL; if (fPreferredListView->CountItems() == 1 || message->FindPointer("drop_target", &target) != B_OK) break; if (target == fPreferredListView) { // change ordering int32 dropIndex = message->FindInt32("drop_index"); int32 index = 0; if (message->FindInt32("index", &index) == B_OK && dropIndex != index) { BListItem* item = fPreferredListView->RemoveItem(index); if (dropIndex > index) index--; fPreferredListView->AddItem(item, dropIndex); _PreferredLanguagesChanged(); } break; } // supposed to fall through - remove item } case kMsgPreferredLanguageDeleted: case kMsgPreferredLanguageInvoked: { if (fPreferredListView->CountItems() == 1) break; // Remove from preferred languages int32 index = 0; if (message->FindInt32("index", &index) == B_OK) { delete fPreferredListView->RemoveItem(index); _PreferredLanguagesChanged(); if (message->what == kMsgPreferredLanguageDeleted) fPreferredListView->Select(index); } break; } case kMsgConventionsSelection: { // Country selection changed. // Get the new selected country from the ListView and send it to the // main app event handler. void* listView; if (message->FindPointer("source", &listView) != B_OK) break; BListView* conventionsList = static_cast<BListView*>(listView); if (conventionsList == NULL) break; LanguageListItem* item = static_cast<LanguageListItem*> (conventionsList->ItemAt(conventionsList->CurrentSelection())); if (item == NULL) break; BFormattingConventions conventions(item->ID()); MutableLocaleRoster::Default()->SetDefaultFormattingConventions( conventions); _SettingsChanged(); fFormatView->Refresh(); break; } case kMsgFilesystemTranslationChanged: { MutableLocaleRoster::Default()->SetFilesystemTranslationPreferred( fFilesystemTranslationCheckbox->Value()); BAlert* alert = new BAlert(B_TRANSLATE("Locale"), B_TRANSLATE("Deskbar and Tracker need to be restarted for this " "change to take effect. Would you like to restart them now?"), B_TRANSLATE("Cancel"), B_TRANSLATE("Restart"), NULL, B_WIDTH_FROM_WIDEST, B_IDEA_ALERT); alert->SetShortcut(0, B_ESCAPE); alert->Go(new BInvoker(new BMessage(kMsgRestartTrackerAndDeskbar), NULL, be_app)); break; } default: BWindow::MessageReceived(message); break; } }
LocaleWindow::LocaleWindow() : BWindow(BRect(0, 0, 0, 0), "Locale", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE | B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS) { BCountry* defaultCountry; be_locale_roster->GetDefaultCountry(&defaultCountry); SetLayout(new BGroupLayout(B_HORIZONTAL)); float spacing = be_control_look->DefaultItemSpacing(); BTabView* tabView = new BTabView("tabview"); BGroupView* languageTab = new BGroupView(B_TRANSLATE("Language"), B_HORIZONTAL, spacing); // first list: available languages fLanguageListView = new LanguageListView("available", B_MULTIPLE_SELECTION_LIST); BScrollView* scrollView = new BScrollView("scroller", fLanguageListView, B_WILL_DRAW | B_FRAME_EVENTS, false, true); fLanguageListView->SetInvocationMessage(new BMessage(kMsgLanguageInvoked)); fLanguageListView->SetDragMessage(new BMessage(kMsgLanguageDragged)); // Fill the language list from the LocaleRoster data BMessage installedLanguages; if (be_locale_roster->GetInstalledLanguages(&installedLanguages) == B_OK) { BString currentID; LanguageListItem* lastAddedCountryItem = NULL; for (int i = 0; installedLanguages.FindString("langs", i, ¤tID) == B_OK; i++) { // Now get an human-readable, localized name for each language BLanguage* currentLanguage; be_locale_roster->GetLanguage(currentID.String(), ¤tLanguage); BString name; currentLanguage->GetName(name); // TODO: as long as the app_server doesn't support font overlays, // use the translated name if problematic characters are used... const char* string = name.String(); while (uint32 code = BUnicodeChar::FromUTF8(&string)) { if (code > 1424) { currentLanguage->GetTranslatedName(name); break; } } LanguageListItem* item = new LanguageListItem(name, currentID.String(), currentLanguage->Code()); if (currentLanguage->IsCountrySpecific() && lastAddedCountryItem != NULL && lastAddedCountryItem->Code() == item->Code()) { fLanguageListView->AddUnder(item, lastAddedCountryItem); } else { // This is a language variant, add it at top-level fLanguageListView->AddItem(item); if (!currentLanguage->IsCountrySpecific()) { item->SetExpanded(false); lastAddedCountryItem = item; } } delete currentLanguage; } fLanguageListView->FullListSortItems(compare_typed_list_items); } else { BAlert* alert = new BAlert("Error", B_TRANSLATE("Unable to find the available languages! You can't " "use this preflet!"), B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_STOP_ALERT); alert->Go(); } // Second list: active languages fPreferredListView = new LanguageListView("preferred", B_MULTIPLE_SELECTION_LIST); BScrollView* scrollViewEnabled = new BScrollView("scroller", fPreferredListView, B_WILL_DRAW | B_FRAME_EVENTS, false, true); fPreferredListView->SetInvocationMessage( new BMessage(kMsgPreferredLanguageInvoked)); fPreferredListView->SetDeleteMessage( new BMessage(kMsgPreferredLanguageDeleted)); fPreferredListView->SetDragMessage( new BMessage(kMsgPreferredLanguageDragged)); BLayoutBuilder::Group<>(languageTab) .AddGroup(B_VERTICAL, spacing) .Add(new BStringView("", B_TRANSLATE("Available languages"))) .Add(scrollView) .End() .AddGroup(B_VERTICAL, spacing) .Add(new BStringView("", B_TRANSLATE("Preferred languages"))) .Add(scrollViewEnabled) .End() .SetInsets(spacing, spacing, spacing, spacing); BView* countryTab = new BView(B_TRANSLATE("Country"), B_WILL_DRAW); countryTab->SetLayout(new BGroupLayout(B_VERTICAL, 0)); BListView* listView = new BListView("country", B_SINGLE_SELECTION_LIST); scrollView = new BScrollView("scroller", listView, B_WILL_DRAW | B_FRAME_EVENTS, false, true); listView->SetSelectionMessage(new BMessage(kMsgCountrySelection)); // get all available countries from ICU // Use DateFormat::getAvailableLocale so we get only the one we can // use. Maybe check the NumberFormat one and see if there is more. int32_t localeCount; const Locale* currentLocale = Locale::getAvailableLocales(localeCount); for (int index = 0; index < localeCount; index++) { UnicodeString countryFullName; BString string; BStringByteSink sink(&string); currentLocale[index].getDisplayName(countryFullName); countryFullName.toUTF8(sink); LanguageListItem* item = new LanguageListItem(string, currentLocale[index].getName(), NULL); listView->AddItem(item); if (!strcmp(currentLocale[index].getName(), defaultCountry->Code())) listView->Select(listView->CountItems() - 1); } // TODO: find a real solution intead of this hack listView->SetExplicitMinSize( BSize(25 * be_plain_font->Size(), B_SIZE_UNSET)); fFormatView = new FormatView(defaultCountry); countryTab->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL, spacing) .AddGroup(B_VERTICAL, 3) .Add(scrollView) .End() .Add(fFormatView) .SetInsets(spacing, spacing, spacing, spacing)); listView->ScrollToSelection(); tabView->AddTab(languageTab); tabView->AddTab(countryTab); BButton* button = new BButton(B_TRANSLATE("Defaults"), new BMessage(kMsgDefaults)); fRevertButton = new BButton(B_TRANSLATE("Revert"), new BMessage(kMsgRevert)); fRevertButton->SetEnabled(false); BLayoutBuilder::Group<>(this, B_VERTICAL, spacing) .Add(tabView) .AddGroup(B_HORIZONTAL, spacing) .Add(button) .Add(fRevertButton) .AddGlue() .End() .SetInsets(spacing, spacing, spacing, spacing) .End(); _UpdatePreferredFromLocaleRoster(); SettingsReverted(); CenterOnScreen(); }
void LocaleWindow::MessageReceived(BMessage* message) { switch (message->what) { case kMsgDefaults: _Defaults(); break; case kMsgRevert: be_app_messenger.SendMessage(message); _UpdatePreferredFromLocaleRoster(); break; case kMsgLanguageDragged: { void* target = NULL; if (message->FindPointer("drop_target", &target) != B_OK || target != fPreferredListView) break; // Add from available languages to preferred languages int32 dropIndex; if (message->FindInt32("drop_index", &dropIndex) != B_OK) dropIndex = fPreferredListView->CountItems(); int32 index = 0; for (int32 i = 0; message->FindInt32("index", i, &index) == B_OK; i++) { LanguageListItem* item = static_cast<LanguageListItem*>( fLanguageListView->FullListItemAt(index)); _InsertPreferredLanguage(item, dropIndex++); } break; } case kMsgLanguageInvoked: { int32 index = 0; for (int32 i = 0; message->FindInt32("index", i, &index) == B_OK; i++) { LanguageListItem* item = static_cast<LanguageListItem*>( fLanguageListView->ItemAt(index)); _InsertPreferredLanguage(item); } break; } case kMsgPreferredLanguageDragged: { void* target = NULL; if (fPreferredListView->CountItems() == 1 || message->FindPointer("drop_target", &target) != B_OK) break; if (target == fPreferredListView) { // change ordering int32 dropIndex = message->FindInt32("drop_index"); int32 index = 0; if (message->FindInt32("index", &index) == B_OK && dropIndex != index) { BListItem* item = fPreferredListView->RemoveItem(index); if (dropIndex > index) index--; fPreferredListView->AddItem(item, dropIndex); _PreferredLanguagesChanged(); } break; } // supposed to fall through - remove item } case kMsgPreferredLanguageDeleted: case kMsgPreferredLanguageInvoked: { if (fPreferredListView->CountItems() == 1) break; // Remove from preferred languages int32 index = 0; if (message->FindInt32("index", &index) == B_OK) { delete fPreferredListView->RemoveItem(index); _PreferredLanguagesChanged(); if (message->what == kMsgPreferredLanguageDeleted) fPreferredListView->Select(index); } break; } case kMsgCountrySelection: { // Country selection changed. // Get the new selected country from the ListView and send it to the // main app event handler. void* listView; if (message->FindPointer("source", &listView) != B_OK) break; BListView* countryList = static_cast<BListView*>(listView); LanguageListItem* item = static_cast<LanguageListItem*> (countryList->ItemAt(countryList->CurrentSelection())); BMessage newMessage(kMsgSettingsChanged); newMessage.AddString("country", item->ID()); be_app_messenger.SendMessage(&newMessage); SettingsChanged(); BCountry* country = new BCountry(item->ID()); fFormatView->SetCountry(country); break; } default: BWindow::MessageReceived(message); break; } }
bool LanguageListView::InitiateDrag(BPoint point, int32 dragIndex, bool /*wasSelected*/) { if (fDragMessage == NULL) return false; BListItem* item = ItemAt(CurrentSelection(0)); if (item == NULL) { // workaround for a timing problem // TODO: this should support extending the selection item = ItemAt(dragIndex); Select(dragIndex); } if (item == NULL) return false; // create drag message BMessage message = *fDragMessage; message.AddPointer("listview", this); for (int32 i = 0;; i++) { int32 index = CurrentSelection(i); if (index < 0) break; message.AddInt32("index", index); } // figure out drag rect BRect dragRect(0.0, 0.0, Bounds().Width(), -1.0); int32 numItems = 0; bool fade = false; // figure out, how many items fit into our bitmap for (int32 i = 0, index; message.FindInt32("index", i, &index) == B_OK; i++) { BListItem* item = ItemAt(index); if (item == NULL) break; dragRect.bottom += ceilf(item->Height()) + 1.0; numItems++; if (dragRect.Height() > MAX_DRAG_HEIGHT) { dragRect.bottom = MAX_DRAG_HEIGHT; fade = true; break; } } BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true); if (dragBitmap->IsValid()) { BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW); dragBitmap->AddChild(view); dragBitmap->Lock(); BRect itemBounds(dragRect) ; itemBounds.bottom = 0.0; // let all selected items, that fit into our drag_bitmap, draw for (int32 i = 0; i < numItems; i++) { int32 index = message.FindInt32("index", i); LanguageListItem* item = static_cast<LanguageListItem*>(ItemAt(index)); itemBounds.bottom = itemBounds.top + ceilf(item->Height()); if (itemBounds.bottom > dragRect.bottom) itemBounds.bottom = dragRect.bottom; item->DrawItem(view, itemBounds); itemBounds.top = itemBounds.bottom + 1.0; } // make a black frame arround the edge view->SetHighColor(0, 0, 0, 255); view->StrokeRect(view->Bounds()); view->Sync(); uint8* bits = (uint8*)dragBitmap->Bits(); int32 height = (int32)dragBitmap->Bounds().Height() + 1; int32 width = (int32)dragBitmap->Bounds().Width() + 1; int32 bpr = dragBitmap->BytesPerRow(); if (fade) { for (int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = ALPHA; } for (int32 y = height - ALPHA / 2; y < height; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = (height - y) << 1; } } else { for (int32 y = 0; y < height; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = ALPHA; } } dragBitmap->Unlock(); } else { delete dragBitmap; dragBitmap = NULL; } if (dragBitmap != NULL) DragMessage(&message, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0)); else DragMessage(&message, dragRect.OffsetToCopy(point), this); return true; }