hrev51704 adds 3 changesets to branch 'master'
old head: e229bf70b8765f280c32864ce69a33285f979b26
new head: 0278976dd53ef7bcf6f17c027c26c41087b14fac
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=0278976dd53e+%5Ee229bf70b876
----------------------------------------------------------------------------
226f6c8bf18d: 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@xxxxxxxxxxxxx>
[ Hrishi Hiraskar <hrishihiraskar@xxxxxxxxx> ]
d2f5cd017cbe: WebPositive: Improve CookieWindow cookie deletion
Fixes Coverity issue CID 1340122.
Also resolves two TODO items in the code: allowing the deletion
of a selection of cookies, and deleting all cookies from a site
when there are no specific cookies selected.
Signed-off-by: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
[ ohnx <me@xxxxxxxxx> ]
0278976dd53e: magnify: make it controllable by scripting
scripting properties:
* Info, Grid, and Stick (true/false)
* CopyImage
* MakeSquare
* Zoom (1-100)
Decreasing pixel size from the menu will half the size
until it's less than 32.
fixes #13884
Signed-off-by: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
[ Owen <owenca@xxxxxxxxxxxxxxxxxxxxxxxx> ]
----------------------------------------------------------------------------
9 files changed, 413 insertions(+), 65 deletions(-)
headers/private/notification/Notifications.h | 5 +
src/apps/magnify/Magnify.cpp | 194 ++++++++++++++++++--
src/apps/magnify/Magnify.h | 5 +
src/apps/webpositive/CookieWindow.cpp | 47 +++--
src/preferences/notifications/GeneralView.cpp | 84 +++++++++
src/preferences/notifications/GeneralView.h | 5 +
src/servers/notification/NotificationWindow.cpp | 136 ++++++++++----
src/servers/notification/NotificationWindow.h | 1 +
src/servers/notification/Notifications.cpp | 1 +
############################################################################
Commit: 226f6c8bf18d1d1250d91dc630de3662bdc03ec8
URL: http://cgit.haiku-os.org/haiku/commit/?id=226f6c8bf18d
Author: Hrishi Hiraskar <hrishihiraskar@xxxxxxxxx>
Date: Mon Dec 11 10:54:02 2017 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Commit-Date: Sun Dec 24 11:02:38 2017 UTC
Ticket: https://dev.haiku-os.org/ticket/9749
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@xxxxxxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/headers/private/notification/Notifications.h
b/headers/private/notification/Notifications.h
index 18298a4..2f3ac9e 100644
--- a/headers/private/notification/Notifications.h
+++ b/headers/private/notification/Notifications.h
@@ -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
diff --git a/src/preferences/notifications/GeneralView.cpp
b/src/preferences/notifications/GeneralView.cpp
index bbd831f..bde3688 100644
--- a/src/preferences/notifications/GeneralView.cpp
+++ b/src/preferences/notifications/GeneralView.cpp
@@ -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);
}
diff --git a/src/preferences/notifications/GeneralView.h
b/src/preferences/notifications/GeneralView.h
index 0bd5a084..9106cee 100644
--- a/src/preferences/notifications/GeneralView.h
+++ b/src/preferences/notifications/GeneralView.h
@@ -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);
diff --git a/src/servers/notification/NotificationWindow.cpp
b/src/servers/notification/NotificationWindow.cpp
index bad3683..f00a5fd 100644
--- a/src/servers/notification/NotificationWindow.cpp
+++ b/src/servers/notification/NotificationWindow.cpp
@@ -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) {
diff --git a/src/servers/notification/NotificationWindow.h
b/src/servers/notification/NotificationWindow.h
index f4325a9..8861453 100644
--- a/src/servers/notification/NotificationWindow.h
+++ b/src/servers/notification/NotificationWindow.h
@@ -63,6 +63,7 @@ private:
float fWidth;
icon_size fIconSize;
int32 fTimeout;
+ uint32 fPosition;
bool fShouldRun;
BPath fCachePath;
};
diff --git a/src/servers/notification/Notifications.cpp
b/src/servers/notification/Notifications.cpp
index 3dfcb1e..d49f0c3 100644
--- a/src/servers/notification/Notifications.cpp
+++ b/src/servers/notification/Notifications.cpp
@@ -17,3 +17,4 @@ const char* kTimeoutName = "timeout";
// Display settings
const char* kWidthName = "width";
const char* kIconSizeName = "icon size";
+const char* kNotificationPositionName = "notification position";
############################################################################
Commit: d2f5cd017cbe2a9718601ab45a6772f6d6265074
URL: http://cgit.haiku-os.org/haiku/commit/?id=d2f5cd017cbe
Author: ohnx <me@xxxxxxxxx>
Date: Thu Dec 21 04:36:08 2017 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Commit-Date: Sun Dec 24 11:04:21 2017 UTC
WebPositive: Improve CookieWindow cookie deletion
Fixes Coverity issue CID 1340122.
Also resolves two TODO items in the code: allowing the deletion
of a selection of cookies, and deleting all cookies from a site
when there are no specific cookies selected.
Signed-off-by: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/apps/webpositive/CookieWindow.cpp
b/src/apps/webpositive/CookieWindow.cpp
index a8b7ec2..abb21c3 100644
--- a/src/apps/webpositive/CookieWindow.cpp
+++ b/src/apps/webpositive/CookieWindow.cpp
@@ -144,7 +144,7 @@ CookieWindow::CookieWindow(BRect frame, BNetworkCookieJar&
jar)
.Add(fCookies)
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
.SetInsets(5, 5, 5, 5)
-#if 0
+#if DEBUG
.Add(new BButton("import", B_TRANSLATE("Import"
B_UTF8_ELLIPSIS),
NULL))
.Add(new BButton("export", B_TRANSLATE("Export"
B_UTF8_ELLIPSIS),
@@ -303,7 +303,7 @@ CookieWindow::_AddDomain(BString domain, bool fake)
}
}
-#if 0
+#if DEBUG
puts("==============================");
for (i = 0; i < fDomains->FullListCountItems(); i++) {
BStringItem* t = (BStringItem*)fDomains->FullListItemAt(i);
@@ -373,19 +373,40 @@ CookieWindow::_ShowCookiesForDomain(BString domain)
void
CookieWindow::_DeleteCookies()
{
- // TODO shall we handle multiple selection here?
- CookieRow* row = (CookieRow*)fCookies->CurrentSelection();
- if (row == NULL) {
- // TODO see if a domain is selected in the domain list, and
delete all
- // cookies for that domain
- return;
+ CookieRow* row;
+ CookieRow* prevRow;
+
+ for (prevRow = NULL; ; prevRow = row) {
+ row = (CookieRow*)fCookies->CurrentSelection(prevRow);
+
+ if (prevRow != NULL) {
+ fCookies->RemoveRow(prevRow);
+ delete prevRow;
+ }
+
+ if (row == NULL)
+ break;
+
+ // delete this cookie
+ BNetworkCookie& cookie = row->Cookie();
+ cookie.SetExpirationDate(0);
+ fCookieJar.AddCookie(cookie);
}
- fCookies->RemoveRow(row);
+ // A domain was selected in the domain list
+ if (prevRow == NULL) {
+ while (true) {
+ // Clear the first cookie continuously
+ row = (CookieRow*)fCookies->RowAt(0);
- BNetworkCookie& cookie = row->Cookie();
- cookie.SetExpirationDate(0);
- fCookieJar.AddCookie(cookie);
+ if (row == NULL)
+ break;
- delete row;
+ BNetworkCookie& cookie = row->Cookie();
+ cookie.SetExpirationDate(0);
+ fCookieJar.AddCookie(cookie);
+ fCookies->RemoveRow(row);
+ delete row;
+ }
+ }
}
############################################################################
Revision: hrev51704
Commit: 0278976dd53ef7bcf6f17c027c26c41087b14fac
URL: http://cgit.haiku-os.org/haiku/commit/?id=0278976dd53e
Author: Owen <owenca@xxxxxxxxxxxxxxxxxxxxxxxx>
Date: Tue Dec 19 10:37:54 2017 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Commit-Date: Sun Dec 24 11:05:09 2017 UTC
Ticket: https://dev.haiku-os.org/ticket/13884
magnify: make it controllable by scripting
scripting properties:
* Info, Grid, and Stick (true/false)
* CopyImage
* MakeSquare
* Zoom (1-100)
Decreasing pixel size from the menu will half the size
until it's less than 32.
fixes #13884
Signed-off-by: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/apps/magnify/Magnify.cpp b/src/apps/magnify/Magnify.cpp
index 02d7c4a..08e7fa0 100644
--- a/src/apps/magnify/Magnify.cpp
+++ b/src/apps/magnify/Magnify.cpp
@@ -26,6 +26,7 @@
#include <NodeInfo.h>
#include <Path.h>
#include <PopUpMenu.h>
+#include <PropertyInfo.h>
#include <Screen.h>
#include <ScrollView.h>
#include <TextView.h>
@@ -98,6 +99,40 @@ const int32 kDefaultPixelSize = 8;
const int32 kBorderSize = 10;
+static property_info sProperties[] = {
+ { "Info", { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
+ { B_DIRECT_SPECIFIER, 0 },
+ "Show/hide info.", 0,
+ { B_BOOL_TYPE }
+ },
+ { "Grid", { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
+ { B_DIRECT_SPECIFIER, 0 },
+ "Show/hide grid.", 0,
+ { B_BOOL_TYPE }
+ },
+ { "MakeSquare", { B_EXECUTE_PROPERTY, 0 },
+ { B_DIRECT_SPECIFIER, 0 },
+ "Make the view square.", 0,
+ },
+ { "Zoom", { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
+ { B_DIRECT_SPECIFIER, 0 },
+ "Gets/sets the zoom factor (1-16).", 0,
+ { B_INT32_TYPE }
+ },
+ { "Stick", { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
+ { B_DIRECT_SPECIFIER, 0 },
+ "Stick/unstick coordinates.", 0,
+ { B_BOOL_TYPE }
+ },
+ { "CopyImage", { B_EXECUTE_PROPERTY, 0 },
+ { B_DIRECT_SPECIFIER, 0 },
+ "Copy image to clipboard.", 0,
+ },
+
+ { 0 }
+};
+
+
static float
FontHeight(BView* target, bool full)
{
@@ -304,12 +339,126 @@ TWindow::~TWindow()
}
+status_t
+TWindow::GetSupportedSuites(BMessage* msg)
+{
+ msg->AddString("suites", "suite/x-vnd.Haiku-Magnify");
+
+ BPropertyInfo propertyInfo(sProperties);
+ msg->AddFlat("messages", &propertyInfo);
+
+ return BHandler::GetSupportedSuites(msg);
+}
+
+
+BHandler*
+TWindow::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier,
+ int32 what, const char* property)
+{
+ BPropertyInfo propertyInfo(sProperties);
+ if (propertyInfo.FindMatch(msg, index, specifier, what, property) >= 0)
+ return this;
+
+ return BHandler::ResolveSpecifier(msg, index, specifier, what,
property);
+}
+
+
void
TWindow::MessageReceived(BMessage* m)
{
bool active = fFatBits->Active();
switch (m->what) {
+ case B_EXECUTE_PROPERTY:
+ case B_GET_PROPERTY:
+ case B_SET_PROPERTY:
+ {
+ int32 index;
+ BMessage specifier;
+ int32 what;
+ const char* property;
+ if (m->GetCurrentSpecifier(&index, &specifier, &what,
&property)
+ != B_OK)
+ return BWindow::MessageReceived(m);
+
+ status_t result = B_OK;
+ BMessage reply(B_REPLY);
+
+ BPropertyInfo propertyInfo(sProperties);
+ switch (propertyInfo.FindMatch(m, index, &specifier,
what,
+ property)) {
+ case 0:
+ if (m->what == B_GET_PROPERTY)
+ result =
reply.AddBool("result", fInfoBarState);
+ else if (m->what == B_SET_PROPERTY) {
+ bool showInfo;
+ result = m->FindBool("data",
&showInfo);
+ if (result == B_OK) {
+ fInfoBarState =
showInfo;
+ ShowInfo(fInfoBarState);
+ }
+ }
+ break;
+
+ case 1:
+ if (m->what == B_GET_PROPERTY)
+ result =
reply.AddBool("result", fShowGrid);
+ else if (m->what == B_SET_PROPERTY) {
+ bool showGrid;
+ result = m->FindBool("data",
&showGrid);
+ if (result == B_OK)
+ SetGrid(showGrid);
+ }
+ break;
+
+ case 2:
+ if (fHPixelCount != fVPixelCount) {
+ int32 big = fHPixelCount >
fVPixelCount ? fHPixelCount
+
: fVPixelCount;
+ ResizeWindow(big, big);
+ }
+ break;
+
+ case 3:
+ if (m->what == B_GET_PROPERTY)
+ result =
reply.AddInt32("result", fPixelSize);
+ else if (m->what == B_SET_PROPERTY) {
+ int32 zoom;
+ result = m->FindInt32("data",
&zoom);
+ if (result == B_OK)
+ SetPixelSize(zoom);
+ }
+ break;
+
+ case 4:
+ if (m->what == B_GET_PROPERTY)
+ result =
reply.AddBool("result", fFatBits->Sticked());
+ else if (m->what == B_SET_PROPERTY) {
+ bool stick;
+ result = m->FindBool("data",
&stick);
+ if (result == B_OK)
+
fFatBits->MakeSticked(stick);
+ }
+ break;
+
+ case 5:
+ fFatBits->CopyImage();
+ break;
+
+ default:
+ return BWindow::MessageReceived(m);
+ }
+
+ if (result != B_OK) {
+ reply.what = B_MESSAGE_NOT_UNDERSTOOD;
+ reply.AddString("message", strerror(result));
+ reply.AddInt32("error", result);
+ }
+
+ m->SendReply(&reply);
+ break;
+ }
+
case msg_show_info:
if (active) {
fInfoBarState = !fInfoBarState;
@@ -783,6 +932,11 @@ TWindow::PixelCount(int32* h, int32 *v)
void
TWindow::SetPixelSize(int32 s)
{
+ if (s > 100)
+ s = 100;
+ else if (s < 1)
+ s = 1;
+
if (s == fPixelSize)
return;
@@ -791,33 +945,39 @@ TWindow::SetPixelSize(int32 s)
// tell info that size has changed
// tell mag that size has changed
+ float w = Bounds().Width();
+ float h = Bounds().Height();
CalcViewablePixels();
ResizeWindow(fHPixelCount, fVPixelCount);
+
+ // the window might not actually change in size
+ // in that case force the buffers to the new dimension
+ if (w == Bounds().Width() && h == Bounds().Height())
+ fFatBits->InitBuffers(fHPixelCount, fVPixelCount, fPixelSize,
ShowGrid());
}
void
-TWindow::SetPixelSize(bool d)
+TWindow::SetPixelSize(bool plus)
{
- if (d) { // grow
- fPixelSize++;
- if (fPixelSize > 16)
- fPixelSize = 16;
+ int32 pixelSize;
+
+ if (plus) {
+ if (fPixelSize >= 16)
+ return;
+
+ pixelSize = fPixelSize + 1;
} else {
- fPixelSize--;
- if (fPixelSize < 1)
- fPixelSize = 1;
- }
+ pixelSize = fPixelSize / 2;
- float w = Bounds().Width();
- float h = Bounds().Height();
- CalcViewablePixels();
- ResizeWindow(fHPixelCount, fVPixelCount);
+ if (pixelSize < 16)
+ if (fPixelSize > 16)
+ pixelSize = (fPixelSize + 16) / 2;
+ else
+ pixelSize = fPixelSize - 1;
+ }
- // the window might not actually change in size
- // in that case force the buffers to the new dimension
- if (w == Bounds().Width() && h == Bounds().Height())
- fFatBits->InitBuffers(fHPixelCount, fVPixelCount, fPixelSize,
ShowGrid());
+ SetPixelSize(pixelSize);
}
diff --git a/src/apps/magnify/Magnify.h b/src/apps/magnify/Magnify.h
index 35cfa83..9b9663b 100644
--- a/src/apps/magnify/Magnify.h
+++ b/src/apps/magnify/Magnify.h
@@ -201,6 +201,11 @@ class TWindow : public BWindow {
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
+ status_t GetSupportedSuites(BMessage* msg);
+ BHandler* ResolveSpecifier(BMessage* msg, int32
index,
+ BMessage* specifier,
int32 what,
+ const char* property);
+
void GetPrefs(int32 pixelCount = -1);
void SetPrefs();