Notification_Server: Added ability to choose position of notifications
The feature gives user ability to choose the position of notifications out of Follow Deskbar, Lower Right, Lower Left, Upper Right and Upper Left. Fixes #9749 - Notification_Server: add the ability to choose the position of notifications (easy). Signed-off-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
This commit is contained in:
parent
e229bf70b8
commit
226f6c8bf1
@ -6,10 +6,13 @@
|
||||
#define _NOTIFICATIONS_H
|
||||
|
||||
#include <Mime.h>
|
||||
#include <View.h>
|
||||
#include <String.h>
|
||||
|
||||
#define kNotificationServerSignature "application/x-vnd.Haiku-notification_server"
|
||||
|
||||
#define B_FOLLOW_DESKBAR B_FOLLOW_NONE
|
||||
|
||||
// Messages
|
||||
const uint32 kNotificationMessage = 'nssm';
|
||||
|
||||
@ -21,6 +24,7 @@ extern const char* kAutoStartName;
|
||||
extern const char* kTimeoutName;
|
||||
extern const char* kWidthName;
|
||||
extern const char* kIconSizeName;
|
||||
extern const char* kNotificationPositionName;
|
||||
|
||||
// General default settings
|
||||
const bool kDefaultAutoStart = true;
|
||||
@ -32,5 +36,6 @@ const float kMinimumWidth = 300.0f;
|
||||
const float kMaximumWidth = 1000.0f;
|
||||
const int32 kWidthStep = 50;
|
||||
const icon_size kDefaultIconSize = B_LARGE_ICON;
|
||||
const uint32 kDefaultNotificationPosition = B_FOLLOW_DESKBAR;
|
||||
|
||||
#endif // _NOTIFICATIONS_H
|
||||
|
@ -43,10 +43,27 @@
|
||||
const uint32 kToggleNotifications = '_TSR';
|
||||
const uint32 kWidthChanged = '_WIC';
|
||||
const uint32 kTimeoutChanged = '_TIC';
|
||||
const uint32 kPositionChanged = '_NPC';
|
||||
const uint32 kServerChangeTriggered = '_SCT';
|
||||
const BString kSampleMessageID("NotificationsSample");
|
||||
|
||||
|
||||
static int32
|
||||
notification_position_to_index(uint32 notification_position) {
|
||||
if (notification_position == B_FOLLOW_NONE)
|
||||
return 0;
|
||||
else if (notification_position == (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM))
|
||||
return 1;
|
||||
else if (notification_position == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM))
|
||||
return 2;
|
||||
else if (notification_position == (B_FOLLOW_RIGHT | B_FOLLOW_TOP))
|
||||
return 3;
|
||||
else if (notification_position == (B_FOLLOW_LEFT | B_FOLLOW_TOP))
|
||||
return 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
GeneralView::GeneralView(SettingsHost* host)
|
||||
:
|
||||
SettingsPane("general", host)
|
||||
@ -87,10 +104,37 @@ GeneralView::GeneralView(SettingsHost* host)
|
||||
B_TRANSLATE_COMMENT(minLabel.String(), "Slider low text"),
|
||||
B_TRANSLATE_COMMENT(maxLabel.String(), "Slider high text"));
|
||||
|
||||
// Notification Position
|
||||
fPositionMenu = new BPopUpMenu(B_TRANSLATE("Follow Deskbar"));
|
||||
const char* positionLabels[] = {
|
||||
B_TRANSLATE_MARK("Follow Deskbar"),
|
||||
B_TRANSLATE_MARK("Lower right"),
|
||||
B_TRANSLATE_MARK("Lower left"),
|
||||
B_TRANSLATE_MARK("Upper right"),
|
||||
B_TRANSLATE_MARK("Upper left")
|
||||
};
|
||||
const uint32 positions[] = {
|
||||
B_FOLLOW_DESKBAR, // Follow Deskbar
|
||||
B_FOLLOW_BOTTOM | B_FOLLOW_RIGHT, // Lower right
|
||||
B_FOLLOW_BOTTOM | B_FOLLOW_LEFT, // Lower left
|
||||
B_FOLLOW_TOP | B_FOLLOW_RIGHT, // Upper right
|
||||
B_FOLLOW_TOP | B_FOLLOW_LEFT // Upper left
|
||||
};
|
||||
for (int i=0; i < 5; i++) {
|
||||
BMessage* message = new BMessage(kPositionChanged);
|
||||
message->AddInt32(kNotificationPositionName, positions[i]);
|
||||
|
||||
fPositionMenu->AddItem(new BMenuItem(B_TRANSLATE_NOCOLLECT(
|
||||
positionLabels[i]), message));
|
||||
}
|
||||
BMenuField* positionField = new BMenuField(B_TRANSLATE("Position:"),
|
||||
fPositionMenu);
|
||||
|
||||
box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
|
||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||
.Add(fWidthSlider)
|
||||
.Add(fDurationSlider)
|
||||
.Add(positionField)
|
||||
.AddGlue()
|
||||
.View());
|
||||
|
||||
@ -108,6 +152,7 @@ GeneralView::AttachedToWindow()
|
||||
fNotificationBox->SetTarget(this);
|
||||
fWidthSlider->SetTarget(this);
|
||||
fDurationSlider->SetTarget(this);
|
||||
fPositionMenu->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
|
||||
@ -134,6 +179,15 @@ GeneralView::MessageReceived(BMessage* msg)
|
||||
SettingsPane::SettingsChanged(true);
|
||||
break;
|
||||
}
|
||||
case kPositionChanged:
|
||||
{
|
||||
int32 position;
|
||||
if (msg->FindInt32(kNotificationPositionName, &position) == B_OK) {
|
||||
fNewPosition = position;
|
||||
SettingsPane::SettingsChanged(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
break;
|
||||
@ -163,6 +217,12 @@ GeneralView::Load(BMessage& settings)
|
||||
else
|
||||
fOriginalIconSize = (icon_size)setting;
|
||||
|
||||
int32 position;
|
||||
if (settings.FindInt32(kNotificationPositionName, &position) != B_OK)
|
||||
fOriginalPosition = kDefaultNotificationPosition;
|
||||
else
|
||||
fOriginalPosition = position;
|
||||
|
||||
_EnableControls();
|
||||
|
||||
return Revert();
|
||||
@ -184,6 +244,8 @@ GeneralView::Save(BMessage& settings)
|
||||
icon_size iconSize = B_LARGE_ICON;
|
||||
settings.AddInt32(kIconSizeName, (int32)iconSize);
|
||||
|
||||
settings.AddInt32(kNotificationPositionName, (int32)fNewPosition);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -196,6 +258,12 @@ GeneralView::Revert()
|
||||
|
||||
fWidthSlider->SetValue(fOriginalWidth / 50);
|
||||
_SetWidthLabel(fOriginalWidth);
|
||||
|
||||
fNewPosition = fOriginalPosition;
|
||||
BMenuItem* item = fPositionMenu->ItemAt(
|
||||
notification_position_to_index(fNewPosition));
|
||||
if (item != NULL)
|
||||
item->SetMarked(true);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -212,6 +280,9 @@ GeneralView::RevertPossible()
|
||||
if (fOriginalWidth != width)
|
||||
return true;
|
||||
|
||||
if (fOriginalPosition != fNewPosition)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -225,6 +296,12 @@ GeneralView::Defaults()
|
||||
fWidthSlider->SetValue(kDefaultWidth / 50);
|
||||
_SetWidthLabel(kDefaultWidth);
|
||||
|
||||
fNewPosition = kDefaultNotificationPosition;
|
||||
BMenuItem* item = fPositionMenu->ItemAt(
|
||||
notification_position_to_index(fNewPosition));
|
||||
if (item != NULL)
|
||||
item->SetMarked(true);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -239,6 +316,9 @@ GeneralView::DefaultsPossible()
|
||||
int32 width = fWidthSlider->Value() * 50;
|
||||
if (kDefaultWidth != width)
|
||||
return true;
|
||||
|
||||
if (kDefaultNotificationPosition != fNewPosition)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -257,6 +337,10 @@ GeneralView::_EnableControls()
|
||||
bool enabled = fNotificationBox->Value() == B_CONTROL_ON;
|
||||
fWidthSlider->SetEnabled(enabled);
|
||||
fDurationSlider->SetEnabled(enabled);
|
||||
BMenuItem* item = fPositionMenu->ItemAt(
|
||||
notification_position_to_index(fOriginalPosition));
|
||||
if (item != NULL)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <Menu.h>
|
||||
#include <MenuField.h>
|
||||
#include <Mime.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <RadioButton.h>
|
||||
#include <Slider.h>
|
||||
#include <StringView.h>
|
||||
@ -40,10 +41,14 @@ private:
|
||||
BCheckBox* fNotificationBox;
|
||||
BSlider* fDurationSlider;
|
||||
BSlider* fWidthSlider;
|
||||
BPopUpMenu* fPositionMenu;
|
||||
|
||||
|
||||
int32 fOriginalTimeout;
|
||||
float fOriginalWidth;
|
||||
icon_size fOriginalIconSize;
|
||||
uint32 fOriginalPosition;
|
||||
uint32 fNewPosition;
|
||||
|
||||
void _EnableControls();
|
||||
void _SetWidthLabel(int32 value);
|
||||
|
@ -26,7 +26,9 @@
|
||||
#include <NodeMonitor.h>
|
||||
#include <Notifications.h>
|
||||
#include <Path.h>
|
||||
#include <Point.h>
|
||||
#include <PropertyInfo.h>
|
||||
#include <Screen.h>
|
||||
|
||||
#include "AppGroupView.h"
|
||||
#include "AppUsage.h"
|
||||
@ -50,6 +52,37 @@ property_info main_prop_list[] = {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if notification position overlaps with
|
||||
* deskbar position
|
||||
*/
|
||||
static bool
|
||||
is_overlapping(deskbar_location deskbar,
|
||||
uint32 notification) {
|
||||
if (deskbar == B_DESKBAR_RIGHT_TOP
|
||||
&& notification == (B_FOLLOW_RIGHT | B_FOLLOW_TOP))
|
||||
return true;
|
||||
if (deskbar == B_DESKBAR_RIGHT_BOTTOM
|
||||
&& notification == (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM))
|
||||
return true;
|
||||
if (deskbar == B_DESKBAR_LEFT_TOP
|
||||
&& notification == (B_FOLLOW_LEFT | B_FOLLOW_TOP))
|
||||
return true;
|
||||
if (deskbar == B_DESKBAR_LEFT_BOTTOM
|
||||
&& notification == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM))
|
||||
return true;
|
||||
if (deskbar == B_DESKBAR_TOP
|
||||
&& (notification == (B_FOLLOW_LEFT | B_FOLLOW_TOP)
|
||||
|| notification == (B_FOLLOW_RIGHT | B_FOLLOW_TOP)))
|
||||
return true;
|
||||
if (deskbar == B_DESKBAR_BOTTOM
|
||||
&& (notification == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)
|
||||
|| notification == (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
NotificationWindow::NotificationWindow()
|
||||
:
|
||||
BWindow(BRect(0, 0, -1, -1), B_TRANSLATE_MARK("Notification"),
|
||||
@ -63,7 +96,7 @@ NotificationWindow::NotificationWindow()
|
||||
fCachePath.Append("Notifications");
|
||||
BDirectory cacheDir;
|
||||
result = cacheDir.SetTo(fCachePath.Path());
|
||||
if(result == B_ENTRY_NOT_FOUND)
|
||||
if (result == B_ENTRY_NOT_FOUND)
|
||||
cacheDir.CreateDirectory(fCachePath.Path(), NULL);
|
||||
|
||||
SetLayout(new BGroupLayout(B_VERTICAL, 0));
|
||||
@ -146,8 +179,8 @@ NotificationWindow::MessageReceived(BMessage* message)
|
||||
BString sourceName(notification->SourceName());
|
||||
|
||||
bool allow = false;
|
||||
appfilter_t::iterator it =
|
||||
fAppFilters.find(sourceSignature.String());
|
||||
appfilter_t::iterator it = fAppFilters
|
||||
.find(sourceSignature.String());
|
||||
|
||||
AppUsage* appUsage = NULL;
|
||||
if (it == fAppFilters.end()) {
|
||||
@ -275,43 +308,70 @@ NotificationWindow::SetPosition()
|
||||
|
||||
float x = Frame().left;
|
||||
float y = Frame().top;
|
||||
// If we can't guess, don't move...
|
||||
// If we cant guess, don't move...
|
||||
BPoint location(x, y);
|
||||
|
||||
BDeskbar deskbar;
|
||||
BRect frame = deskbar.Frame();
|
||||
|
||||
switch (deskbar.Location()) {
|
||||
case B_DESKBAR_TOP:
|
||||
// Put it just under, top right corner
|
||||
y = frame.bottom + topOffset;
|
||||
x = frame.right - width + rightOffset;
|
||||
break;
|
||||
case B_DESKBAR_BOTTOM:
|
||||
// Put it just above, lower left corner
|
||||
y = frame.top - height - bottomOffset;
|
||||
x = frame.right - width + rightOffset;
|
||||
break;
|
||||
case B_DESKBAR_RIGHT_TOP:
|
||||
x = frame.left - width - rightOffset;
|
||||
y = frame.top - topOffset + 1;
|
||||
break;
|
||||
case B_DESKBAR_LEFT_TOP:
|
||||
x = frame.right + leftOffset;
|
||||
y = frame.top - topOffset + 1;
|
||||
break;
|
||||
case B_DESKBAR_RIGHT_BOTTOM:
|
||||
y = frame.bottom - height + bottomOffset;
|
||||
x = frame.left - width - rightOffset;
|
||||
break;
|
||||
case B_DESKBAR_LEFT_BOTTOM:
|
||||
y = frame.bottom - height + bottomOffset;
|
||||
x = frame.right + leftOffset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
// If notification and deskbar position are same
|
||||
// then follow deskbar position
|
||||
uint32 position = (is_overlapping(deskbar.Location(), fPosition))
|
||||
? B_FOLLOW_DESKBAR
|
||||
: fPosition;
|
||||
|
||||
|
||||
if (position == B_FOLLOW_DESKBAR)
|
||||
{
|
||||
BRect frame = deskbar.Frame();
|
||||
switch (deskbar.Location()) {
|
||||
case B_DESKBAR_TOP:
|
||||
// In case of overlapping here or for bottom
|
||||
// use user's notification position
|
||||
y = frame.bottom + topOffset;
|
||||
x = (fPosition == B_FOLLOW_LEFT | B_FOLLOW_TOP)
|
||||
? frame.left + rightOffset
|
||||
: frame.right - width + rightOffset;
|
||||
break;
|
||||
case B_DESKBAR_BOTTOM:
|
||||
y = frame.top - height - bottomOffset;
|
||||
x = (fPosition == B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)
|
||||
? frame.left + rightOffset
|
||||
: frame.right - width + rightOffset;
|
||||
break;
|
||||
case B_DESKBAR_RIGHT_TOP:
|
||||
y = frame.top - topOffset + 1;
|
||||
x = frame.left - width - rightOffset;
|
||||
break;
|
||||
case B_DESKBAR_LEFT_TOP:
|
||||
y = frame.top - topOffset + 1;
|
||||
x = frame.right + leftOffset;
|
||||
break;
|
||||
case B_DESKBAR_RIGHT_BOTTOM:
|
||||
y = frame.bottom - height + bottomOffset;
|
||||
x = frame.left - width - rightOffset;
|
||||
break;
|
||||
case B_DESKBAR_LEFT_BOTTOM:
|
||||
y = frame.bottom - height + bottomOffset;
|
||||
x = frame.right + leftOffset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
location = BPoint(x, y);
|
||||
} else if (position == (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)) {
|
||||
location = BScreen().Frame().RightBottom();
|
||||
location -= BPoint(width, height);
|
||||
} else if (position == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)) {
|
||||
location = BScreen().Frame().LeftBottom();
|
||||
location -= BPoint(0, height);
|
||||
} else if (position == (B_FOLLOW_RIGHT | B_FOLLOW_TOP)) {
|
||||
location = BScreen().Frame().RightTop();
|
||||
location -= BPoint(width, 0);
|
||||
} else if (position == (B_FOLLOW_LEFT | B_FOLLOW_TOP)) {
|
||||
location = BScreen().Frame().LeftTop();
|
||||
}
|
||||
|
||||
MoveTo(x, y);
|
||||
MoveTo(location);
|
||||
}
|
||||
|
||||
|
||||
@ -402,6 +462,12 @@ NotificationWindow::_LoadDisplaySettings(BMessage& settings)
|
||||
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) {
|
||||
|
@ -63,6 +63,7 @@ private:
|
||||
float fWidth;
|
||||
icon_size fIconSize;
|
||||
int32 fTimeout;
|
||||
uint32 fPosition;
|
||||
bool fShouldRun;
|
||||
BPath fCachePath;
|
||||
};
|
||||
|
@ -17,3 +17,4 @@ const char* kTimeoutName = "timeout";
|
||||
// Display settings
|
||||
const char* kWidthName = "width";
|
||||
const char* kIconSizeName = "icon size";
|
||||
const char* kNotificationPositionName = "notification position";
|
||||
|
Loading…
Reference in New Issue
Block a user