Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added data/RTTR/assets/base/io_new/015_pinicup.bmp
Binary file not shown.
Binary file added data/RTTR/assets/base/io_new/016_pinicsel.bmp
Binary file not shown.
Binary file added data/RTTR/assets/base/io_new/017_pinicdn.bmp
Binary file not shown.
Binary file added data/RTTR/assets/base/io_new/018_unpinicup.bmp
Binary file not shown.
Binary file added data/RTTR/assets/base/io_new/019_unpinicsel.bmp
Binary file not shown.
Binary file added data/RTTR/assets/base/io_new/020_unpinicdn.bmp
Binary file not shown.
12 changes: 12 additions & 0 deletions libs/s25main/Loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "ogl/glArchivItem_Bitmap_RLE.h"
#include "ogl/glArchivItem_Bitmap_Raw.h"
#include "ogl/glArchivItem_Bob.h"
#include "ogl/glArchivItem_Sound_Wave.h"
#include "ogl/glFont.h"
#include "ogl/glSmartBitmap.h"
#include "ogl/glTexturePacker.h"
Expand Down Expand Up @@ -385,6 +386,17 @@ void Loader::LoadDummyMapFiles()
}
}

void Loader::LoadDummySoundFiles()
{
libsiedler2::Archiv& archive = files_["sound"].archive;
archive.alloc(116);
for(unsigned id = 51; id < archive.size(); id++)
{
auto snd = std::make_unique<glArchivItem_Sound_Wave>();
archive.set(id, std::move(snd));
}
}

namespace {
struct NationResourcesSource
{
Expand Down
1 change: 1 addition & 0 deletions libs/s25main/Loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class Loader
/// Creates archives with empty files for the GUI (for testing purposes)
void LoadDummyGUIFiles();
void LoadDummyMapFiles();
void LoadDummySoundFiles();
/// Load a file and save it into the loader repo
bool Load(const boost::filesystem::path& path, const libsiedler2::ArchivItem_Palette* palette = nullptr);
bool Load(const ResourceId& resId, const libsiedler2::ArchivItem_Palette* palette = nullptr);
Expand Down
5 changes: 5 additions & 0 deletions libs/s25main/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ void Settings::LoadDefaults()
// {
interface.autosave_interval = 0;
interface.revert_mouse = false;
interface.enableWindowPinning = false;
// }

// addons
Expand Down Expand Up @@ -296,6 +297,7 @@ void Settings::Load()
// {
interface.autosave_interval = iniInterface->getIntValue("autosave_interval");
interface.revert_mouse = iniInterface->getBoolValue("revert_mouse");
interface.enableWindowPinning = iniInterface->getValue("enable_window_pinning", false);
// }

// addons
Expand Down Expand Up @@ -353,6 +355,7 @@ void Settings::LoadIngame()
settings.restorePos = DrawPoint(iniWindow->getValue("restore_pos_x", lastPos.x),
iniWindow->getValue("restore_pos_y", lastPos.y));
settings.isOpen = iniWindow->getIntValue("is_open");
settings.isPinned = iniWindow->getValue("is_pinned", false);
settings.isMinimized = iniWindow->getValue("is_minimized", false);
}
} catch(std::runtime_error& e)
Expand Down Expand Up @@ -456,6 +459,7 @@ void Settings::Save()
// {
iniInterface->setValue("autosave_interval", interface.autosave_interval);
iniInterface->setValue("revert_mouse", interface.revert_mouse);
iniInterface->setValue("enable_window_pinning", interface.enableWindowPinning);
// }

// addons
Expand Down Expand Up @@ -513,6 +517,7 @@ void Settings::SaveIngame()
iniWindow->setValue("restore_pos_y", settings.restorePos.y);
}
iniWindow->setValue("is_open", settings.isOpen);
iniWindow->setValue("is_pinned", settings.isPinned);
iniWindow->setValue("is_minimized", settings.isMinimized);
}

Expand Down
2 changes: 2 additions & 0 deletions libs/s25main/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct PersistentWindowSettings
DrawPoint lastPos = DrawPoint::Invalid();
DrawPoint restorePos = DrawPoint::Invalid();
bool isOpen = false;
bool isPinned = false;
bool isMinimized = false;
};

Expand Down Expand Up @@ -104,6 +105,7 @@ class Settings : public Singleton<Settings, SingletonPolicies::WithLongevity>
{
unsigned autosave_interval;
bool revert_mouse;
bool enableWindowPinning;
Comment thread
Flamefire marked this conversation as resolved.
} interface;

