Skip to content

Commit

Permalink
add Pause button to memory bookmarks window
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamiras committed Aug 17, 2024
1 parent 3ec349e commit 397ef45
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/RA_Resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
#define IDC_RA_LBL_TYPE 1243
#define IDC_RA_TYPE 1244
#define IDC_RA_RESULTS_IMPORT 1245
#define IDC_RA_PAUSE 1246


#define IDD_RA_MEMORY 1501
Expand Down Expand Up @@ -216,7 +217,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 122
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1246
#define _APS_NEXT_CONTROL_VALUE 1247
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
1 change: 1 addition & 0 deletions src/RA_Shared.rc
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ BEGIN
PUSHBUTTON "Clear All Changes",IDC_RA_CLEAR_CHANGE,270,3,70,14,BS_MULTILINE
CONTROL "",IDC_RA_LBX_ADDRESSES,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_CLIPCHILDREN | WS_BORDER,4,18,336,118
PUSHBUTTON "Remove Selected",IDC_RA_DEL_BOOKMARK,4,137,70,14,BS_MULTILINE
PUSHBUTTON "Pause",IDC_RA_PAUSE,126,137,50,14,BS_MULTILINE
PUSHBUTTON "Freeze",IDC_RA_FREEZE,178,137,50,14,BS_MULTILINE
PUSHBUTTON "Move Up",IDC_RA_MOVE_BOOKMARK_UP,239,137,50,14,BS_MULTILINE
PUSHBUTTON "Move Down",IDC_RA_MOVE_BOOKMARK_DOWN,290,137,50,14
Expand Down
74 changes: 73 additions & 1 deletion src/ui/viewmodels/MemoryBookmarksViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ const IntModelProperty MemoryBookmarksViewModel::MemoryBookmarkViewModel::Behavi
const IntModelProperty MemoryBookmarksViewModel::MemoryBookmarkViewModel::RowColorProperty("MemoryBookmarkViewModel", "RowColor", 0);
const BoolModelProperty MemoryBookmarksViewModel::MemoryBookmarkViewModel::ReadOnlyProperty("MemoryBookmarkViewModel", "IsReadOnly", false);
const BoolModelProperty MemoryBookmarksViewModel::MemoryBookmarkViewModel::IsDirtyProperty("MemoryBookmarkViewModel", "IsDirty", false);
const BoolModelProperty MemoryBookmarksViewModel::HasSelectionProperty("MemoryBookmarkViewModel", "HasSelection", false);
const StringModelProperty MemoryBookmarksViewModel::FreezeButtonTextProperty("MemoryBookmarksViewModel", "FreezeButtonText", L"Freeze");
const StringModelProperty MemoryBookmarksViewModel::PauseButtonTextProperty("MemoryBookmarksViewModel", "PauseButtonText", L"Pause");

constexpr int MaxTextBookmarkLength = 8;

Expand Down Expand Up @@ -703,7 +705,11 @@ void MemoryBookmarksViewModel::OnViewModelBoolValueChanged(gsl::index, const Boo
if (args.Property == LookupItemViewModel::IsSelectedProperty)
{
if (!m_vBookmarks.IsUpdating())
{
UpdateHasSelection();
UpdateFreezeButtonText();
UpdatePauseButtonText();
}
}
}

Expand All @@ -712,13 +718,33 @@ void MemoryBookmarksViewModel::OnViewModelIntValueChanged(gsl::index, const IntM
if (args.Property == MemoryBookmarkViewModel::BehaviorProperty)
{
if (!m_vBookmarks.IsUpdating())
{
UpdateFreezeButtonText();
UpdatePauseButtonText();
}
}
}

void MemoryBookmarksViewModel::OnEndViewModelCollectionUpdate()
{
UpdateHasSelection();
UpdateFreezeButtonText();
UpdatePauseButtonText();
}

