void NotificationWindow::_LoadDisplaySettings(BMessage& settings) { int32 setting; float originalWidth = fWidth; if (settings.FindFloat(kWidthName, &fWidth) != B_OK) fWidth = kDefaultWidth; if (originalWidth != fWidth) GetLayout()->SetExplicitSize(BSize(fWidth, B_SIZE_UNSET)); if (settings.FindInt32(kIconSizeName, &setting) != B_OK) fIconSize = kDefaultIconSize; else fIconSize = (icon_size)setting; int32 position; if (settings.FindInt32(kNotificationPositionName, &position) != B_OK) fPosition = kDefaultNotificationPosition; else fPosition = position; // Notify the views about the change appview_t::iterator aIt; for (aIt = fAppViews.begin(); aIt != fAppViews.end(); ++aIt) { AppGroupView* view = aIt->second; view->Invalidate(); } }
void NotificationWindow::_ResizeAll() { appview_t::iterator aIt; bool shouldHide = true; for (aIt = fAppViews.begin(); aIt != fAppViews.end(); aIt++) { AppGroupView* app = aIt->second; if (app->HasChildren()) { shouldHide = false; break; } } if (shouldHide) { if (!IsHidden()) Hide(); return; } for (aIt = fAppViews.begin(); aIt != fAppViews.end(); aIt++) { AppGroupView* view = aIt->second; if (!view->HasChildren()) { if (!view->IsHidden()) view->Hide(); } else { if (view->IsHidden()) view->Show(); } } SetPosition(); if (IsHidden()) Show(); }
void NotificationWindow::ResizeAll() { if (fAppViews.empty()) { if (!IsHidden()) Hide(); return; } appview_t::iterator aIt; bool shouldHide = true; for (aIt = fAppViews.begin(); aIt != fAppViews.end(); aIt++) { AppGroupView* app = aIt->second; if (app->HasChildren()) { shouldHide = false; break; } } if (shouldHide) { if (!IsHidden()) Hide(); return; } if (IsHidden()) Show(); float width = 0; float height = 0; for (aIt = fAppViews.begin(); aIt != fAppViews.end(); aIt++) { AppGroupView* view = aIt->second; float w = -1; float h = -1; if (!view->HasChildren()) { if (!view->IsHidden()) view->Hide(); } else { view->GetPreferredSize(&w, &h); width = max_c(width, h); view->ResizeToPreferred(); view->MoveTo(0, height); height += h; if (view->IsHidden()) view->Show(); } } ResizeTo(ViewWidth(), height); PopupAnimation(Bounds().Width(), Bounds().Height()); }
void NotificationWindow::MessageReceived(BMessage* message) { switch (message->what) { case B_NODE_MONITOR: { LoadSettings(); LoadAppFilters(); break; } case kResizeToFit: ResizeAll(); break; case B_COUNT_PROPERTIES: { BMessage reply(B_REPLY); BMessage specifier; const char* property = NULL; bool messageOkay = true; if (message->FindMessage("specifiers", 0, &specifier) != B_OK) messageOkay = false; if (specifier.FindString("property", &property) != B_OK) messageOkay = false; if (strcmp(property, "message") != 0) messageOkay = false; if (messageOkay) reply.AddInt32("result", fViews.size()); else { reply.what = B_MESSAGE_NOT_UNDERSTOOD; reply.AddInt32("error", B_ERROR); } message->SendReply(&reply); break; } case B_CREATE_PROPERTY: case kNotificationMessage: { int32 type; const char* content = NULL; const char* title = NULL; const char* app = NULL; BMessage reply(B_REPLY); bool messageOkay = true; if (message->FindInt32("type", &type) != B_OK) type = B_INFORMATION_NOTIFICATION; if (message->FindString("content", &content) != B_OK) messageOkay = false; if (message->FindString("title", &title) != B_OK) messageOkay = false; if (message->FindString("app", &app) != B_OK && message->FindString("appTitle", &app) != B_OK) messageOkay = false; if (messageOkay) { NotificationView* view = new NotificationView(this, (notification_type)type, app, title, content, new BMessage(*message)); appfilter_t::iterator fIt = fAppFilters.find(app); bool allow = false; if (fIt == fAppFilters.end()) { app_info info; BMessenger messenger = message->ReturnAddress(); if (messenger.IsValid()) be_roster->GetRunningAppInfo(messenger.Team(), &info); else be_roster->GetAppInfo("application/x-vnd.Be-SHEL", &info); AppUsage* appUsage = new AppUsage(info.ref, app, true); fAppFilters[app] = appUsage; appUsage->Allowed(title, (notification_type)type); allow = true; } else allow = fIt->second->Allowed(title, (notification_type)type); if (allow) { appview_t::iterator aIt = fAppViews.find(app); AppGroupView* group = NULL; if (aIt == fAppViews.end()) { group = new AppGroupView(this, app); fAppViews[app] = group; fBorder->AddChild(group); } else group = aIt->second; group->AddInfo(view); ResizeAll(); reply.AddInt32("error", B_OK); } else reply.AddInt32("error", B_NOT_ALLOWED); } else { reply.what = B_MESSAGE_NOT_UNDERSTOOD; reply.AddInt32("error", B_ERROR); } message->SendReply(&reply); break; } case kRemoveView: { void* _ptr; message->FindPointer("view", &_ptr); NotificationView* info = reinterpret_cast<NotificationView*>(_ptr); fBorder->RemoveChild(info); std::vector<NotificationView*>::iterator i = find(fViews.begin(), fViews.end(), info); if (i != fViews.end()) fViews.erase(i); delete info; ResizeAll(); break; } default: BWindow::MessageReceived(message); } }
void NotificationWindow::MessageReceived(BMessage* message) { switch (message->what) { case B_NODE_MONITOR: { _LoadSettings(); _LoadAppFilters(); break; } case B_COUNT_PROPERTIES: { BMessage reply(B_REPLY); BMessage specifier; const char* property = NULL; bool messageOkay = true; if (message->FindMessage("specifiers", 0, &specifier) != B_OK) messageOkay = false; if (specifier.FindString("property", &property) != B_OK) messageOkay = false; if (strcmp(property, "message") != 0) messageOkay = false; if (messageOkay) reply.AddInt32("result", fViews.size()); else { reply.what = B_MESSAGE_NOT_UNDERSTOOD; reply.AddInt32("error", B_ERROR); } message->SendReply(&reply); break; } case B_CREATE_PROPERTY: case kNotificationMessage: { BMessage reply(B_REPLY); BNotification* notification = new BNotification(message); if (notification->InitCheck() == B_OK) { bigtime_t timeout; if (message->FindInt64("timeout", &timeout) != B_OK) timeout = -1; BMessenger messenger = message->ReturnAddress(); app_info info; if (messenger.IsValid()) be_roster->GetRunningAppInfo(messenger.Team(), &info); else be_roster->GetAppInfo("application/x-vnd.Be-SHEL", &info); NotificationView* view = new NotificationView(this, notification, timeout); bool allow = false; appfilter_t::iterator it = fAppFilters.find(info.signature); if (it == fAppFilters.end()) { AppUsage* appUsage = new AppUsage(notification->Group(), true); appUsage->Allowed(notification->Title(), notification->Type()); fAppFilters[info.signature] = appUsage; allow = true; } else { allow = it->second->Allowed(notification->Title(), notification->Type()); } if (allow) { BString groupName(notification->Group()); appview_t::iterator aIt = fAppViews.find(groupName); AppGroupView* group = NULL; if (aIt == fAppViews.end()) { group = new AppGroupView(this, groupName == "" ? NULL : groupName.String()); fAppViews[groupName] = group; GetLayout()->AddView(group); } else group = aIt->second; group->AddInfo(view); _ResizeAll(); reply.AddInt32("error", B_OK); } else reply.AddInt32("error", B_NOT_ALLOWED); } else { reply.what = B_MESSAGE_NOT_UNDERSTOOD; reply.AddInt32("error", B_ERROR); } message->SendReply(&reply); break; } case kRemoveView: { NotificationView* view = NULL; if (message->FindPointer("view", (void**)&view) != B_OK) return; views_t::iterator it = find(fViews.begin(), fViews.end(), view); if (it != fViews.end()) fViews.erase(it); _ResizeAll(); break; } default: BWindow::MessageReceived(message); } }
void NotificationView::Draw(BRect updateRect) { BRect progRect; SetDrawingMode(B_OP_ALPHA); SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); // Icon size float iconSize = (float)fParent->IconSize(); BRect stripeRect = Bounds(); stripeRect.right = kIconStripeWidth; SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT)); FillRect(stripeRect); SetHighColor(fStripeColor); stripeRect.right = 2; FillRect(stripeRect); SetHighColor(ui_color(B_PANEL_TEXT_COLOR)); // Rectangle for icon and overlay icon BRect iconRect(0, 0, 0, 0); // Draw icon if (fBitmap) { float ix = 18; float iy = (Bounds().Height() - iconSize) / 4.0; // Icon is vertically centered in view if (fNotification->Type() == B_PROGRESS_NOTIFICATION) { // Move icon up by half progress bar height if it's present iy -= (progRect.Height() + kEdgePadding); } iconRect.Set(ix, iy, ix + iconSize - 1.0, iy + iconSize - 1.0); DrawBitmapAsync(fBitmap, fBitmap->Bounds(), iconRect); } // Draw content LineInfoList::iterator lIt; for (lIt = fLines.begin(); lIt != fLines.end(); lIt++) { LineInfo *l = (*lIt); SetFont(&l->font); // Truncate the string. We have already line-wrapped the text but if // there is a very long 'word' we can only truncate it. TruncateString(&(l->text), B_TRUNCATE_END, Bounds().Width() - l->location.x); DrawString(l->text.String(), l->text.Length(), l->location); } rgb_color detailCol = ui_color(B_CONTROL_BORDER_COLOR); detailCol = tint_color(detailCol, B_LIGHTEN_2_TINT); AppGroupView* groupView = dynamic_cast<AppGroupView*>(Parent()); if (groupView != NULL && groupView->ChildrenCount() > 1) _DrawCloseButton(updateRect); SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); BPoint left(Bounds().left, Bounds().top); BPoint right(Bounds().right, Bounds().top); StrokeLine(left, right); Sync(); }
void NotificationWindow::MessageReceived(BMessage* message) { switch (message->what) { case B_NODE_MONITOR: { _LoadSettings(); break; } case kNotificationMessage: { if (!fShouldRun) break; BMessage reply(B_REPLY); BNotification* notification = new BNotification(message); if (notification->InitCheck() == B_OK) { bigtime_t timeout; if (message->FindInt64("timeout", &timeout) != B_OK) timeout = fTimeout; BString sourceSignature(notification->SourceSignature()); BString sourceName(notification->SourceName()); bool allow = false; appfilter_t::iterator it = fAppFilters .find(sourceSignature.String()); AppUsage* appUsage = NULL; if (it == fAppFilters.end()) { if (sourceSignature.Length() > 0 && sourceName.Length() > 0) { appUsage = new AppUsage(sourceName.String(), sourceSignature.String(), true); fAppFilters[sourceSignature.String()] = appUsage; // TODO save back to settings file } allow = true; } else { appUsage = it->second; allow = appUsage->Allowed(); } if (allow) { BString groupName(notification->Group()); appview_t::iterator aIt = fAppViews.find(groupName); AppGroupView* group = NULL; if (aIt == fAppViews.end()) { group = new AppGroupView(this, groupName == "" ? NULL : groupName.String()); fAppViews[groupName] = group; GetLayout()->AddView(group); } else group = aIt->second; NotificationView* view = new NotificationView(notification, timeout, fIconSize); group->AddInfo(view); _ShowHide(); reply.AddInt32("error", B_OK); } else reply.AddInt32("error", B_NOT_ALLOWED); } else { reply.what = B_MESSAGE_NOT_UNDERSTOOD; reply.AddInt32("error", B_ERROR); } message->SendReply(&reply); break; } case kRemoveGroupView: { AppGroupView* view = NULL; if (message->FindPointer("view", (void**)&view) != B_OK) return; // It's possible that between sending this message, and us receiving // it, the view has become used again, in which case we shouldn't // delete it. if (view->HasChildren()) return; // this shouldn't happen if (fAppViews.erase(view->Group()) < 1) break; view->RemoveSelf(); delete view; _ShowHide(); break; } default: BWindow::MessageReceived(message); } }