struct
Expand Down
17 changes: 11 additions & 6 deletions libs/s25main/WindowManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,14 @@ void WindowManager::RelayKeyboardMessage(KeyboardMsgHandler msg, const KeyEvent&
return; // No windows -> nothing to do

// ESC or ALT+W closes the active window
if(ke.kt == KeyType::Escape || (ke.c == 'w' && ke.alt))
const auto escape = (ke.kt == KeyType::Escape);
if(escape || (ke.c == 'w' && ke.alt))
{
// Find one which isn't yet marked for closing so multiple ESC in between draw calls can close multiple windows
const auto itActiveWnd =
std::find_if(windows.rbegin(), windows.rend(), [](const auto& wnd) { return !wnd->ShouldBeClosed(); });
// ESC doesn't close pinned windows
const auto itActiveWnd = std::find_if(windows.rbegin(), windows.rend(), [escape](const auto& wnd) {
return !wnd->ShouldBeClosed() && !(escape && wnd->IsPinned());
});
if(itActiveWnd != windows.rend() && (*itActiveWnd)->getCloseBehavior() != CloseBehavior::Custom)
(*itActiveWnd)->Close();
} else if(!CALL_MEMBER_FN(*windows.back(), msg)(ke)) // send to active window
Expand Down Expand Up @@ -418,10 +421,12 @@ void WindowManager::Msg_RightDown(const MouseCoords& mc)
}
if(foundWindow)
{
// Close it if requested
// Close it if requested (unless pinned)
if(foundWindow->getCloseBehavior() == CloseBehavior::Regular)
foundWindow->Close();
else
{
if(!foundWindow->IsPinned())
foundWindow->Close();
} else
{
SetActiveWindow(*foundWindow);
foundWindow->Msg_RightDown(mc);
Expand Down
74 changes: 60 additions & 14 deletions libs/s25main/ingameWindows/IngameWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@

namespace {
constexpr Extent ButtonSize(16, 16);
}
constexpr unsigned TitleMargin = 32;
} // namespace

const DrawPoint IngameWindow::posLastOrCenter(DrawPoint::MaxElementValue, DrawPoint::MaxElementValue);
const DrawPoint IngameWindow::posCenter(DrawPoint::MaxElementValue - 1, DrawPoint::MaxElementValue);
Expand All @@ -32,7 +33,8 @@ const Extent IngameWindow::borderSize(1, 1);
IngameWindow::IngameWindow(unsigned id, const DrawPoint& pos, const Extent& size, std::string title,
glArchivItem_Bitmap* background, bool modal, CloseBehavior closeBehavior, Window* parent)
: Window(parent, id, pos, size), title_(std::move(title)), background(background), lastMousePos(0, 0),
isModal_(modal), closeme(false), isMinimized_(false), isMoving(false), closeBehavior_(closeBehavior)
isModal_(modal), closeme(false), isPinned_(false), isMinimized_(false), isMoving(false),
closeBehavior_(closeBehavior)
{
std::fill(buttonStates_.begin(), buttonStates_.end(), ButtonState::Up);
contentOffset.x = LOADER.GetImageN("resource", 38)->getWidth(); // left border
Expand All @@ -54,14 +56,14 @@ IngameWindow::IngameWindow(unsigned id, const DrawPoint& pos, const Extent& size
if(windowSettings_)
{
// Restore minimized state
if(windowSettings_ && windowSettings_->isMinimized)
if(windowSettings_->isMinimized)
{
isMinimized_ = true;
Extent minimizedSize(GetSize().x, contentOffset.y + contentOffsetEnd.y);
Window::Resize(minimizedSize);
}
// Load restorePos
restorePos_ = windowSettings_->restorePos;
isPinned_ = windowSettings_->isPinned; // Restore pinned state
restorePos_ = windowSettings_->restorePos; // Load restorePos
}

// Load last position or center the window
Expand Down Expand Up @@ -177,6 +179,15 @@ void IngameWindow::SetMinimized(bool minimized)
windowSettings_->isMinimized = isMinimized_;
}

void IngameWindow::SetPinned(bool pinned)
{
isPinned_ = pinned;

// if possible save the pinned state to settings
if(windowSettings_)
windowSettings_->isPinned = isPinned_;
}

void IngameWindow::MouseLeftDown(const MouseCoords& mc)
{
// Maus muss sich auf der Titelleiste befinden
Expand Down Expand Up @@ -211,17 +222,32 @@ void IngameWindow::MouseLeftUp(const MouseCoords& mc)
buttonStates_[btn] = ButtonState::Up;

if((btn == IwButton::Close && closeBehavior_ == CloseBehavior::Custom) // no close button
|| (btn == IwButton::Minimize && isModal_)) // modal windows cannot be minimized
|| (isModal_ // modal windows cannot be pinned or minimized
&& (btn == IwButton::Title || btn == IwButton::PinOrMinimize)))
continue;

if(IsPointInRect(mc.GetPos(), GetButtonBounds(btn)))
{
switch(btn)
{
case IwButton::Close: Close(); break;
case IwButton::Minimize:
SetMinimized(!IsMinimized());
LOADER.GetSoundN("sound", 113)->Play(255, false);
case IwButton::Title:
if(SETTINGS.interface.enableWindowPinning && mc.dbl_click)
{
SetMinimized(!IsMinimized());
LOADER.GetSoundN("sound", 113)->Play(255, false);
}
break;
case IwButton::PinOrMinimize:
if(SETTINGS.interface.enableWindowPinning)
{
SetPinned(!IsPinned());
LOADER.GetSoundN("sound", 111)->Play(255, false);
} else
{
SetMinimized(!IsMinimized());
LOADER.GetSoundN("sound", 113)->Play(255, false);
}
break;
}
}
Expand Down Expand Up @@ -294,11 +320,26 @@ void IngameWindow::Draw_()
using ButtonStateResIds = helpers::EnumArray<unsigned, ButtonState>;
constexpr ButtonStateResIds closeResIds = {47, 55, 51};
constexpr ButtonStateResIds minimizeResIds = {48, 56, 52};
constexpr ButtonStateResIds pinBaseResIds = {47, 47, 51};
constexpr ButtonStateResIds pinOverlayResIds = {15, 16, 17};
constexpr ButtonStateResIds unpinOverlayResIds = {18, 19, 20};
if(closeBehavior_ != CloseBehavior::Custom)
LOADER.GetImageN("resource", closeResIds[buttonStates_[IwButton::Close]])->DrawFull(GetPos());
LOADER.GetImageN("resource", closeResIds[buttonStates_[IwButton::Close]])
->DrawFull(GetButtonBounds(IwButton::Close));
if(!IsModal())
LOADER.GetImageN("resource", minimizeResIds[buttonStates_[IwButton::Minimize]])
->DrawFull(GetButtonBounds(IwButton::Minimize));
{
const auto buttonState = buttonStates_[IwButton::PinOrMinimize];
const auto bounds = GetButtonBounds(IwButton::PinOrMinimize);
if(SETTINGS.interface.enableWindowPinning)
{
LOADER.GetImageN("resource", pinBaseResIds[buttonState])->DrawFull(bounds);
if(isPinned_)
LOADER.GetImageN("io_new", unpinOverlayResIds[buttonState])->DrawFull(bounds);
else
LOADER.GetImageN("io_new", pinOverlayResIds[buttonState])->DrawFull(bounds);
} else
LOADER.GetImageN("resource", minimizeResIds[buttonState])->DrawFull(bounds);
}

// The title bar
unsigned titleIndex;
Expand Down Expand Up @@ -410,10 +451,15 @@ void IngameWindow::SaveOpenStatus(bool isOpen) const
Rect IngameWindow::GetButtonBounds(IwButton btn) const
{
auto pos = GetPos();
auto size = ButtonSize;
switch(btn)
{
case IwButton::Close: break;
case IwButton::Minimize: pos.x += GetSize().x - ButtonSize.x; break;
case IwButton::Title:
pos.x += TitleMargin;
size.x = GetSize().x - TitleMargin * 2;
break;
case IwButton::PinOrMinimize: pos.x += GetSize().x - ButtonSize.x; break;
}
return Rect(pos, ButtonSize);
return Rect(pos, size);
}
9 changes: 7 additions & 2 deletions libs/s25main/ingameWindows/IngameWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ enum CloseBehavior
enum class IwButton
{
Close,
Minimize
Title, /// Pseudo-button to respond to double-clicks on the title bar
PinOrMinimize
};
constexpr auto maxEnumValue(IwButton)
{
return IwButton::Minimize;
return IwButton::PinOrMinimize;
}

class IngameWindow : public Window
Expand Down Expand Up @@ -86,6 +87,9 @@ class IngameWindow : public Window
/// ist das Fenster minimiert?
bool IsMinimized() const { return isMinimized_; }

void SetPinned(bool pinned = true);
bool IsPinned() const { return isPinned_; }

CloseBehavior getCloseBehavior() const { return closeBehavior_; }

/// Modal windows cannot be minimized, are always active and stay on top of non-modal ones
Expand Down Expand Up @@ -126,6 +130,7 @@ class IngameWindow : public Window

bool isModal_;
bool closeme;
bool isPinned_;
bool isMinimized_;
bool isMoving;
CloseBehavior closeBehavior_;
Expand Down
Loading