void MemoryBookmarksViewModel::UpdateHasSelection()
{
for (gsl::index nIndex = 0; ra::to_unsigned(nIndex) < m_vBookmarks.Count(); ++nIndex)
{
const auto& pBookmark = *m_vBookmarks.GetItemAt(nIndex);
if (pBookmark.IsSelected())
{
SetValue(HasSelectionProperty, true);
return;
}
}

SetValue(HasSelectionProperty, false);
}

bool MemoryBookmarksViewModel::ShouldFreeze() const
Expand All @@ -735,7 +761,7 @@ bool MemoryBookmarksViewModel::ShouldFreeze() const

void MemoryBookmarksViewModel::UpdateFreezeButtonText()
{
if (ShouldFreeze())
if (!HasSelection() || ShouldFreeze())
SetValue(FreezeButtonTextProperty, FreezeButtonTextProperty.GetDefaultValue());
else
SetValue(FreezeButtonTextProperty, L"Unfreeze");
Expand Down Expand Up @@ -767,6 +793,52 @@ void MemoryBookmarksViewModel::ToggleFreezeSelected()
m_vBookmarks.EndUpdate();
}

bool MemoryBookmarksViewModel::ShouldPause() const
{
for (gsl::index nIndex = 0; ra::to_unsigned(nIndex) < m_vBookmarks.Count(); ++nIndex)
{
const auto& pBookmark = *m_vBookmarks.GetItemAt(nIndex);
if (pBookmark.IsSelected() && pBookmark.GetBehavior() != BookmarkBehavior::PauseOnChange)
return true;
}

return false;
}

void MemoryBookmarksViewModel::UpdatePauseButtonText()
{
if (!HasSelection() || ShouldPause())
SetValue(PauseButtonTextProperty, PauseButtonTextProperty.GetDefaultValue());
else
SetValue(PauseButtonTextProperty, L"Stop Pausing");
}

void MemoryBookmarksViewModel::TogglePauseSelected()
{
m_vBookmarks.BeginUpdate();

if (ShouldPause())
{
for (gsl::index nIndex = m_vBookmarks.Count() - 1; nIndex >= 0; --nIndex)
{
auto* pItem = m_vBookmarks.GetItemAt(nIndex);
if (pItem && pItem->IsSelected())
pItem->SetBehavior(BookmarkBehavior::PauseOnChange);
}
}
else
{
for (gsl::index nIndex = m_vBookmarks.Count() - 1; nIndex >= 0; --nIndex)
{
auto* pItem = m_vBookmarks.GetItemAt(nIndex);
if (pItem && pItem->IsSelected() && pItem->GetBehavior() == BookmarkBehavior::PauseOnChange)
pItem->SetBehavior(BookmarkBehavior::None);
}
}

m_vBookmarks.EndUpdate();
}

