Files
haiku-beta6/src/apps/deskbar/PreferencesWindow.cpp
T
John Scipione 446139c354 Deskbar: Fix open prefs window incorrectly sets Deskbar window state.
Set window location but do not Invoke() when opening prefs window.
We do not want the Deskbar window location to change on open/show
prefs window, only when you change the preference.

The root problem here is that we currently do not support horizontal
mini-mode in Deskbar preferences, only vertical. Consequently, opening
the prefs window switches Deskbar into vertical mini-mode when in
horizontal mini-mode. Leave the state alone so this doesn't happen.

Change-Id: Ife00e02f4bc16344fed47d23b9d768aa46b8d7f7
Reviewed-on: https://review.haiku-os.org/c/haiku/+/11524
Haiku-Format: Haiku-format Bot <[email protected]>
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
(cherry picked from commit 6674947bb98ba64da5af9d5de6f894850a194b98)
Reviewed-on: https://review.haiku-os.org/c/haiku/+/11533
2026-08-15 03:10:30 +00:00

617 lines
18 KiB
C++

/*
* Copyright 2009-2011 Haiku, Inc.
* All Rights Reserved. Distributed under the terms of the MIT License.
*
* Authors:
* John Scipione, [email protected]
* Jonas Sundström, [email protected]
*/
#include "PreferencesWindow.h"
#include <Box.h>
#include <Button.h>
#include <Catalog.h>
#include <CheckBox.h>
#include <ControlLook.h>
#include <File.h>
#include <FormattingConventions.h>
#include <GroupLayout.h>
#include <LayoutBuilder.h>
#include <ListView.h>
#include <Locale.h>
#include <OpenWithTracker.h>
#include <Path.h>
#include <RadioButton.h>
#include <Roster.h>
#include <Screen.h>
#include <SeparatorView.h>
#include <Slider.h>
#include <SpaceLayoutItem.h>
#include <Spinner.h>
#include <View.h>
#include <DeskbarPrivate.h>
#include "BarApp.h"
#include "DeskbarUtils.h"
#include "ScreenCornerSelector.h"
#include "StatusView.h"
static const char* kSettingsFileName = "prefs_window_settings";
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "PreferencesWindow"
PreferencesWindow::PreferencesWindow(BRect frame)
:
BWindow(frame, "", B_TITLED_WINDOW,
B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE)
{
BString title(B_TRANSLATE("%appname% preferences"));
title.ReplaceFirst("%appname%", B_TRANSLATE_SYSTEM_NAME("Deskbar"));
SetTitle(title);
// Initial settings (used by revert button)
fSettings = *static_cast<TBarApp*>(be_app)->Settings();
// Menu controls
fMenuRecentDocuments = new BCheckBox(B_TRANSLATE("Recent documents:"),
new BMessage(kUpdateRecentCounts));
fMenuRecentApplications = new BCheckBox(B_TRANSLATE("Recent applications:"),
new BMessage(kUpdateRecentCounts));
fMenuRecentFolders = new BCheckBox(B_TRANSLATE("Recent folders:"),
new BMessage(kUpdateRecentCounts));
fMenuRecentDocumentCount = new BSpinner("recent documents", NULL,
new BMessage(kUpdateRecentCounts));
fMenuRecentApplicationCount = new BSpinner("recent applications", NULL,
new BMessage(kUpdateRecentCounts));
fMenuRecentFolderCount = new BSpinner("recent folders", NULL,
new BMessage(kUpdateRecentCounts));
// Applications controls
fAppsSort = new BCheckBox(B_TRANSLATE("Sort applications by name"),
new BMessage(kSortRunningApps));
fAppsSortTrackerFirst = new BCheckBox(B_TRANSLATE("Tracker always first"),
new BMessage(kTrackerFirst));
fAppsShowExpanders = new BCheckBox(B_TRANSLATE("Show application expander"),
new BMessage(kSuperExpando));
fAppsExpandNew = new BCheckBox(B_TRANSLATE("Expand new applications"),
new BMessage(kExpandNewTeams));
fAppsHideLabels = new BCheckBox(B_TRANSLATE("Hide application names"),
new BMessage(kHideLabels));
fAppsIconSizeSlider = new BSlider("icon_size", B_TRANSLATE("Icon size"),
new BMessage(kResizeTeamIcons), kMinimumIconSize / kIconSizeInterval,
kMaximumIconSize / kIconSizeInterval, B_HORIZONTAL);
fAppsIconSizeSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fAppsIconSizeSlider->SetHashMarkCount((kMaximumIconSize - kMinimumIconSize)
/ kIconSizeInterval + 1);
fAppsIconSizeSlider->SetLimitLabels(B_TRANSLATE("Small"), B_TRANSLATE("Large"));
fAppsIconSizeSlider->SetModificationMessage(new BMessage(kResizeTeamIcons));
// Window controls
fWindowLocation = new ScreenCornerSelector(BRect(0, 0, 120, 80), B_TRANSLATE("Location"),
new BMessage(kMsgSetLocation), B_FOLLOW_NONE);
_SetWindowLocation(fSettings.vertical, fSettings.left, fSettings.top, fSettings.state);
fWindowAlwaysOnTop = new BCheckBox(B_TRANSLATE("Always on top"),
new BMessage(kAlwaysTop));
fWindowAutoRaise = new BCheckBox(B_TRANSLATE("Auto-raise"),
new BMessage(kAutoRaise));
fWindowAutoHide = new BCheckBox(B_TRANSLATE("Auto-hide"),
new BMessage(kAutoHide));
// Menu settings
fMenuRecentDocuments->SetValue(fSettings.recentDocsEnabled);
fMenuRecentDocumentCount->SetEnabled(fSettings.recentDocsEnabled);
fMenuRecentDocumentCount->SetRange(0, 50);
fMenuRecentDocumentCount->SetValue(fSettings.recentDocsCount);
fMenuRecentApplications->SetValue(fSettings.recentAppsEnabled);
fMenuRecentApplicationCount->SetEnabled(fSettings.recentAppsEnabled);
fMenuRecentApplicationCount->SetRange(0, 50);
fMenuRecentApplicationCount->SetValue(fSettings.recentAppsCount);
fMenuRecentFolders->SetValue(fSettings.recentFoldersEnabled);
fMenuRecentFolderCount->SetEnabled(fSettings.recentFoldersEnabled);
fMenuRecentFolderCount->SetRange(0, 50);
fMenuRecentFolderCount->SetValue(fSettings.recentFoldersCount);
// Applications settings
fAppsSort->SetValue(fSettings.sortRunningApps);
fAppsSortTrackerFirst->SetValue(fSettings.trackerAlwaysFirst);
fAppsShowExpanders->SetValue(fSettings.superExpando);
fAppsExpandNew->SetValue(fSettings.expandNewTeams);
fAppsHideLabels->SetValue(fSettings.hideLabels);
fAppsIconSizeSlider->SetValue(fSettings.iconSize / kIconSizeInterval);
// Window settings
fWindowAlwaysOnTop->SetValue(fSettings.alwaysOnTop);
fWindowAutoRaise->SetValue(fSettings.autoRaise);
fWindowAutoHide->SetValue(fSettings.autoHide);
_EnableDisableDependentItems();
// Targets
fAppsSort->SetTarget(be_app);
fAppsSortTrackerFirst->SetTarget(be_app);
fAppsShowExpanders->SetTarget(be_app);
fAppsExpandNew->SetTarget(be_app);
fAppsHideLabels->SetTarget(be_app);
fAppsIconSizeSlider->SetTarget(be_app);
fWindowLocation->SetTarget(be_app);
fWindowAlwaysOnTop->SetTarget(be_app);
fWindowAutoRaise->SetTarget(be_app);
fWindowAutoHide->SetTarget(be_app);
const float spacing = be_control_look->DefaultItemSpacing() * 2.3;
// Applications
BBox* appsSettingsBox = new BBox("applications");
appsSettingsBox->SetLabel(B_TRANSLATE("Applications"));
appsSettingsBox->AddChild(BLayoutBuilder::Group<>()
.AddGroup(B_VERTICAL, 0)
.Add(fAppsSort)
.Add(fAppsSortTrackerFirst)
.Add(fAppsShowExpanders)
.AddGroup(B_HORIZONTAL, 0)
.Add(BSpaceLayoutItem::CreateHorizontalStrut(spacing))
.Add(fAppsExpandNew)
.End()
.Add(fAppsHideLabels)
.AddGlue()
.Add(BSpaceLayoutItem::CreateVerticalStrut(B_USE_SMALL_SPACING))
.Add(fAppsIconSizeSlider)
.SetInsets(B_USE_DEFAULT_SPACING)
.End()
.View());
// Menu
BBox* menuBox = new BBox("menu");
menuBox->SetLabel(B_TRANSLATE("Menu"));
menuBox->AddChild(BLayoutBuilder::Group<>()
.AddGroup(B_VERTICAL, 0)
.AddGroup(B_HORIZONTAL, 0)
.AddGroup(B_VERTICAL, 0)
.Add(fMenuRecentDocuments)
.Add(fMenuRecentFolders)
.Add(fMenuRecentApplications)
.End()
.AddGlue()
.AddGroup(B_VERTICAL, 0)
.Add(fMenuRecentDocumentCount)
.Add(fMenuRecentFolderCount)
.Add(fMenuRecentApplicationCount)
.End()
.End()
.Add(BSpaceLayoutItem::CreateVerticalStrut(
B_USE_SMALL_SPACING))
.Add(new BButton(B_TRANSLATE("Edit in Tracker"
B_UTF8_ELLIPSIS), new BMessage(kEditInTracker)))
.AddGlue()
.SetInsets(B_USE_DEFAULT_SPACING)
.End()
.View());
// Window
BBox* windowSettingsBox = new BBox("window");
windowSettingsBox->SetLabel(B_TRANSLATE("Window"));
windowSettingsBox->AddChild(BLayoutBuilder::Group<>()
.SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET))
.AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING)
.Add(fWindowLocation)
.AddGroup(B_VERTICAL, 0)
.AddGlue()
.Add(fWindowAlwaysOnTop)
.Add(fWindowAutoRaise)
.Add(fWindowAutoHide)
.AddGlue()
.End()
.SetInsets(B_USE_DEFAULT_SPACING)
.End()
.View());
// Action Buttons
fDefaultsButton = new BButton(B_TRANSLATE("Defaults"),
new BMessage(kDefaults));
fRevertButton = new BButton(B_TRANSLATE("Revert"),
new BMessage(kRevert));
// Layout
BLayoutBuilder::Group<>(this)
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
.Add(appsSettingsBox)
.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
.Add(menuBox)
.Add(windowSettingsBox)
.End()
.End()
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
.Add(fDefaultsButton)
.Add(fRevertButton)
.AddGlue()
.End()
.SetInsets(B_USE_WINDOW_SPACING)
.End();
BMessage windowSettings;
BPoint where;
if (_LoadSettings(&windowSettings) == B_OK
&& windowSettings.FindPoint("window_position", &where) == B_OK
&& BScreen(this).Frame().Contains(where)) {
MoveTo(where);
} else
CenterOnScreen();
}
PreferencesWindow::~PreferencesWindow()
{
_UpdateRecentCounts();
}
void
PreferencesWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case kEditInTracker:
OpenWithTracker(B_USER_DESKBAR_DIRECTORY);
break;
case kUpdatePreferences:
_EnableDisableDependentItems();
_UpdateButtons();
break;
case kUpdateRecentCounts:
_UpdateRecentCounts();
_UpdateButtons();
break;
case kStateChanged:
{
bool vertical, left, top;
int32 state;
if (message->FindBool("vertical", &vertical) == B_OK
&& message->FindBool("left", &left) == B_OK
&& message->FindBool("top", &top) == B_OK
&& message->FindInt32("state", &state) == B_OK) {
_SetWindowLocation(vertical, left, top, state);
}
_EnableDisableDependentItems();
break;
}
case kRevert:
_UpdatePreferences(&fSettings);
break;
case kDefaults:
_UpdatePreferences(
static_cast<TBarApp*>(be_app)->DefaultSettings());
break;
default:
BWindow::MessageReceived(message);
break;
}
}
bool
PreferencesWindow::QuitRequested()
{
BMessage windowSettings;
windowSettings.AddPoint("window_position", Frame().LeftTop());
_SaveSettings(&windowSettings);
be_app->PostMessage(kConfigQuit);
return false;
}
void
PreferencesWindow::Show()
{
if (IsHidden())
SetWorkspaces(B_CURRENT_WORKSPACE);
// refresh window location from settings
desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings();
if (settings != NULL)
_SetWindowLocation(settings->vertical, settings->left, settings->top, settings->state);
_UpdateButtons();
BWindow::Show();
}
// #pragma mark - private methods
void
PreferencesWindow::_EnableDisableDependentItems()
{
TBarApp* barApp = static_cast<TBarApp*>(be_app);
desk_settings* settings = barApp->Settings();
if (settings != NULL) {
if (settings->vertical && settings->state == kExpandoState) {
fAppsShowExpanders->SetEnabled(true);
fAppsExpandNew->SetEnabled(fAppsShowExpanders->Value());
} else {
fAppsShowExpanders->SetEnabled(false);
fAppsExpandNew->SetEnabled(false);
}
}
fMenuRecentDocumentCount->SetEnabled(fMenuRecentDocuments->Value() != B_CONTROL_OFF);
fMenuRecentFolderCount->SetEnabled(fMenuRecentFolders->Value() != B_CONTROL_OFF);
fMenuRecentApplicationCount->SetEnabled(fMenuRecentApplications->Value() != B_CONTROL_OFF);
fWindowAutoRaise->SetEnabled(fWindowAlwaysOnTop->Value() == B_CONTROL_OFF);
}
bool
PreferencesWindow::_IsDefaultable()
{
desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings();
desk_settings* defaults = static_cast<TBarApp*>(be_app)->DefaultSettings();
return defaults->sortRunningApps != settings->sortRunningApps
|| defaults->trackerAlwaysFirst != settings->trackerAlwaysFirst
|| defaults->superExpando != settings->superExpando
|| defaults->expandNewTeams != settings->expandNewTeams
|| defaults->hideLabels != settings->hideLabels
|| defaults->iconSize != settings->iconSize
|| defaults->recentAppsEnabled != settings->recentAppsEnabled
|| defaults->recentDocsEnabled != settings->recentDocsEnabled
|| defaults->recentFoldersEnabled
!= settings->recentFoldersEnabled
|| defaults->recentAppsCount != settings->recentAppsCount
|| defaults->recentDocsCount != settings->recentDocsCount
|| defaults->recentFoldersCount != settings->recentFoldersCount
|| defaults->alwaysOnTop != settings->alwaysOnTop
|| defaults->autoRaise != settings->autoRaise
|| defaults->autoHide != settings->autoHide;
}
bool
PreferencesWindow::_IsRevertable()
{
desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings();
return fSettings.sortRunningApps != settings->sortRunningApps
|| fSettings.trackerAlwaysFirst != settings->trackerAlwaysFirst
|| fSettings.superExpando != settings->superExpando
|| fSettings.expandNewTeams != settings->expandNewTeams
|| fSettings.hideLabels != settings->hideLabels
|| fSettings.iconSize != settings->iconSize
|| fSettings.recentAppsEnabled != settings->recentAppsEnabled
|| fSettings.recentDocsEnabled != settings->recentDocsEnabled
|| fSettings.recentFoldersEnabled
!= settings->recentFoldersEnabled
|| fSettings.recentAppsCount != settings->recentAppsCount
|| fSettings.recentDocsCount != settings->recentDocsCount
|| fSettings.recentFoldersCount != settings->recentFoldersCount
|| fSettings.alwaysOnTop != settings->alwaysOnTop
|| fSettings.autoRaise != settings->autoRaise
|| fSettings.autoHide != settings->autoHide;
}
status_t
PreferencesWindow::_InitSettingsFile(BFile* file, bool write)
{
BPath prefsPath;
status_t status = GetDeskbarSettingsDirectory(prefsPath);
if (status != B_OK)
return status;
status = prefsPath.Append(kSettingsFileName);
if (status != B_OK)
return status;
if (write) {
status = file->SetTo(prefsPath.Path(),
B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
} else
status = file->SetTo(prefsPath.Path(), B_READ_ONLY);
return status;
}
status_t
PreferencesWindow::_LoadSettings(BMessage* settings)
{
BFile prefsFile;
status_t status = _InitSettingsFile(&prefsFile, false);
if (status != B_OK)
return status;
return settings->Unflatten(&prefsFile);
}
status_t
PreferencesWindow::_SaveSettings(BMessage* settings)
{
BFile prefsFile;
status_t status = _InitSettingsFile(&prefsFile, true);
if (status != B_OK)
return status;
return settings->Flatten(&prefsFile);
}
void
PreferencesWindow::_SetWindowLocation(bool vertical, bool left, bool top, int32 state)
{
if (vertical) {
if (state == kExpandoState) {
if (top) {
if (left)
fWindowLocation->SetValue(B_DESKBAR_LEFT_TOP | kExpandBit);
else
fWindowLocation->SetValue(B_DESKBAR_RIGHT_TOP | kExpandBit);
#if 0
} else {
if (left)
fWindowLocation->SetValue(B_DESKBAR_LEFT_BOTTOM | kExpandBit);
else
fWindowLocation->SetValue(B_DESKBAR_RIGHT_BOTTOM | kExpandBit);
#endif
}
} else {
if (top) {
if (left)
fWindowLocation->SetValue(B_DESKBAR_LEFT_TOP);
else
fWindowLocation->SetValue(B_DESKBAR_RIGHT_TOP);
} else {
if (left)
fWindowLocation->SetValue(B_DESKBAR_LEFT_BOTTOM);
else
fWindowLocation->SetValue(B_DESKBAR_RIGHT_BOTTOM);
}
}
} else {
if (state == kExpandoState) {
// these are always expanded but don't set the bit
if (top)
fWindowLocation->SetValue(B_DESKBAR_TOP);
else
fWindowLocation->SetValue(B_DESKBAR_BOTTOM);
} else {
// horizontal mini-mode
if (top) {
if (left)
fWindowLocation->SetValue(B_DESKBAR_LEFT_TOP);
else
fWindowLocation->SetValue(B_DESKBAR_RIGHT_TOP);
} else {
if (left)
fWindowLocation->SetValue(B_DESKBAR_LEFT_BOTTOM);
else
fWindowLocation->SetValue(B_DESKBAR_RIGHT_BOTTOM);
}
}
}
}
void
PreferencesWindow::_UpdateButtons()
{
fDefaultsButton->SetEnabled(_IsDefaultable());
fRevertButton->SetEnabled(_IsRevertable());
}
void
PreferencesWindow::_UpdatePreferences(desk_settings* settings)
{
desk_settings* current = static_cast<TBarApp*>(be_app)->Settings();
bool updateRecentCounts = false;
if (current->sortRunningApps != settings->sortRunningApps) {
fAppsSort->SetValue(settings->sortRunningApps);
fAppsSort->Invoke();
}
if (current->trackerAlwaysFirst != settings->trackerAlwaysFirst) {
fAppsSortTrackerFirst->SetValue(settings->trackerAlwaysFirst);
fAppsSortTrackerFirst->Invoke();
}
if (current->superExpando != settings->superExpando) {
fAppsShowExpanders->SetValue(settings->superExpando);
fAppsShowExpanders->Invoke();
}
if (current->expandNewTeams != settings->expandNewTeams) {
fAppsExpandNew->SetValue(settings->expandNewTeams);
fAppsExpandNew->Invoke();
}
if (current->hideLabels != settings->hideLabels) {
fAppsHideLabels->SetValue(settings->hideLabels);
fAppsHideLabels->Invoke();
}
if (current->iconSize != settings->iconSize) {
fAppsIconSizeSlider->SetValue(settings->iconSize / kIconSizeInterval);
fAppsIconSizeSlider->Invoke();
}
if (current->recentDocsEnabled != settings->recentDocsEnabled) {
fMenuRecentDocuments->SetValue(settings->recentDocsEnabled
? B_CONTROL_ON : B_CONTROL_OFF);
updateRecentCounts = true;
}
if (current->recentFoldersEnabled != settings->recentFoldersEnabled) {
fMenuRecentFolders->SetValue(settings->recentFoldersEnabled
? B_CONTROL_ON : B_CONTROL_OFF);
updateRecentCounts = true;
}
if (current->recentAppsEnabled != settings->recentAppsEnabled) {
fMenuRecentApplications->SetValue(settings->recentAppsEnabled
? B_CONTROL_ON : B_CONTROL_OFF);
updateRecentCounts = true;
}
if (current->recentDocsCount != settings->recentDocsCount) {
fMenuRecentDocumentCount->SetValue(settings->recentDocsCount);
updateRecentCounts = true;
}
if (current->recentFoldersCount != settings->recentFoldersCount) {
fMenuRecentFolderCount->SetValue(settings->recentFoldersCount);
updateRecentCounts = true;
}
if (current->recentAppsCount != settings->recentAppsCount) {
fMenuRecentApplicationCount->SetValue(settings->recentAppsCount);
updateRecentCounts = true;
}
if (current->alwaysOnTop != settings->alwaysOnTop) {
fWindowAlwaysOnTop->SetValue(settings->alwaysOnTop);
fWindowAlwaysOnTop->Invoke();
}
if (current->autoRaise != settings->autoRaise) {
fWindowAutoRaise->SetValue(settings->autoRaise);
fWindowAutoRaise->Invoke();
}
if (current->autoHide != settings->autoHide) {
fWindowAutoHide->SetValue(settings->autoHide);
fWindowAutoHide->Invoke();
}
if (updateRecentCounts)
_UpdateRecentCounts();
}
void
PreferencesWindow::_UpdateRecentCounts()
{
BMessage message(kUpdateRecentCounts);
message.AddInt32("documents", fMenuRecentDocumentCount->Value());
message.AddInt32("applications", fMenuRecentApplicationCount->Value());
message.AddInt32("folders", fMenuRecentFolderCount->Value());
message.AddBool("documentsEnabled", fMenuRecentDocuments->Value());
message.AddBool("applicationsEnabled", fMenuRecentApplications->Value());
message.AddBool("foldersEnabled", fMenuRecentFolders->Value());
be_app->PostMessage(&message);
_EnableDisableDependentItems();
}