void BDirMenu::Populate(const BEntry *startEntry, BWindow *originatingWindow, bool includeStartEntry, bool select, bool reverse, bool addShortcuts) { try { if (!startEntry) throw (status_t)B_ERROR; Model model(startEntry); ThrowOnInitCheckError(&model); ModelMenuItem *menu = new ModelMenuItem(&model, this, true, true); if (fMenuBar) fMenuBar->AddItem(menu); BEntry entry(*startEntry); bool showDesktop, showDisksIcon; { TrackerSettings settings; showDesktop = settings.DesktopFilePanelRoot(); showDisksIcon = settings.ShowDisksIcon(); } // might start one level above startEntry if (!includeStartEntry) { BDirectory parent; BDirectory dir(&entry); // if we're at the root directory skip "mnt" and go straight to "/" if (!showDesktop && dir.InitCheck() == B_OK && dir.IsRootDirectory()) parent.SetTo("/"); else entry.GetParent(&parent); parent.GetEntry(&entry); } BVolume bootVol; BVolumeRoster().GetBootVolume(&bootVol); BDirectory desktopDir; FSGetDeskDir(&desktopDir, bootVol.Device()); BEntry desktopEntry; desktopDir.GetEntry(&desktopEntry); for (;;) { BNode node(&entry); ThrowOnInitCheckError(&node); PoseInfo info; ReadAttrResult result = ReadAttr(&node, kAttrPoseInfo, kAttrPoseInfoForeign, B_RAW_TYPE, 0, &info, sizeof(PoseInfo), &PoseInfo::EndianSwap); BDirectory parent; entry.GetParent(&parent); bool hitRoot = false; // if we're at the root directory skip "mnt" and go straight to "/" BDirectory dir(&entry); if (!showDesktop && dir.InitCheck() == B_OK && dir.IsRootDirectory()) { hitRoot = true; parent.SetTo("/"); } if (showDesktop) { BEntry root("/"); // warp from "/" to Desktop properly if (entry == root) { if (showDisksIcon) AddDisksIconToMenu(reverse); entry = desktopEntry; } if (entry == desktopEntry) hitRoot = true; } if (result == kReadAttrFailed || !info.fInvisible || (showDesktop && desktopEntry == entry)) AddItemToDirMenu(&entry, originatingWindow, reverse, addShortcuts); if (hitRoot) { if (!showDesktop && showDisksIcon && *startEntry != "/") AddDisksIconToMenu(reverse); break; } parent.GetEntry(&entry); } // select last item in menu if (!select) return; ModelMenuItem *item = dynamic_cast<ModelMenuItem *>(ItemAt(CountItems() - 1)); if (item) { item->SetMarked(true); if (menu) { entry.SetTo(item->TargetModel()->EntryRef()); ThrowOnError(menu->SetEntry(&entry)); } } } catch (status_t err) { PRINT(("BDirMenu::Populate: caught error %s\n", strerror(err))); if (!CountItems()) { BString error; error << "Error [" << strerror(err) << "] populating menu"; AddItem(new BMenuItem(error.String(), 0)); } } }
void DOMSVGPathSegList::InternalListWillChangeTo(const SVGPathData& aNewValue) { // When the number of items in our internal counterpart changes, we MUST stay // in sync. Everything in the scary comment in // DOMSVGLengthList::InternalBaseValListWillChangeTo applies here just as // much, but we have the additional issue that failing to stay in sync would // mean that - assuming we aren't reading bad memory - we would likely end up // decoding command types from argument floats when looking in our // SVGPathData's data array! Either way, we'll likely then go down // NS_NOTREACHED code paths, or end up reading/setting more bad memory!! // The only time that our other DOM list type implementations remove items is // if those items become surplus items due to an attribute change or SMIL // animation sample shortening the list. In general though, they try to keep // their existing DOM items, even when things change. To be consistent, we'd // really like to do the same thing. However, because different types of path // segment correspond to different DOMSVGPathSeg subclasses, the type of // items in our list are generally not the same, which makes this harder for // us. We have to remove DOM segments if their type is not the same as the // type of the new internal segment at their index. // // We also need to sync up mInternalDataIndex, but since we need to loop over // all the items in the new list checking types anyway, that's almost // insignificant in terms of overhead. // // Note that this method is called on every single SMIL animation resample // and we have no way to short circuit the overhead since we don't have a // way to tell if the call is due to a new animation, or a resample of an // existing animation (when the number and type of items would be the same). // (Note that a new animation could start overriding an existing animation at // any time, so checking IsAnimating() wouldn't work.) Because we get called // on every sample, it would not be acceptable alternative to throw away all // our items and let them be recreated lazily, since that would break what // script sees! uint32_t length = mItems.Length(); uint32_t index = 0; uint32_t dataLength = aNewValue.mData.Length(); uint32_t dataIndex = 0; // index into aNewValue's raw data array uint32_t newSegType; nsRefPtr<DOMSVGPathSegList> kungFuDeathGrip; if (length) { // RemovingFromList() might clear last reference to |this|. // Retain a temporary reference to keep from dying before returning. // // NOTE: For path-seg lists (unlike other list types), we have to do this // *whenever our list is nonempty* (even if we're growing in length). // That's because the path-seg-type of any segment could differ between old // list vs. new list, which will make us destroy & recreate that segment, // which could remove the last reference to us. // // (We explicitly *don't* want to create a kungFuDeathGrip in the length=0 // case, though, because we do hit this code inside our constructor before // any other owning references have been added, and at that point, the // deathgrip-removal would make us die before we exit our constructor.) kungFuDeathGrip = this; } while (index < length && dataIndex < dataLength) { newSegType = SVGPathSegUtils::DecodeType(aNewValue.mData[dataIndex]); if (ItemAt(index) && ItemAt(index)->Type() != newSegType) { ItemAt(index)->RemovingFromList(); ItemAt(index) = nullptr; } // Only after the RemovingFromList() can we touch mInternalDataIndex! mItems[index].mInternalDataIndex = dataIndex; ++index; dataIndex += 1 + SVGPathSegUtils::ArgCountForType(newSegType); } NS_ABORT_IF_FALSE((index == length && dataIndex <= dataLength) || (index <= length && dataIndex == dataLength), "very bad - list corruption?"); if (index < length) { // aNewValue has fewer items than our previous internal counterpart uint32_t newLength = index; // Remove excess items from the list: for (; index < length; ++index) { if (ItemAt(index)) { ItemAt(index)->RemovingFromList(); ItemAt(index) = nullptr; } } // Only now may we truncate mItems mItems.SetLength(newLength); } else if (dataIndex < dataLength) { // aNewValue has more items than our previous internal counterpart // Sync mItems: while (dataIndex < dataLength) { if (mItems.Length() && mItems.Length() - 1 > DOMSVGPathSeg::MaxListIndex()) { // It's safe to get out of sync with our internal list as long as we // have FEWER items than it does. return; } if (!mItems.AppendElement(ItemProxy(nullptr, dataIndex))) { // OOM ErrorResult rv; Clear(rv); MOZ_ASSERT(!rv.Failed()); return; } dataIndex += 1 + SVGPathSegUtils::ArgCountForType(SVGPathSegUtils::DecodeType(aNewValue.mData[dataIndex])); } } NS_ABORT_IF_FALSE(dataIndex == dataLength, "Serious processing error"); NS_ABORT_IF_FALSE(index == length, "Serious counting error"); }
void BListView::KeyDown(const char* bytes, int32 numBytes) { bool extend = fListType == B_MULTIPLE_SELECTION_LIST && (modifiers() & B_SHIFT_KEY) != 0; if (fFirstSelected == -1 && (bytes[0] == B_UP_ARROW || bytes[0] == B_DOWN_ARROW)) { // nothing is selected yet, select the first enabled item int32 lastItem = CountItems() - 1; for (int32 i = 0; i <= lastItem; i++) { if (ItemAt(i)->IsEnabled()) { Select(i); break; } } return; } switch (bytes[0]) { case B_UP_ARROW: { if (fAnchorIndex > 0) { if (!extend || fAnchorIndex <= fFirstSelected) { for (int32 i = 1; fAnchorIndex - i >= 0; i++) { if (ItemAt(fAnchorIndex - i)->IsEnabled()) { // Select the previous enabled item Select(fAnchorIndex - i, extend); break; } } } else { Deselect(fAnchorIndex); do fAnchorIndex--; while (fAnchorIndex > 0 && !ItemAt(fAnchorIndex)->IsEnabled()); } } ScrollToSelection(); break; } case B_DOWN_ARROW: { int32 lastItem = CountItems() - 1; if (fAnchorIndex < lastItem) { if (!extend || fAnchorIndex >= fLastSelected) { for (int32 i = 1; fAnchorIndex + i <= lastItem; i++) { if (ItemAt(fAnchorIndex + i)->IsEnabled()) { // Select the next enabled item Select(fAnchorIndex + i, extend); break; } } } else { Deselect(fAnchorIndex); do fAnchorIndex++; while (fAnchorIndex < lastItem && !ItemAt(fAnchorIndex)->IsEnabled()); } } ScrollToSelection(); break; } case B_HOME: if (extend) { Select(0, fAnchorIndex, true); fAnchorIndex = 0; } else { // select the first enabled item int32 lastItem = CountItems() - 1; for (int32 i = 0; i <= lastItem; i++) { if (ItemAt(i)->IsEnabled()) { Select(i, false); break; } } } ScrollToSelection(); break; case B_END: if (extend) { Select(fAnchorIndex, CountItems() - 1, true); fAnchorIndex = CountItems() - 1; } else { // select the last enabled item for (int32 i = CountItems() - 1; i >= 0; i--) { if (ItemAt(i)->IsEnabled()) { Select(i, false); break; } } } ScrollToSelection(); break; case B_PAGE_UP: { BPoint scrollOffset(LeftTop()); scrollOffset.y = std::max(0.0f, scrollOffset.y - Bounds().Height()); ScrollTo(scrollOffset); break; } case B_PAGE_DOWN: { BPoint scrollOffset(LeftTop()); if (BListItem* item = LastItem()) { scrollOffset.y += Bounds().Height(); scrollOffset.y = std::min(item->Bottom() - Bounds().Height(), scrollOffset.y); } ScrollTo(scrollOffset); break; } case B_RETURN: case B_SPACE: Invoke(); break; default: BView::KeyDown(bytes, numBytes); } }
void BListView::MouseDown(BPoint point) { if (!IsFocus()) { MakeFocus(); Sync(); Window()->UpdateIfNeeded(); } BMessage* message = Looper()->CurrentMessage(); int32 index = IndexOf(point); // If the user double (or more) clicked within the current selection, // we don't change the selection but invoke the selection. // TODO: move this code someplace where it can be shared everywhere // instead of every class having to reimplement it, once some sane // API for it is decided. BPoint delta = point - fTrack->drag_start; bigtime_t sysTime; Window()->CurrentMessage()->FindInt64("when", &sysTime); bigtime_t timeDelta = sysTime - fTrack->last_click_time; bigtime_t doubleClickSpeed; get_click_speed(&doubleClickSpeed); bool doubleClick = false; if (timeDelta < doubleClickSpeed && fabs(delta.x) < kDoubleClickTresh && fabs(delta.y) < kDoubleClickTresh && fTrack->item_index == index) { doubleClick = true; } if (doubleClick && index >= fFirstSelected && index <= fLastSelected) { fTrack->drag_start.Set(INT32_MAX, INT32_MAX); Invoke(); return; } int32 modifiers; message->FindInt32("modifiers", &modifiers); if (!doubleClick) { fTrack->drag_start = point; fTrack->last_click_time = system_time(); fTrack->item_index = index; fTrack->was_selected = index >= 0 ? ItemAt(index)->IsSelected() : false; fTrack->try_drag = true; } if (index > -1) { if (fListType == B_MULTIPLE_SELECTION_LIST) { if (modifiers & B_SHIFT_KEY) { // select entire block // TODO: maybe review if we want it like in Tracker // (anchor item) Select(min_c(index, fFirstSelected), max_c(index, fLastSelected)); } else { if (modifiers & B_COMMAND_KEY) { // toggle selection state of clicked item (like in Tracker) // toggle selection state of clicked item if (ItemAt(index)->IsSelected()) Deselect(index); else Select(index, true); } else Select(index); } } else { // toggle selection state of clicked item if ((modifiers & B_COMMAND_KEY) && ItemAt(index)->IsSelected()) Deselect(index); else Select(index); } } else if ((modifiers & B_COMMAND_KEY) == 0) DeselectAll(); }
already_AddRefed<DOMSVGPathSeg> DOMSVGPathSegList::ReplaceItem(DOMSVGPathSeg& aNewItem, uint32_t aIndex, ErrorResult& aError) { if (IsAnimValList()) { aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return nullptr; } if (aIndex >= LengthNoFlush()) { aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return nullptr; } nsRefPtr<DOMSVGPathSeg> domItem = &aNewItem; if (domItem->HasOwner()) { domItem = domItem->Clone(); // must do this before changing anything! } AutoChangePathSegListNotifier notifier(this); if (ItemAt(aIndex)) { // Notify any existing DOM item of removal *before* modifying the lists so // that the DOM item can copy the *old* value at its index: ItemAt(aIndex)->RemovingFromList(); } uint32_t internalIndex = mItems[aIndex].mInternalDataIndex; // We use InternalList() to get oldArgCount since we may not have a DOM // wrapper at the index being replaced. uint32_t oldType = SVGPathSegUtils::DecodeType(InternalList().mData[internalIndex]); // NOTE: ArgCountForType returns a (small) unsigned value, but we're // intentionally putting it in a signed variable, because we're going to // subtract these values and might produce something negative. int32_t oldArgCount = SVGPathSegUtils::ArgCountForType(oldType); int32_t newArgCount = SVGPathSegUtils::ArgCountForType(domItem->Type()); float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS]; domItem->ToSVGPathSegEncodedData(segAsRaw); bool ok = !!InternalList().mData.ReplaceElementsAt( internalIndex, 1 + oldArgCount, segAsRaw, 1 + newArgCount); InternalList().mCachedPath = nullptr; if (!ok) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } ItemAt(aIndex) = domItem; // This MUST come after the ToSVGPathSegEncodedData call, otherwise that call // would end up reading bad data from InternalList()! domItem->InsertingIntoList(this, aIndex, IsAnimValList()); int32_t delta = newArgCount - oldArgCount; if (delta != 0) { for (uint32_t i = aIndex + 1; i < LengthNoFlush(); ++i) { mItems[i].mInternalDataIndex += delta; } } return domItem.forget(); }
void MainWindow::MessageReceived(BMessage* message) { switch (message->what) { case kSearchContact: { void* control = NULL; if (message->FindPointer("source", &control) != B_OK) return; SearchBarTextControl* searchBox = static_cast<SearchBarTextControl*>(control); if (searchBox == NULL) return; RosterMap map = fServer->RosterItems(); for (uint32 i = 0; i < map.CountItems(); i++) { ContactLinker* linker = map.ValueAt(i); RosterItem* item = linker->GetRosterItem(); // If the search filter has been deleted show all the items, // otherwise remove the item in order to show only items // that matches the search criteria if (strcmp(searchBox->Text(), "") == 0) AddItem(item); else if (linker->GetName().IFindFirst(searchBox->Text()) == B_ERROR) RemoveItem(item); else AddItem(item); UpdateListItem(item); } break; } case CAYA_SHOW_SETTINGS: { PreferencesDialog* dialog = new PreferencesDialog(); dialog->Show(); break; } case CAYA_OPEN_CHAT_WINDOW: { int index = message->FindInt32("index"); RosterItem* ritem = ItemAt(index); if (ritem != NULL) ritem->GetContactLinker()->ShowWindow(false, true); break; } case CAYA_REPLICANT_STATUS_SET: { int32 status; message->FindInt32("status", &status); AccountManager* accountManager = AccountManager::Get(); accountManager->SetStatus((CayaStatus)status); break; } case CAYA_REPLICANT_SHOW_WINDOW: { if (LockLooper()) { SetWorkspaces(B_CURRENT_WORKSPACE); if ((IsMinimized() || IsHidden()) || fWorkspaceChanged) { Minimize(false); Show(); fWorkspaceChanged = false; } else if ((!IsMinimized() || !IsHidden()) || (!fWorkspaceChanged)) { Minimize(true); } UnlockLooper(); } break; } case IM_MESSAGE: ImMessage(message); break; case IM_ERROR: ImError(message); break; case B_ABOUT_REQUESTED: be_app->PostMessage(message); break; default: BWindow::MessageReceived(message); } }
void TExpandoMenuBar::MouseDown(BPoint where) { BMessage *message = Window()->CurrentMessage(); // check for three finger salute, a.k.a. Vulcan Death Grip if (message != NULL) { int32 modifiers = 0; message->FindInt32("modifiers", &modifiers); if ((modifiers & B_COMMAND_KEY) != 0 && (modifiers & B_OPTION_KEY) != 0 && (modifiers & B_SHIFT_KEY) != 0 && !fBarView->Dragging()) { TTeamMenuItem *item = TeamItemAtPoint(where); if (item != NULL) { const BList *teams = item->Teams(); int32 teamCount = teams->CountItems(); team_id teamID; for (int32 team = 0; team < teamCount; team++) { teamID = (team_id)teams->ItemAt(team); kill_team(teamID); // remove the team immediately // from display RemoveTeam(teamID, false); } return; } } } // This feature is broken because the menu bar never receives // the second click #ifdef DOUBLECLICKBRINGSTOFRONT // doubleclick on an item brings all to front for (int32 i = fFirstApp; i < count; i++) { TTeamMenuItem *item = (TTeamMenuItem *)ItemAt(i); if (item->Frame().Contains(where)) { bigtime_t clickSpeed = 0; get_click_speed(&clickSpeed); if ( (fLastClickItem == i) && (clickSpeed > (system_time() - fLastClickTime)) ) { // bring this team's window to the front BMessage showMessage(M_BRING_TEAM_TO_FRONT); showMessage.AddInt32("itemIndex", i); Window()->PostMessage(&showMessage, this); return; } fLastClickItem = i; fLastClickTime = system_time(); break; } } #endif // control click - show all/hide all shortcut if (message != NULL) { int32 modifiers = 0; message->FindInt32("modifiers", &modifiers); if ((modifiers & B_CONTROL_KEY) != 0 && ! fBarView->Dragging()) { TTeamMenuItem *item = TeamItemAtPoint(where); if (item != NULL) { // show/hide item's teams BMessage showMessage((modifiers & B_SHIFT_KEY) != 0 ? M_MINIMIZE_TEAM : M_BRING_TEAM_TO_FRONT); showMessage.AddInt32("itemIndex", IndexOf(item)); Window()->PostMessage(&showMessage, this); return; } } } // Check the bounds of the expand Team icon if (fShowTeamExpander && fVertical && !fBarView->Dragging()) { TTeamMenuItem *item = TeamItemAtPoint(where); if (item != NULL) { BRect expanderRect = item->ExpanderBounds(); if (expanderRect.Contains(where)) { // Let the update thread wait... BAutolock locker(sMonLocker); // Toggle the item item->ToggleExpandState(true); item->Draw(); // Absorb the message. return; } } } BMenuBar::MouseDown(where); }
JobItem* JobListView::SelectedItem() const { return dynamic_cast<JobItem*>(ItemAt(CurrentSelection())); }
void TExpandoMenuBar::MessageReceived(BMessage* message) { int32 index; TTeamMenuItem* item; switch (message->what) { case B_SOME_APP_LAUNCHED: { BList* teams = NULL; message->FindPointer("teams", (void**)&teams); BBitmap* icon = NULL; message->FindPointer("icon", (void**)&icon); const char* signature = NULL; message->FindString("sig", &signature); uint32 flags = 0; message->FindInt32("flags", ((int32*) &flags)); const char* name = NULL; message->FindString("name", &name); AddTeam(teams, icon, strdup(name), strdup(signature)); break; } case B_MOUSE_WHEEL_CHANGED: { float deltaY = 0; message->FindFloat("be:wheel_delta_y", &deltaY); if (deltaY == 0) return; TInlineScrollView* scrollView = dynamic_cast<TInlineScrollView*>(Parent()); if (scrollView == NULL) return; float largeStep; float smallStep; scrollView->GetSteps(&smallStep, &largeStep); // pressing the option/command/control key scrolls faster if (modifiers() & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY)) deltaY *= largeStep; else deltaY *= smallStep; scrollView->ScrollBy(deltaY); break; } case kAddTeam: AddTeam(message->FindInt32("team"), message->FindString("sig")); break; case kRemoveTeam: { team_id team = -1; message->FindInt32("team", &team); RemoveTeam(team, true); break; } case B_SOME_APP_QUIT: { team_id team = -1; message->FindInt32("team", &team); RemoveTeam(team, false); break; } case kMinimizeTeam: { index = message->FindInt32("itemIndex"); item = dynamic_cast<TTeamMenuItem*>(ItemAt(index)); if (item == NULL) break; TShowHideMenuItem::TeamShowHideCommon(B_MINIMIZE_WINDOW, item->Teams(), item->Menu()->ConvertToScreen(item->Frame()), true); break; } case kBringTeamToFront: { index = message->FindInt32("itemIndex"); item = dynamic_cast<TTeamMenuItem*>(ItemAt(index)); if (item == NULL) break; TShowHideMenuItem::TeamShowHideCommon(B_BRING_TO_FRONT, item->Teams(), item->Menu()->ConvertToScreen(item->Frame()), true); break; } default: BMenuBar::MessageReceived(message); break; } }
/*! \brief Insert new item into the menu in alphabetical order. * \param[in] item The CategoryMenuItem to insert. * \note \"Default\" item and separator * The item with label "Default" is always the first in list. * The separator, if it exists, is always the second. * All other items are sorted alphabetically. */ bool CategoryMenu::AddItem( CategoryMenuItem* item ) { int index, limit = this->CountItems(); BString label( item->Label() ), testString("Default"); BMenuItem* itemToTest = NULL; CategoryMenuItem *catItem = NULL; /* Maybe we're adding default item? */ if ( label == testString ) { // If current label is "Default" if ( ( limit == 0 ) || ( BString( ItemAt( 0 )->Label() ) != testString ) ) { // And the menu is empty or the first item has another label // Adding "Default" at the first place. return BMenu::AddItem( item, 0 ); } else { // The menu is not empty, and the first item is already "Default". catItem = dynamic_cast<CategoryMenuItem*>( ItemAt( 0 ) ); if ( catItem ) { catItem->UpdateColor( item->GetColor() ); } delete item; return true; // Exit - nothing to do } } // Else, the item should not be added at all - there must be only one! (c) Kurgan /* Well, the category to be added was not a "Default". * It's not a separator either; the separator is added by BMenu::AddItem(). */ index = 0; while ( index < limit ) { itemToTest = ItemAt( index ); catItem = dynamic_cast< CategoryMenuItem* >( itemToTest ); testString.SetTo( itemToTest->Label() ); // Jumping over "Default" item if ( testString == "Default" ) { ++index; continue; } // Jumping over non-CategoryMenuItem items if ( !catItem ) { ++index; continue; } /* Now the tough part starts */ // Jump over items that are alphabetically lower if ( testString < label ) { ++index; continue; } // If same item was found - update its color else if ( testString == label ) { if ( catItem ) { catItem->UpdateColor( item->GetColor() ); } delete item; return true; // Exit - nothing to do } // Found first item that's greater alphabetically else { // Verify the message if ( ! item->Message() ) { BMessage* toSend = NULL; if ( fTemplateMessage ) { toSend = new BMessage( *fTemplateMessage ); } else { toSend = new BMessage( kCategorySelected ); } if ( !toSend ) { return false; } toSend->AddString( "Category", item->Label() ); item->SetMessage( toSend ); } return BMenu::AddItem( item, index ); } ++index; } // If we got here, then it should be the last item. if ( ! item->Message() ) { BMessage* toSend = NULL; if ( fTemplateMessage ) { toSend = new BMessage( *fTemplateMessage ); } else { toSend = new BMessage( kCategorySelected ); } if ( !toSend ) { return false; } toSend->AddString( "Category", item->Label() ); item->SetMessage( toSend ); } return BMenu::AddItem( item ); } // <-- end of function CategoryMenu::AddItem
/*! \brief Function that adds an item to the list. * \details If the item is "Default", it will be added first. * If it's an update of an existing item, it will be updated. * If it's a new item, it will be added in alphabetical order. */ bool CategoryListView::AddItem( CategoryListItem *toAdd ) { if ( !toAdd ) { return false; } BString testString("Default"), toAddLabel( toAdd->GetLabel() ); CategoryListItem *testItem; bool toReturn = false; int index = 0, limit = this->CountItems(); // Is it the "Default" item? if ( toAddLabel == testString ) { // Well, yes, it is. testItem = dynamic_cast< CategoryListItem* >( ItemAt( 0 ) ); if ( ( limit == 0 ) || ( testItem && ( testItem->GetLabel() != testString ) ) ) { // Either adding the first item, // or the first item is not a CategoryListItem, // or it is a CategoryListItem, but not "Default". toReturn = BListView::AddItem( toAdd, 0 ); FixupScrollbars(); return toReturn; } else if ( !testItem ) { // The first item is not a CategoryListItem. toReturn = BListView::AddItem( toAdd, 0 ); FixupScrollbars(); return toReturn; } else { // The first item is a "Default" item. Update its color. testItem->UpdateColor( toAdd->GetColor() ); delete toAdd; toAdd = NULL; InvalidateItem( 0 ); return true; } } // Well, it's not a "Default" item. index = 0; while ( index < limit ) { testItem = dynamic_cast< CategoryListItem* >( ItemAt( index ) ); if ( ! testItem ) { ++index; continue; } testString = testItem->GetLabel(); // Jump over "Default" leaving it at the top. if ( testString == "Default" ) { ++index; continue; } // Jump over items that are alphabetically lower. if ( testString < toAddLabel ) { ++index; continue; } // If encountered item with the same label, update its color. if ( testString == toAddLabel ) { testItem->UpdateColor( toAdd->GetColor() ); delete toAdd; toAdd = NULL; InvalidateItem( index ); return true; } // Found the place to insert current item if ( testString > toAddLabel ) { toReturn = BListView::AddItem( toAdd, index ); FixupScrollbars(); return toReturn; } ++index; } // If we got here, then all items are alphabetically less. toReturn = BListView::AddItem( toAdd ); FixupScrollbars(); return toReturn; } // <-- end of function CategoryListView::AddItem
void NamesView::MessageReceived (BMessage *msg) { switch (msg->what) { case M_THEME_FOREGROUND_CHANGE: { int16 which (msg->FindInt16 ("which")); bool refresh (false); switch (which) { case C_NAMES_BACKGROUND: fActiveTheme->ReadLock(); SetViewColor (fActiveTheme->ForegroundAt (C_NAMES_BACKGROUND)); refresh = true; fActiveTheme->ReadUnlock(); break; case C_OP: case C_VOICE: case C_HELPER: case C_NAMES_SELECTION: refresh = true; break; default: break; } if (refresh) Invalidate(); } break; case M_THEME_FONT_CHANGE: { int16 which (msg->FindInt16 ("which")); if (which == F_NAMES) { fActiveTheme->ReadLock(); BFont newFont (fActiveTheme->FontAt (F_NAMES)); fActiveTheme->ReadUnlock(); SetFont (&newFont); for (int32 i = 0; i < CountItems(); i++) ItemAt(i)->Update(this, &newFont); Invalidate(); } } break; case B_SIMPLE_DATA: { if (msg->HasRef("refs")) { // this only grabs the first ref for now // TODO: maybe implement queueing of multiple sends next time entry_ref ref; msg->FindRef("refs", &ref); BDirectory dir (&ref); // don't try to dcc send a dir if (dir.InitCheck() == B_OK) break; int32 idx (CurrentSelection()); if (idx >= 0) { NameItem *item (dynamic_cast<NameItem *>(ItemAt(idx))); BMessage message (M_CHOSE_FILE); message.AddString ("nick", item->Name()); message.AddRef ("refs", &ref); ClientAgent *myParent (dynamic_cast<ClientAgent *>(Parent()->Parent())); if (myParent) myParent->fSMsgr.SendMessage (&message); } } } break; default: { BListView::MessageReceived (msg); } break; } }
void NamesView::MouseMoved (BPoint myPoint, uint32 transitcode, const BMessage *dragMessage) { if ((dragMessage != NULL) && (dragMessage->HasRef("refs"))) { // make sure the ref isn't a dir entry_ref ref; dragMessage->FindRef("refs", &ref); BDirectory dir (&ref); if (dir.InitCheck() != B_OK) { int32 nameIndex (IndexOf(myPoint)); if (nameIndex >= 0) Select(nameIndex); } } else if (fTracking) { if (transitcode == B_INSIDE_VIEW) { BListItem *item = ItemAt (IndexOf(myPoint)); if (item) { BListItem *lastitem (NULL); int32 first (CurrentSelection (0)); int32 last (first); int32 i (1); while ((last = CurrentSelection(i++)) != -1) lastitem = ItemAt(last); if (lastitem) last = IndexOf(lastitem); else last = first; int32 current (IndexOf (myPoint)); if (current >= 0) { if (current < first) { // sweep up Select (current, last, true); } else if (current > last) { // sweep down Select (first, current, true); } else if (fCurrentindex > current) { // backtrack up DeselectExcept (first, current); } else if (fCurrentindex < current) { // backtrack down DeselectExcept (current, last); } fCurrentindex = current; } } } } else BListView::MouseMoved (myPoint, transitcode, dragMessage); }
void NamesView::MouseDown (BPoint myPoint) { int32 selected (IndexOf (myPoint)); bool handled (false); if (selected < 0) { DeselectAll(); return; } BMessage *inputMsg (Window()->CurrentMessage()); int32 mousebuttons (0), keymodifiers (0), mouseclicks (0); inputMsg->FindInt32 ("buttons", &mousebuttons); inputMsg->FindInt32 ("modifiers", &keymodifiers); inputMsg->FindInt32 ("clicks", &mouseclicks); if (mouseclicks > 1 && CurrentSelection(1) <= 0 && mousebuttons == B_PRIMARY_MOUSE_BUTTON && (keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { // user double clicked BListItem *item (ItemAt (IndexOf(myPoint))); if (item && !item->IsSelected()) { // "double" clicked away from another selection Select (IndexOf (myPoint), false); fCurrentindex = IndexOf (myPoint); fTracking = true; } else if (item && item->IsSelected()) { // double clicking on a single item NameItem *myItem (reinterpret_cast<NameItem *>(item)); BString theNick (myItem->Name()); BMessage msg (M_OPEN_MSGAGENT); msg.AddString ("nick", theNick.String()); reinterpret_cast<ChannelAgent *>(Parent()->Parent())->fMsgr.SendMessage (&msg); } handled = true; } if (mouseclicks == 1 && CurrentSelection(1) <= 0 && mousebuttons == B_PRIMARY_MOUSE_BUTTON && (keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { // user single clicks BListItem *item (ItemAt (IndexOf(myPoint))); if (item && !item->IsSelected()) Select (IndexOf (myPoint), false); fTracking = true; fCurrentindex = IndexOf (myPoint); handled = true; } if (mouseclicks >= 1 && CurrentSelection(1) >= 0 && mousebuttons == B_PRIMARY_MOUSE_BUTTON && (keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { // user clicks on something in the middle of a sweep selection BListItem *item (ItemAt (IndexOf(myPoint))); if (item) Select (IndexOf (myPoint), false); fTracking = true; fCurrentindex = IndexOf (myPoint); handled = true; } if (mousebuttons == B_SECONDARY_MOUSE_BUTTON && (keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { // user right clicks - display popup menu BListItem *item (ItemAt (IndexOf(myPoint))); if (item && !item->IsSelected()) Select (IndexOf (myPoint), false); fMyPopUp->Go ( ConvertToScreen (myPoint), true, false, ConvertToScreen (ItemFrame (selected))); handled = true; } if (mousebuttons == B_TERTIARY_MOUSE_BUTTON) BListView::MouseDown (myPoint); fLastSelected = selected; if (!handled) BListView::MouseDown (myPoint); }
void NotifyList::MouseDown (BPoint myPoint) { BMessage *msg (Window()->CurrentMessage()); int32 selected (IndexOf (myPoint)); if (selected >= 0) { BMessage *inputMsg (Window()->CurrentMessage()); int32 mousebuttons (0), keymodifiers (0); NotifyListItem *item ((NotifyListItem *)ItemAt(selected)); if (!item) return; inputMsg->FindInt32 ("buttons", &mousebuttons); inputMsg->FindInt32 ("modifiers", &keymodifiers); bigtime_t sysTime; msg->FindInt64 ("when", &sysTime); uint16 clicks = CheckClickCount (myPoint, fLastClick, sysTime, fLastClickTime, fClickCount) % 3; // slight kludge to make sure the expand/collapse triangles behave how they should // -- needed since OutlineListView's Expand/Collapse-related functions are not virtual if (mousebuttons == B_PRIMARY_MOUSE_BUTTON) { if (((clicks % 2) == 0) && item->GetState()) { // react to double click by creating a new messageagent or selecting // an existing one (use /query logic in parsecmd) BString data (item->Text()); data.Prepend ("/QUERY "); BMessage submitMsg (M_SUBMIT); submitMsg.AddString ("input", data.String()); submitMsg.AddBool ("history", false); // don't clear in case user has something typed in text control submitMsg.AddBool ("clear", false); WindowListItem *winItem ((WindowListItem *)vision_app->pClientWin()->pWindowList()->ItemAt( vision_app->pClientWin()->pWindowList()->CurrentSelection())); if (winItem) { BMessenger msgr (winItem->pAgent()); if (msgr.IsValid()) msgr.SendMessage(&submitMsg); } } else Select (selected); } if ((keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { if (mousebuttons == B_SECONDARY_MOUSE_BUTTON) { if (item) { if(!item->IsSelected()) Select (IndexOf (myPoint)); BuildPopUp(); fMyPopUp->Go ( ConvertToScreen (myPoint), true, true, ConvertToScreen (ItemFrame (selected)), true); } } } } }
void TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) { int32 buttons; BMessage* currentMessage = Window()->CurrentMessage(); if (currentMessage == NULL || currentMessage->FindInt32("buttons", &buttons) != B_OK) { buttons = 0; } if (message == NULL) { // force a cleanup _FinishedDrag(); switch (code) { case B_INSIDE_VIEW: { BMenuItem* menuItem; TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); TWindowMenuItem* windowMenuItem = dynamic_cast<TWindowMenuItem*>(menuItem); if (item == NULL || menuItem == NULL) { // item is NULL, remove the tooltip and break out fLastMousedOverItem = NULL; SetToolTip((const char*)NULL); break; } if (menuItem == fLastMousedOverItem) { // already set the tooltip for this item, break out break; } if (windowMenuItem != NULL && fBarView->Vertical() && fBarView->ExpandoState() && item->IsExpanded()) { // expando mode window menu item fLastMousedOverItem = menuItem; if (strcasecmp(windowMenuItem->TruncatedLabel(), windowMenuItem->Label()) > 0) { // label is truncated, set tooltip SetToolTip(windowMenuItem->Label()); } else SetToolTip((const char*)NULL); break; } if (!dynamic_cast<TBarApp*>(be_app)->Settings()->hideLabels) { // item has a visible label, set tool tip if truncated fLastMousedOverItem = menuItem; if (strcasecmp(item->TruncatedLabel(), item->Label()) > 0) { // label is truncated, set tooltip SetToolTip(item->Label()); } else SetToolTip((const char*)NULL); break; } SetToolTip(item->Label()); // new item, set the tooltip to the item label fLastMousedOverItem = menuItem; // save the current menuitem for the next MouseMoved() call break; } } BMenuBar::MouseMoved(where, code, message); return; } if (buttons == 0) return; switch (code) { case B_ENTERED_VIEW: // fPreviousDragTargetItem should always be NULL here anyways. if (fPreviousDragTargetItem != NULL) _FinishedDrag(); fBarView->CacheDragData(message); fPreviousDragTargetItem = NULL; break; case B_OUTSIDE_VIEW: // NOTE: Should not be here, but for the sake of defensive // programming... fall-through case B_EXITED_VIEW: _FinishedDrag(); break; case B_INSIDE_VIEW: if (fBarView->Dragging()) { TTeamMenuItem* item = NULL; int32 itemCount = CountItems(); for (int32 i = 0; i < itemCount; i++) { BMenuItem* _item = ItemAt(i); if (_item->Frame().Contains(where)) { item = dynamic_cast<TTeamMenuItem*>(_item); break; } } if (item == fPreviousDragTargetItem) break; if (fPreviousDragTargetItem != NULL) fPreviousDragTargetItem->SetOverrideSelected(false); if (item != NULL) item->SetOverrideSelected(true); fPreviousDragTargetItem = item; } break; } }
/*********************************************************** * MouseDown ***********************************************************/ void HListView::MouseDown(BPoint pos) { int32 buttons = 0; ResourceUtils utils; BPoint point = pos; MenuUtils menu_utils; Window()->CurrentMessage()->FindInt32("buttons", &buttons); this->MakeFocus(true); // Handling of right click if (buttons == B_SECONDARY_MOUSE_BUTTON) { int32 sel = IndexOf(pos); if (sel >= 0) Select(sel); else DeselectAll(); sel = CurrentSelection(); HListItem* item = NULL; if (sel >= 0) item = cast_as(ItemAt(sel), HListItem); BPopUpMenu* theMenu = new BPopUpMenu("RIGHT_CLICK", false, false); BFont font(be_plain_font); font.SetSize(10); theMenu->SetFont(&font); menu_utils.AddMenuItem(theMenu , _("Add New Download") , M_ADD_URL , NULL, NULL , 'A', 0, utils.GetBitmapResource('BBMP', "BMP:ADDURL")); theMenu->AddSeparatorItem(); menu_utils.AddMenuItem(theMenu , _("Suspend") , M_SUSPEND, NULL, NULL , 0, 0, utils.GetBitmapResource('BBMP', "BMP:SUSPEND")); if (item) { theMenu->FindItem(M_SUSPEND)->SetEnabled(item->IsSuspendable()); } else { theMenu->FindItem(M_SUSPEND)->SetEnabled(false); } menu_utils.AddMenuItem(theMenu , _("Resume") , M_RESUME, NULL, NULL , 0, 0, utils.GetBitmapResource('BBMP', "BMP:RESUME")); if (item) { theMenu->FindItem(M_RESUME)->SetEnabled(item->IsResumable()); } else { theMenu->FindItem(M_RESUME)->SetEnabled(false); } theMenu->AddSeparatorItem(); menu_utils.AddMenuItem(theMenu , _("Stop") , M_STOP, NULL, NULL , 0, 0, utils.GetBitmapResource('BBMP', "BMP:STOP")); if (item) theMenu->FindItem(M_STOP)->SetEnabled(item->IsStarted()); else theMenu->FindItem(M_STOP)->SetEnabled(false); menu_utils.AddMenuItem(theMenu , _("Start") , M_START, NULL, NULL , 0, 0, utils.GetBitmapResource('BBMP', "BMP:CONNECTING")); if (sel >= 0) theMenu->FindItem(M_START)->SetEnabled(!item->IsStarted()); else theMenu->FindItem(M_START)->SetEnabled(false); theMenu->AddSeparatorItem(); menu_utils.AddMenuItem(theMenu , _("Delete") , M_DELETE, NULL, NULL , 'T', 0, utils.GetBitmapResource('BBMP', "BMP:TRASH")); theMenu->FindItem(M_DELETE)->SetEnabled((sel >= 0) ? true : false); BRect r; ConvertToScreen(&pos); r.top = pos.y - 5; r.bottom = pos.y + 5; r.left = pos.x - 5; r.right = pos.x + 5; BMenuItem* theItem = theMenu->Go(pos, false, true, r); if (theItem) { BMessage* aMessage = theItem->Message(); if (aMessage) this->Window()->PostMessage(aMessage); } delete theMenu; } else ColumnListView::MouseDown(point); }
void TExpandoMenuBar::AddTeam(BList* team, BBitmap* icon, char* name, char* signature) { int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize(); desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings(); float itemWidth = -1.0f; if (fVertical) itemWidth = fBarView->Bounds().Width(); else { itemWidth = iconSize; if (!settings->hideLabels) itemWidth += gMinimumWindowWidth - kMinimumIconSize; else itemWidth += kIconPadding * 2; } float itemHeight = -1.0f; TTeamMenuItem* item = new TTeamMenuItem(team, icon, name, signature, itemWidth, itemHeight); if (settings->trackerAlwaysFirst && strcasecmp(signature, kTrackerSignature) == 0) { AddItem(item, 0); } else if (settings->sortRunningApps) { TTeamMenuItem* teamItem = dynamic_cast<TTeamMenuItem*>(ItemAt(0)); int32 firstApp = 0; // if Tracker should always be the first item, we need to skip it // when sorting in the current item if (settings->trackerAlwaysFirst && teamItem != NULL && strcasecmp(teamItem->Signature(), kTrackerSignature) == 0) { firstApp++; } BCollator collator; BLocale::Default()->GetCollator(&collator); int32 i = firstApp; int32 itemCount = CountItems(); while (i < itemCount) { teamItem = dynamic_cast<TTeamMenuItem*>(ItemAt(i)); if (teamItem != NULL && collator.Compare(teamItem->Label(), name) > 0) { AddItem(item, i); break; } i++; } // was the item added to the list yet? if (i == itemCount) AddItem(item); } else AddItem(item); if (fVertical && settings->superExpando && settings->expandNewTeams) item->ToggleExpandState(false); SizeWindow(1); Window()->UpdateIfNeeded(); }
void TExpandoMenuBar::MessageReceived(BMessage *message) { int32 index; TTeamMenuItem *item; switch (message->what) { case B_SOME_APP_LAUNCHED: { BList *teams = NULL; message->FindPointer("teams", (void **)&teams); BBitmap *icon = NULL; message->FindPointer("icon", (void **)&icon); const char *signature; if (message->FindString("sig", &signature) == B_OK &&strcasecmp(signature, kDeskbarSignature) == 0) { delete teams; delete icon; break; } uint32 flags; if (message->FindInt32("flags", ((int32*) &flags)) == B_OK && (flags & B_BACKGROUND_APP) != 0) { delete teams; delete icon; break; } const char *name = NULL; message->FindString("name", &name); AddTeam(teams, icon, strdup(name), strdup(signature)); break; } case msg_AddTeam: AddTeam(message->FindInt32("team"), message->FindString("sig")); break; case msg_RemoveTeam: { team_id team = -1; message->FindInt32("team", &team); RemoveTeam(team, true); break; } case B_SOME_APP_QUIT: { team_id team = -1; message->FindInt32("team", &team); RemoveTeam(team, false); break; } case M_MINIMIZE_TEAM: { index = message->FindInt32("itemIndex"); item = dynamic_cast<TTeamMenuItem *>(ItemAt(index)); if (item == NULL) break; TShowHideMenuItem::TeamShowHideCommon(B_MINIMIZE_WINDOW, item->Teams(), item->Menu()->ConvertToScreen(item->Frame()), true); break; } case M_BRING_TEAM_TO_FRONT: { index = message->FindInt32("itemIndex"); item = dynamic_cast<TTeamMenuItem *>(ItemAt(index)); if (item == NULL) break; TShowHideMenuItem::TeamShowHideCommon(B_BRING_TO_FRONT, item->Teams(), item->Menu()->ConvertToScreen(item->Frame()), true); break; } default: BMenuBar::MessageReceived(message); break; } }
void TExpandoMenuBar::CheckItemSizes(int32 delta) { if (fBarView->Vertical()) return; bool drawLabels = !static_cast<TBarApp*>(be_app)->Settings()->hideLabels; float maxWidth = fBarView->DragRegion()->Frame().left - fDeskbarMenuWidth - kSepItemWidth; int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize(); float iconOnlyWidth = kIconPadding + iconSize + kIconPadding; float minItemWidth = drawLabels ? iconOnlyWidth + kMinMenuItemWidth : iconOnlyWidth - kIconPadding; float maxItemWidth = drawLabels ? gMinimumWindowWidth + iconSize - kMinimumIconSize : iconOnlyWidth; float menuWidth = maxItemWidth * CountItems() + fDeskbarMenuWidth + kSepItemWidth; bool reset = false; float newWidth = -1.0f; if (delta >= 0 && menuWidth > maxWidth) { fOverflow = true; reset = true; newWidth = floorf(maxWidth / CountItems()); } else if (delta < 0 && fOverflow) { reset = true; if (menuWidth > maxWidth) newWidth = floorf(maxWidth / CountItems()); else newWidth = maxItemWidth; } if (reset) { if (newWidth > maxItemWidth) newWidth = maxItemWidth; else if (newWidth < minItemWidth) newWidth = minItemWidth; SetMaxContentWidth(newWidth); if (newWidth == maxItemWidth) fOverflow = false; InvalidateLayout(); for (int32 index = 0; ; index++) { TTeamMenuItem* item = (TTeamMenuItem*)ItemAt(index); if (item == NULL) break; item->SetOverrideWidth(newWidth); } Invalidate(); Window()->UpdateIfNeeded(); fBarView->CheckForScrolling(); } }
void TWindowMenu::AttachedToWindow() { //SetFont(be_plain_font); BMenuItem *item = NULL; while ((item = RemoveItem((int32)0)) != NULL) delete (item); int32 miniCount = 0; bool dragging = false; TBarView *barview =(static_cast<TBarApp *>(be_app))->BarView(); if (barview && barview->LockLooper()) { // 'dragging' mode set in BarView::CacheDragData // invoke in MouseEnter in ExpandoMenuBar dragging = barview->Dragging(); if (dragging) { // We don't want to show the menu when dragging, but it's not // possible to remove a submenu once it exists, so we simply hide it // Don't call BMenu::Hide(), it causes the menu to pop up every now // and then. Window()->Hide(); // if in expando (horizontal or vertical) if (barview->Expando()) { SetTrackingHook(barview->MenuTrackingHook, barview->GetTrackingHookData()); } barview->DragStart(); } barview->UnlockLooper(); } int32 parentMenuItems = 0; int32 numTeams = fTeam->CountItems(); for (int32 i = 0; i < numTeams; i++) { team_id theTeam = (team_id)fTeam->ItemAt(i); int32 count = 0; int32 *tokens = get_token_list(theTeam, &count); for (int32 j = 0; j < count; j++) { window_info *wInfo = get_window_info(tokens[j]); if (wInfo == NULL) continue; if (WindowShouldBeListed(wInfo->w_type) && (wInfo->show_hide_level <= 0 || wInfo->is_mini)) { // Don't add new items if we're expanded. We've already done this, // they've just been moved. int32 numItems = CountItems(); int32 addIndex = 0; for (; addIndex < numItems; addIndex++) if (strcasecmp(ItemAt(addIndex)->Label(), wInfo->name) > 0) break; if (!fExpanded) { TWindowMenuItem *item = new TWindowMenuItem(wInfo->name, wInfo->id, wInfo->is_mini, ((1 << current_workspace()) & wInfo->workspaces) != 0, dragging); // disable app's window dropping for now if (dragging) item->SetEnabled(false); AddItem(item, addIndex); } else { TTeamMenuItem *parentItem = static_cast<TTeamMenuItem *>(Superitem()); if (parentItem->ExpandedWindowItem(wInfo->id)) { TWindowMenuItem *item = parentItem->ExpandedWindowItem(wInfo->id); if (item == NULL) continue; item->SetTo(wInfo->name, wInfo->id, wInfo->is_mini, ((1 << current_workspace()) & wInfo->workspaces) != 0, dragging); parentMenuItems++; } } if (wInfo->is_mini) miniCount++; } free(wInfo); } free(tokens); } int32 itemCount = CountItems() + parentMenuItems; if (itemCount < 1) { TWindowMenuItem *noWindowsItem = new TWindowMenuItem("No Windows", -1, false, false); noWindowsItem->SetEnabled(false); AddItem(noWindowsItem); // if an application has no windows, this feature makes it easy to quit it. // (but we only add this option if the application is not Tracker.) if (fApplicationSignature.Compare(kTrackerSignature) != 0) { AddSeparatorItem(); AddItem(new TShowHideMenuItem("Quit Application", fTeam, B_QUIT_REQUESTED)); } } else { // if we are in drag mode, then don't add the window controls // to the menu if (!dragging) { TShowHideMenuItem *hide = new TShowHideMenuItem("Hide All", fTeam, B_MINIMIZE_WINDOW); TShowHideMenuItem *show = new TShowHideMenuItem("Show All", fTeam, B_BRING_TO_FRONT); TShowHideMenuItem* close = new TShowHideMenuItem("Close All", fTeam, B_QUIT_REQUESTED); if (miniCount == itemCount) hide->SetEnabled(false); else if (miniCount == 0) show->SetEnabled(false); if (!parentMenuItems) AddSeparatorItem(); AddItem(hide); AddItem(show); AddItem(close); } } BMenu::AttachedToWindow(); }
int32 ColumnListView::FullListCurrentSelection(int32 index) const { int32 Selection = CurrentSelection(index); CLVListItem* SelectedItem = (CLVListItem*)ItemAt(Selection); return FullListIndexOf(SelectedItem); }
bool AudioListView::InitiateDrag(BPoint point, int32 dragIndex, bool) { BListItem* item = ItemAt(CurrentSelection(0)); if (item == NULL) { // workaround for a timing problem (see Locale prefs) Select(dragIndex); item = ItemAt(dragIndex); } if (item == NULL) return false; // create drag message BMessage message(kDraggedItem); for (int32 i = 0;; i++) { int32 index = CurrentSelection(i); if (index < 0) break; message.AddPointer("trackitem", ItemAt(CurrentSelection(i))); } // figure out drag rect BRect dragRect(0.0, 0.0, Bounds().Width(), -1.0); // figure out, how many items fit into our bitmap bool fade = false; for (int32 i = 0; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)) == B_OK; i++) { dragRect.bottom += ceilf(item->Height()) + 1.0; 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; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)) == B_OK; i++) { AudioListItem* item; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)); 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 around 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; }
BLayoutItem* BLayoutContainer::RemoveItem(int32 index) { BLayoutItem *item = ItemAt(index); return(RemoveItem(item) ? item : NULL); }
already_AddRefed<DOMSVGPathSeg> DOMSVGPathSegList::ReplaceItem(DOMSVGPathSeg& aNewItem, uint32_t aIndex, ErrorResult& aError) { if (IsAnimValList()) { aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return nullptr; } if (aIndex >= LengthNoFlush()) { aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return nullptr; } nsRefPtr<DOMSVGPathSeg> domItem = &aNewItem; if (domItem->HasOwner()) { domItem = domItem->Clone(); // must do this before changing anything! } nsAttrValue emptyOrOldValue = Element()->WillChangePathSegList(); if (ItemAt(aIndex)) { // Notify any existing DOM item of removal *before* modifying the lists so // that the DOM item can copy the *old* value at its index: ItemAt(aIndex)->RemovingFromList(); } uint32_t internalIndex = mItems[aIndex].mInternalDataIndex; // We use InternalList() to get oldArgCount since we may not have a DOM // wrapper at the index being replaced. uint32_t oldType = SVGPathSegUtils::DecodeType(InternalList().mData[internalIndex]); uint32_t oldArgCount = SVGPathSegUtils::ArgCountForType(oldType); uint32_t newArgCount = SVGPathSegUtils::ArgCountForType(domItem->Type()); float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS]; domItem->ToSVGPathSegEncodedData(segAsRaw); bool ok = !!InternalList().mData.ReplaceElementsAt( internalIndex, 1 + oldArgCount, segAsRaw, 1 + newArgCount); if (!ok) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } ItemAt(aIndex) = domItem; // This MUST come after the ToSVGPathSegEncodedData call, otherwise that call // would end up reading bad data from InternalList()! domItem->InsertingIntoList(this, aIndex, IsAnimValList()); uint32_t delta = newArgCount - oldArgCount; if (delta != 0) { for (uint32_t i = aIndex + 1; i < LengthNoFlush(); ++i) { mItems[i].mInternalDataIndex += delta; } } Element()->DidChangePathSegList(emptyOrOldValue); if (AttrIsAnimating()) { Element()->AnimationNeedsResample(); } return domItem.forget(); }
void CTrackListView::MessageReceived( BMessage *message) { D_MESSAGE(("CTrackListView::MessageReceived()\n")); switch(message->what) { case CObservable::UPDATED: { int32 trackHint, docHint; int32 trackID; if (message->FindInt32("TrackID", &trackID) != B_OK) trackID = -1; if (message->FindInt32("TrackAttrs", &trackHint) != B_OK) trackHint = 0; if (message->FindInt32("DocAttrs", &docHint ) != B_OK) docHint = 0; if (trackHint != 0 || docHint != 0) { if (trackID >= 0) { for (int i = 0; i < CountItems(); i++) { CTrackListItem *item = dynamic_cast<CTrackListItem *> (ItemAt(i)); if (item && (item->GetTrackID() == trackID)) { if (trackHint & (CTrack::Update_Name | CTrack::Update_Flags)) { item->Update(this, be_plain_font); InvalidateItem(i); } } } } if ((docHint & CMeVDoc::Update_AddTrack) || (docHint & CMeVDoc::Update_DelTrack) || (docHint & CMeVDoc::Update_TrackOrder)) { BuildTrackList(); } } break; } case CTrackListItem::EDIT_TRACK: { D_MESSAGE((" -> CTrackListItem::EDIT_TRACK\n")); int32 selection = CurrentSelection(); if (selection >= 0) { CTrackListItem *item = (CTrackListItem *)ItemAt(selection); if (item) m_doc->ShowWindowFor(item->GetTrack()); } break; } case CTrackListItem::MUTE_TRACK: { D_MESSAGE((" -> CTrackListItem::MUTE_TRACK\n")); int32 selection = CurrentSelection(); if (selection >= 0) { CTrackListItem *item = (CTrackListItem *)ItemAt(selection); CTrack *track = item->GetTrack(); track->SetMuted(!track->Muted()); track->NotifyUpdate(CTrack::Update_Name, NULL); m_doc->SetModified(); } break; } case CTrackListItem::SOLO_TRACK: { D_MESSAGE((" -> CTrackListItem::SOLO_TRACK\n")); int32 selection = CurrentSelection(); if (selection >= 0) { // nyi } break; } case CTrackListItem::DELETE_TRACK: { D_MESSAGE((" -> CTrackListItem::DELETE_TRACK\n")); int32 selection = CurrentSelection(); if (selection >= 0) { CTrackListItem *item = (CTrackListItem *)ItemAt(selection); CTrack *track = item->GetTrack(); CTrackDeleteUndoAction *undoAction; undoAction = new CTrackDeleteUndoAction(track); m_doc->AddUndoAction(undoAction); } break; } case CTrackListItem::RENAME_TRACK: { D_MESSAGE((" -> CTrackListItem::RENAME_TRACK\n")); int32 index = CurrentSelection(); if (index < 0) return; CTrackListItem *item = dynamic_cast<CTrackListItem *>(ItemAt(index)); if (item) item->StartEdit(this, index, ItemFrame(index)); break; } case CTrackListItem::TRACK_NAME_EDITED: { D_MESSAGE((" -> CTrackListItem::TRACK_NAME_EDITED\n")); int32 index; BString name; if (message->FindInt32("index", &index) != B_OK) return; CTrackListItem *item = dynamic_cast<CTrackListItem *>(ItemAt(index)); if (!item) return; item->StopEdit(); if (message->FindString("text", &name) == B_OK) { // name changed CTrack *track = item->GetTrack(); CTrackRenameUndoAction *undoAction; undoAction = new CTrackRenameUndoAction(track, name); m_doc->AddUndoAction(undoAction); } MakeFocus(true); break; } case MeVDragMsg_ID: { D_MESSAGE((" -> MeVDragMsg_ID\n")); int32 type; if ((message->FindInt32("Type", &type) != B_OK) || (type != DragTrack_ID)) return; // change of track order requested int32 index; message->FindInt32("Index", &index); // find the target index BPoint point = ConvertFromScreen(message->DropPoint()); point.y -= ItemFrame(0).Height(); int32 dragIndex; if (point.y < 0.0) dragIndex = -1; else { dragIndex = IndexOf(point); if (dragIndex < 0) dragIndex = CountItems() - 1; } // reorder tracks if (dragIndex < index) { m_doc->ChangeTrackOrder(index, dragIndex + 1); m_doc->SetModified(); } else if (dragIndex > index) { m_doc->ChangeTrackOrder(index, dragIndex); m_doc->SetModified(); } break; } default: { BListView::MessageReceived(message); break; } } }
void BListView::MessageReceived(BMessage* message) { switch (message->what) { case B_MOUSE_WHEEL_CHANGED: if (!fTrack->is_dragging) BView::MessageReceived(message); break; case B_COUNT_PROPERTIES: case B_EXECUTE_PROPERTY: case B_GET_PROPERTY: case B_SET_PROPERTY: { BPropertyInfo propInfo(sProperties); BMessage specifier; const char* property; if (message->GetCurrentSpecifier(NULL, &specifier) != B_OK || specifier.FindString("property", &property) != B_OK) { return; } switch (propInfo.FindMatch(message, 0, &specifier, message->what, property)) { case B_ERROR: BView::MessageReceived(message); break; case 0: { BMessage reply(B_REPLY); reply.AddInt32("result", CountItems()); reply.AddInt32("error", B_OK); message->SendReply(&reply); break; } case 1: break; case 2: { int32 count = 0; for (int32 i = 0; i < CountItems(); i++) { if (ItemAt(i)->IsSelected()) count++; } BMessage reply(B_REPLY); reply.AddInt32("result", count); reply.AddInt32("error", B_OK); message->SendReply(&reply); break; } case 3: break; case 4: { BMessage reply (B_REPLY); for (int32 i = 0; i < CountItems(); i++) { if (ItemAt(i)->IsSelected()) reply.AddInt32("result", i); } reply.AddInt32("error", B_OK); message->SendReply(&reply); break; } case 5: break; case 6: { BMessage reply(B_REPLY); bool select; if (message->FindBool("data", &select) == B_OK && select) Select(0, CountItems() - 1, false); else DeselectAll(); reply.AddInt32("error", B_OK); message->SendReply(&reply); break; } } break; } case B_SELECT_ALL: if (fListType == B_MULTIPLE_SELECTION_LIST) Select(0, CountItems() - 1, false); break; default: BView::MessageReceived(message); } }
void MemoryBarMenu::Pulse() { system_info sinfo; get_system_info(&sinfo); int64 committedMemory = (int64)sinfo.used_pages * B_PAGE_SIZE / 1024; int64 cachedMemory = (int64)sinfo.cached_pages * B_PAGE_SIZE / 1024; Window()->BeginViewTransaction(); // create the list of items to remove, for their team is gone. Update the old teams. int lastRecycle = 0; int firstRecycle = 0; int k; MemoryBarMenuItem* item; int total = 0; for (k = 1; (item = (MemoryBarMenuItem*)ItemAt(k)) != NULL; k++) { int m = item->UpdateSituation(committedMemory); if (m < 0) { if (lastRecycle == fRecycleCount) { fRecycleCount += EXTRA; fRecycleList = (MRecycleItem*)realloc(fRecycleList, sizeof(MRecycleItem) * fRecycleCount); } fRecycleList[lastRecycle].index = k; fRecycleList[lastRecycle++].item = item; } else { if (lastRecycle > 0) { RemoveItems(fRecycleList[0].index, lastRecycle, true); k -= lastRecycle; lastRecycle = 0; } total += m; } } // Look new teams that have appeared. Create an item for them, or recycle from the list. int32 cookie = 0; info_pack infos; item = NULL; while (get_next_team_info(&cookie, &infos.team_info) == B_OK) { unsigned int j = 0; while (j < fTeamCount && infos.team_info.team != fTeamList[j]) { j++; } if (j == fTeamCount) { // new team team_info info; j = 0; while (j < fTeamCount && fTeamList[j] != -1) { if (get_team_info(fTeamList[j], &info) != B_OK) fTeamList[j] = -1; else j++; } if (j == fTeamCount) { fTeamCount += 10; fTeamList = (team_id*)realloc(fTeamList, sizeof(team_id) * fTeamCount); } fTeamList[j] = infos.team_info.team; if (!get_team_name_and_icon(infos, true)) { // the team is already gone! delete infos.team_icon; fTeamList[j] = -1; } else { if (!item && firstRecycle < lastRecycle) item = fRecycleList[firstRecycle++].item; if (item) item->Reset(infos.team_name, infos.team_info.team, infos.team_icon, true); else { AddItem(item = new MemoryBarMenuItem(infos.team_name, infos.team_info.team, infos.team_icon, true, NULL)); } int m = item->UpdateSituation(committedMemory); if (m >= 0) { total += m; item = NULL; } else fTeamList[j] = -1; } } } if (item) { RemoveItem(item); delete item; } // Delete the items that haven't been recycled. if (firstRecycle < lastRecycle) { RemoveItems(IndexOf(fRecycleList[firstRecycle].item), lastRecycle - firstRecycle, true); } fLastTotalTime = system_time(); KernelMemoryBarMenuItem *kernelItem; if ((kernelItem = (KernelMemoryBarMenuItem*)ItemAt(0)) != NULL) kernelItem->UpdateSituation(committedMemory, cachedMemory); Window()->EndViewTransaction(); Window()->Flush(); }
void BListView::MouseDown(BPoint where) { if (!IsFocus()) { MakeFocus(); Sync(); Window()->UpdateIfNeeded(); } BMessage* message = Looper()->CurrentMessage(); int32 index = IndexOf(where); int32 buttons = 0; if (message != NULL) message->FindInt32("buttons", &buttons); int32 modifiers = 0; if (message != NULL) message->FindInt32("modifiers", &modifiers); // If the user double (or more) clicked within the current selection, // we don't change the selection but invoke the selection. // TODO: move this code someplace where it can be shared everywhere // instead of every class having to reimplement it, once some sane // API for it is decided. BPoint delta = where - fTrack->drag_start; bigtime_t sysTime; Window()->CurrentMessage()->FindInt64("when", &sysTime); bigtime_t timeDelta = sysTime - fTrack->last_click_time; bigtime_t doubleClickSpeed; get_click_speed(&doubleClickSpeed); bool doubleClick = false; if (timeDelta < doubleClickSpeed && fabs(delta.x) < kDoubleClickThreshold && fabs(delta.y) < kDoubleClickThreshold && fTrack->item_index == index) { doubleClick = true; } if (doubleClick && index >= fFirstSelected && index <= fLastSelected) { fTrack->drag_start.Set(INT32_MAX, INT32_MAX); Invoke(); return BView::MouseDown(where); } if (!doubleClick) { fTrack->drag_start = where; fTrack->last_click_time = system_time(); fTrack->item_index = index; fTrack->was_selected = index >= 0 ? ItemAt(index)->IsSelected() : false; fTrack->try_drag = true; MouseDownThread<BListView>::TrackMouse(this, &BListView::_DoneTracking, &BListView::_Track); } if (index >= 0) { if (fListType == B_MULTIPLE_SELECTION_LIST) { if ((modifiers & B_SHIFT_KEY) != 0) { // select entire block // TODO: maybe review if we want it like in Tracker // (anchor item) if (index >= fFirstSelected && index < fLastSelected) { // clicked inside of selected items block, deselect all // but from the first selected item to the clicked item DeselectExcept(fFirstSelected, index); } else { Select(std::min(index, fFirstSelected), std::max(index, fLastSelected)); } } else { if ((modifiers & B_COMMAND_KEY) != 0) { // toggle selection state of clicked item (like in Tracker) // toggle selection state of clicked item if (ItemAt(index)->IsSelected()) Deselect(index); else Select(index, true); } else Select(index); } } else { // toggle selection state of clicked item if ((modifiers & B_COMMAND_KEY) != 0 && ItemAt(index)->IsSelected()) Deselect(index); else Select(index); } } else if ((modifiers & B_COMMAND_KEY) == 0) DeselectAll(); BView::MouseDown(where); }
NS_IMETHODIMP DOMSVGPathSegList::ReplaceItem(nsIDOMSVGPathSeg *aNewItem, PRUint32 aIndex, nsIDOMSVGPathSeg **_retval) { *_retval = nsnull; if (IsAnimValList()) { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; } nsCOMPtr<DOMSVGPathSeg> domItem = do_QueryInterface(aNewItem); if (!domItem) { return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR; } if (aIndex >= Length()) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } if (domItem->HasOwner()) { domItem = domItem->Clone(); // must do this before changing anything! } if (ItemAt(aIndex)) { // Notify any existing DOM item of removal *before* modifying the lists so // that the DOM item can copy the *old* value at its index: ItemAt(aIndex)->RemovingFromList(); } PRUint32 internalIndex = mItems[aIndex].mInternalDataIndex; // We use InternalList() to get oldArgCount since we may not have a DOM // wrapper at the index being replaced. PRUint32 oldType = SVGPathSegUtils::DecodeType(InternalList().mData[internalIndex]); PRUint32 oldArgCount = SVGPathSegUtils::ArgCountForType(oldType); PRUint32 newArgCount = SVGPathSegUtils::ArgCountForType(domItem->Type()); float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS]; domItem->ToSVGPathSegEncodedData(segAsRaw); PRBool ok = !!InternalList().mData.ReplaceElementsAt( internalIndex, 1 + oldArgCount, segAsRaw, 1 + newArgCount); if (!ok) { return NS_ERROR_OUT_OF_MEMORY; } ItemAt(aIndex) = domItem; // This MUST come after the ToSVGPathSegEncodedData call, otherwise that call // would end up reading bad data from InternalList()! domItem->InsertingIntoList(this, aIndex, IsAnimValList()); PRUint32 delta = newArgCount - oldArgCount; if (delta != 0) { for (PRUint32 i = aIndex + 1; i < Length(); ++i) { mItems[i].mInternalDataIndex += delta; } } Element()->DidChangePathSegList(PR_TRUE); #ifdef MOZ_SMIL if (AttrIsAnimating()) { Element()->AnimationNeedsResample(); } #endif NS_ADDREF(*_retval = domItem.get()); return NS_OK; }