void MemoryBookmarksViewModel::MoveSelectedBookmarksUp()
{
m_vBookmarks.ShiftItemsUp(MemoryBookmarkViewModel::IsSelectedProperty);
Expand Down
16 changes: 16 additions & 0 deletions src/ui/viewmodels/MemoryBookmarksViewModel.hh
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,9 @@ public:
/// <returns>Number of bookmarks that were removed</returns>
int RemoveSelectedBookmarks();

static const BoolModelProperty HasSelectionProperty;
const bool HasSelection() const { return GetValue(HasSelectionProperty); }

static const StringModelProperty FreezeButtonTextProperty;
const std::wstring& GetFreezeButtonText() const { return GetValue(FreezeButtonTextProperty); }

Expand All @@ -344,6 +347,14 @@ public:
/// </summary>
void ToggleFreezeSelected();

static const StringModelProperty PauseButtonTextProperty;
const std::wstring& GetPauseButtonText() const { return GetValue(PauseButtonTextProperty); }

/// <summary>
/// Marks the selected items to pause on change. Or, if they're already all marked, unmarks them.
/// </summary>
void TogglePauseSelected();

/// <summary>
/// Moves the selected bookmarks higher in the list.
/// </summary>
Expand Down Expand Up @@ -395,6 +406,11 @@ private:
bool ShouldFreeze() const;
void UpdateFreezeButtonText();

bool ShouldPause() const;
void UpdatePauseButtonText();

void UpdateHasSelection();

ViewModelCollection<MemoryBookmarkViewModel> m_vBookmarks;
LookupItemViewModelCollection m_vSizes;
LookupItemViewModelCollection m_vFormats;
Expand Down
15 changes: 15 additions & 0 deletions src/ui/win32/MemoryBookmarksDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,13 @@ MemoryBookmarksDialog::MemoryBookmarksDialog(MemoryBookmarksViewModel& vmMemoryB
m_bindBookmarks(vmMemoryBookmarks)
{
m_bindWindow.SetInitialPosition(RelativePosition::After, RelativePosition::Near, "Memory Bookmarks");
m_bindWindow.BindLabel(IDC_RA_PAUSE, MemoryBookmarksViewModel::PauseButtonTextProperty);
m_bindWindow.BindLabel(IDC_RA_FREEZE, MemoryBookmarksViewModel::FreezeButtonTextProperty);
m_bindWindow.BindEnabled(IDC_RA_DEL_BOOKMARK, MemoryBookmarksViewModel::HasSelectionProperty);
m_bindWindow.BindEnabled(IDC_RA_PAUSE, MemoryBookmarksViewModel::HasSelectionProperty);
m_bindWindow.BindEnabled(IDC_RA_FREEZE, MemoryBookmarksViewModel::HasSelectionProperty);
m_bindWindow.BindEnabled(IDC_RA_MOVE_BOOKMARK_UP, MemoryBookmarksViewModel::HasSelectionProperty);
m_bindWindow.BindEnabled(IDC_RA_MOVE_BOOKMARK_DOWN, MemoryBookmarksViewModel::HasSelectionProperty);

m_bindBookmarks.SetShowGridLines(true);
m_bindBookmarks.BindIsSelected(MemoryBookmarksViewModel::MemoryBookmarkViewModel::IsSelectedProperty);
Expand Down Expand Up @@ -251,6 +257,7 @@ MemoryBookmarksDialog::MemoryBookmarksDialog(MemoryBookmarksViewModel& vmMemoryB
SetAnchor(IDC_RA_CLEAR_CHANGE, Anchor::Top | Anchor::Right);
SetAnchor(IDC_RA_LBX_ADDRESSES, Anchor::Top | Anchor::Left | Anchor::Bottom | Anchor::Right);
SetAnchor(IDC_RA_DEL_BOOKMARK, Anchor::Bottom | Anchor::Left);
SetAnchor(IDC_RA_PAUSE, Anchor::Bottom | Anchor::Right);
SetAnchor(IDC_RA_FREEZE, Anchor::Bottom | Anchor::Right);
SetAnchor(IDC_RA_MOVE_BOOKMARK_UP, Anchor::Bottom | Anchor::Right);
SetAnchor(IDC_RA_MOVE_BOOKMARK_DOWN, Anchor::Bottom | Anchor::Right);
Expand Down Expand Up @@ -314,6 +321,14 @@ BOOL MemoryBookmarksDialog::OnCommand(WORD nCommand)
return TRUE;
}

case IDC_RA_PAUSE: {
auto* vmMemoryBookmarks = dynamic_cast<MemoryBookmarksViewModel*>(&m_vmWindow);
if (vmMemoryBookmarks)
vmMemoryBookmarks->TogglePauseSelected();

return TRUE;
}

case IDC_RA_MOVE_BOOKMARK_UP:
{
auto* vmMemoryBookmarks = dynamic_cast<MemoryBookmarksViewModel*>(&m_vmWindow);
Expand Down
57 changes: 57 additions & 0 deletions tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,63 @@ TEST_CLASS(MemoryBookmarksViewModel_Tests)
Assert::AreEqual(std::wstring(L"Freeze"), bookmarks.GetFreezeButtonText());
}

TEST_METHOD(TestTogglePauseSelected)
{
MemoryBookmarksViewModelHarness bookmarks;
bookmarks.AddBookmark(1234U, MemSize::EightBit);
bookmarks.AddBookmark(2345U, MemSize::EightBit);
bookmarks.AddBookmark(4567U, MemSize::EightBit);
bookmarks.AddBookmark(6789U, MemSize::EightBit);
Assert::AreEqual(std::wstring(L"Pause"), bookmarks.GetPauseButtonText());
Assert::IsFalse(bookmarks.HasSelection());

// no selected items are marked to pause - mark them all
bookmarks.Bookmarks().GetItemAt(1)->SetSelected(true);
bookmarks.Bookmarks().GetItemAt(3)->SetSelected(true);
Assert::IsTrue(bookmarks.HasSelection());

Assert::AreEqual(std::wstring(L"Pause"), bookmarks.GetPauseButtonText());
bookmarks.TogglePauseSelected();
Assert::IsTrue(bookmarks.HasSelection());

Assert::AreEqual({ 4U }, bookmarks.Bookmarks().Count());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::None, bookmarks.Bookmarks().GetItemAt(0)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::PauseOnChange, bookmarks.Bookmarks().GetItemAt(1)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::None, bookmarks.Bookmarks().GetItemAt(2)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::PauseOnChange, bookmarks.Bookmarks().GetItemAt(3)->GetBehavior());
Assert::AreEqual(std::wstring(L"Stop Pausing"), bookmarks.GetPauseButtonText());

// some selected items are marked to pause - mark the rest (items 2 and 3 are selected)
bookmarks.Bookmarks().GetItemAt(1)->SetSelected(false);
bookmarks.Bookmarks().GetItemAt(2)->SetSelected(true);
Assert::IsTrue(bookmarks.HasSelection());

Assert::AreEqual(std::wstring(L"Pause"), bookmarks.GetPauseButtonText());
bookmarks.TogglePauseSelected();

Assert::AreEqual({ 4U }, bookmarks.Bookmarks().Count());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::None, bookmarks.Bookmarks().GetItemAt(0)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::PauseOnChange, bookmarks.Bookmarks().GetItemAt(1)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::PauseOnChange, bookmarks.Bookmarks().GetItemAt(2)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::PauseOnChange, bookmarks.Bookmarks().GetItemAt(3)->GetBehavior());
Assert::AreEqual(std::wstring(L"Stop Pausing"), bookmarks.GetPauseButtonText());

// all selected items are marked to pause - unmark them (items 1 and 3 are selected)
bookmarks.Bookmarks().GetItemAt(1)->SetSelected(true);
bookmarks.Bookmarks().GetItemAt(2)->SetSelected(false);
Assert::IsTrue(bookmarks.HasSelection());

Assert::AreEqual(std::wstring(L"Stop Pausing"), bookmarks.GetPauseButtonText());
bookmarks.TogglePauseSelected();

Assert::AreEqual({ 4U }, bookmarks.Bookmarks().Count());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::None, bookmarks.Bookmarks().GetItemAt(0)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::None, bookmarks.Bookmarks().GetItemAt(1)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::PauseOnChange, bookmarks.Bookmarks().GetItemAt(2)->GetBehavior());
Assert::AreEqual(MemoryBookmarksViewModel::BookmarkBehavior::None, bookmarks.Bookmarks().GetItemAt(3)->GetBehavior());
Assert::AreEqual(std::wstring(L"Pause"), bookmarks.GetPauseButtonText());
}

TEST_METHOD(TestClearAllChanges)
{
MemoryBookmarksViewModelHarness bookmarks;
Expand Down

0 comments on commit 397ef45

Please sign in to comment.