Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Feature]: Zoom tree view with ctrl+ mouse wheel and slider #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 14, 2024
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
95 changes: 95 additions & 0 deletions 95 src/NppJsonViewer/JsonViewDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ JsonViewDlg::JsonViewDlg(HINSTANCE hInstance, const NppData& nppData, const bool
, m_nDlgId(nCmdId)
, m_pEditor(std::make_unique<ScintillaEditor>(nppData))
, m_pTreeView(std::make_unique<TreeViewCtrl>())
, m_pTreeViewZoom(std::make_unique<SliderCtrl>())
, m_pSetting(pSetting)
, m_pCurrFileName(std::make_unique<wchar_t[]>(FILENAME_LEN_IN_TITLE))
{
Expand Down Expand Up @@ -895,6 +896,74 @@ void JsonViewDlg::EnableControls(const std::vector<DWORD>& ids, bool enable)
EnableWindow(GetDlgItem(getHSelf(), id), enable ? TRUE : FALSE);
}

auto JsonViewDlg::GetZoomLevel() const -> int
{
return m_pTreeViewZoom->GetPosition();
}

void JsonViewDlg::SetZoomLevel(int pos) const
{
m_pTreeViewZoom->SetPosition(pos);
}

void JsonViewDlg::SetTreeViewZoom(double dwZoomFactor) const
{
HWND hTreeView = GetDlgItem(getHSelf(), IDC_TREE);
static HFONT hCurrentFont = reinterpret_cast<HFONT>(SendMessage(hTreeView, WM_GETFONT, 0, 0));

LOGFONT logFont {};
GetObject(hCurrentFont, sizeof(LOGFONT), &logFont);
logFont.lfHeight = static_cast<LONG>(logFont.lfHeight * dwZoomFactor);

static HFONT hTreeFont = nullptr;
if (hTreeFont)
{
DeleteObject(hTreeFont);
}
hTreeFont = CreateFontIndirect(&logFont);

SendMessage(hTreeView, WM_SETFONT, reinterpret_cast<WPARAM>(hTreeFont), TRUE);
InvalidateRect(hTreeView, nullptr, TRUE);
}

void JsonViewDlg::UpdateUIOnZoom(int zoomPercentage) const
{
// Update zoom level on slider
SetZoomLevel(zoomPercentage);

// Update the Tree view
double zoomFactor = zoomPercentage / 100.0;
SetTreeViewZoom(zoomFactor);
}

void JsonViewDlg::HandleZoomOnScroll(WPARAM wParam) const
{
int pos = GetZoomLevel(); // Current zoom level
int delta = GET_WHEEL_DELTA_WPARAM(wParam);

const auto& zoomRange = m_pTreeViewZoom->GetRange();
const bool isZoomIn = delta > 0;
bool bRefreshUI = true;

if (isZoomIn && pos < zoomRange.m_nMaxZoom)
{
pos += 10; // Zoom in
}
else if (!isZoomIn && pos > zoomRange.m_nMinZoom)
{
pos -= 10; // Zoom out
}
else
{
bRefreshUI = false;
}

if (bRefreshUI)
{
UpdateUIOnZoom(pos);
}
}

void JsonViewDlg::HandleTreeEvents(LPARAM lParam) const
{
LPNMHDR lpnmh = reinterpret_cast<LPNMHDR>(lParam);
Expand Down Expand Up @@ -1030,6 +1099,7 @@ INT_PTR JsonViewDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
::SetWindowLongPtr(getHSelf(), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));

m_pTreeView->OnInit(getHSelf(), IDC_TREE);
m_pTreeViewZoom->OnInit(getHSelf(), IDC_ZOOM_SLIDER, IDC_ZOOM_PERCENT);

PrepareButtons();

Expand Down Expand Up @@ -1107,6 +1177,31 @@ INT_PTR JsonViewDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
}

case WM_MOUSEWHEEL:
{
if (GetKeyState(VK_CONTROL) & 0x8000)
{
HandleZoomOnScroll(wParam);
return TRUE;
}
return FALSE;
}

case WM_HSCROLL:
{
HWND hSlider = GetDlgItem(getHSelf(), IDC_ZOOM_SLIDER);

if (reinterpret_cast<HWND>(lParam) == hSlider)
{
int pos = m_pTreeViewZoom->GetPosition();
UpdateUIOnZoom(pos);

return TRUE;
}
return FALSE;
}


default:
return DockingDlgInterface::run_dlgProc(message, wParam, lParam);
}
Expand Down
8 changes: 8 additions & 0 deletions 8 src/NppJsonViewer/JsonViewDlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "PluginInterface.h"
#include "resource.h"
#include "TreeViewCtrl.h"
#include "SliderCtrl.h"
#include "ScintillaEditor.h"
#include "JsonHandler.h"
#include "JsonNode.h"
Expand Down Expand Up @@ -89,6 +90,12 @@ class JsonViewDlg
void ShowControls(const std::vector<DWORD>& ids, bool show);
void EnableControls(const std::vector<DWORD>& ids, bool enable);

auto GetZoomLevel() const -> int;
void SetZoomLevel(int pos) const;
void SetTreeViewZoom(double dwZoomFactor) const;
void UpdateUIOnZoom(int zoomPercentage) const;
void HandleZoomOnScroll(WPARAM wParam) const;

void HandleTreeEvents(LPARAM lParam) const;

auto GetFormatSetting() const -> std::tuple<LE, LF, char, unsigned>;
Expand Down Expand Up @@ -118,5 +125,6 @@ class JsonViewDlg
std::unique_ptr<wchar_t[]> m_pCurrFileName;
std::unique_ptr<ScintillaEditor> m_pEditor = nullptr;
std::unique_ptr<TreeViewCtrl> m_pTreeView = nullptr;
std::unique_ptr<SliderCtrl> m_pTreeViewZoom = nullptr;
std::shared_ptr<Setting> m_pSetting = nullptr;
};
2 changes: 2 additions & 0 deletions 2 src/NppJsonViewer/NPPJSONViewer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
<ClCompile Include="ScintillaEditor.cpp" />
<ClCompile Include="SettingsDlg.cpp" />
<ClCompile Include="ShortcutCommand.cpp" />
<ClCompile Include="SliderCtrl.cpp" />
<ClCompile Include="TreeViewCtrl.cpp" />
</ItemGroup>
<ItemGroup>
Expand All @@ -221,6 +222,7 @@
<ClInclude Include="ScintillaEditor.h" />
<ClInclude Include="SettingsDlg.h" />
<ClInclude Include="ShortcutCommand.h" />
<ClInclude Include="SliderCtrl.h" />
<ClInclude Include="StopWatch.h" />
<ClCompile Include="TreeHandler.h" />
<ClInclude Include="TrackingStream.h" />
Expand Down
6 changes: 6 additions & 0 deletions 6 src/NppJsonViewer/NPPJSONViewer.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
<ClCompile Include="TreeHandler.h">
<Filter>Header Files</Filter>
</ClCompile>
<ClCompile Include="SliderCtrl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
Expand Down Expand Up @@ -134,6 +137,9 @@
<ClInclude Include="TrackingStream.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SliderCtrl.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
Expand Down
76 changes: 76 additions & 0 deletions 76 src/NppJsonViewer/SliderCtrl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "SliderCtrl.h"

#include <string>

SliderCtrl::SliderCtrl(const SliderRange& sliderRange)
: m_sliderRange(sliderRange)
{
}

SliderCtrl::~SliderCtrl()
{
// Restore the original window procedure on cleanup
SetWindowLongPtr(m_hSelf, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_oldSliderProc));
}

void SliderCtrl::OnInit(HWND hParent, int sliderID, int sliderInfoID)
{
m_hParent = hParent;
m_hSelf = GetDlgItem(m_hParent, sliderID);
m_hSelfInfo = GetDlgItem(m_hParent, sliderInfoID);

// Set slider range and initial position
SendMessage(m_hSelf, TBM_SETRANGE, TRUE, MAKELPARAM(m_sliderRange.m_nMinZoom, m_sliderRange.m_nMaxZoom));
SendMessage(m_hSelf, TBM_SETPOS, TRUE, m_sliderRange.m_nDefault);
SendMessage(m_hSelf, TBM_SETPAGESIZE, 0, m_sliderRange.m_nSteps);

UpdateInfo(m_sliderRange.m_nDefault);

// Subclass the slider control to handle double-click events
m_oldSliderProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(m_hSelfInfo, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(runWinProc)));

// Save this instance for access in the static window procedure
SetWindowLongPtr(m_hSelfInfo, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
}

auto SliderCtrl::GetPosition() const -> int
{
int pos = static_cast<int>(SendMessage(m_hSelf, TBM_GETPOS, 0, 0));
return pos;
}

void SliderCtrl::SetPosition(int pos) const
{
// Set slider position
SendMessage(m_hSelf, TBM_SETPOS, TRUE, pos);

// Set slider position in text value
UpdateInfo(pos);
}

void SliderCtrl::UpdateInfo(int zoomPercentage) const
{
std::wstring sliderInfoText = std::to_wstring(zoomPercentage) + L"%";
SetWindowText(m_hSelfInfo, sliderInfoText.c_str());
}

LRESULT SliderCtrl::runWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
SliderCtrl* pThis = reinterpret_cast<SliderCtrl*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));

if (pThis)
{
if (message == WM_LBUTTONDBLCLK)
{
// Reset slider to 100% on double-click
// Also notify its parent to adjust tree view as well
pThis->SetPosition(100);
SendMessage(pThis->m_hParent, WM_HSCROLL, NULL, reinterpret_cast<LPARAM>(pThis->m_hSelf));
}

// Call the original window procedure for other messages
return CallWindowProc(pThis->m_oldSliderProc, hWnd, message, wParam, lParam);
}

return FALSE;
}
53 changes: 53 additions & 0 deletions 53 src/NppJsonViewer/SliderCtrl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#pragma once


#include <Windows.h>
#include <CommCtrl.h>

struct SliderRange
{
int m_nDefault = 100;
int m_nMinZoom = 80;
int m_nMaxZoom = 250;
int m_nSteps = 10;
}; // namespace SliderRange

class SliderCtrl
{
HWND m_hParent = nullptr;
HWND m_hSelf = nullptr;
HWND m_hSelfInfo = nullptr;
HWND m_hTreeView = nullptr;
WNDPROC m_oldSliderProc = nullptr;
const SliderRange m_sliderRange {};

public:
explicit SliderCtrl(const SliderRange& sliderRange = {});

~SliderCtrl();

void OnInit(HWND hParent, int sliderID, int sliderInfoID);

HWND GetSliderHandle() const
{
return m_hSelf;
}

HWND GetSliderInfoHandle() const
{
return m_hSelfInfo;
}

auto GetRange() const -> const SliderRange&
{
return m_sliderRange;
}

auto GetPosition() const -> int;
void SetPosition(int pos) const;
void UpdateInfo(int zoomPercentage) const;

private:
// Static window procedure for the slider
static LRESULT CALLBACK runWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
};
4 changes: 3 additions & 1 deletion 4 src/NppJsonViewer/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#define IDC_CHK_IGNORE_COMMENT 1031
#define IDC_CHK_JSON_HIGHLIGHT 1032
#define IDC_CHK_REPLACE_UNDEFINED 1033
#define IDC_ZOOM_SLIDER 1034
#define IDC_ZOOM_PERCENT 1035
#define IDM_COPY_TREEITEM 40001
#define IDM_COPY_NODENAME 40002
#define IDM_COPY_NODEVALUE 40003
Expand All @@ -55,7 +57,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40007
#define _APS_NEXT_CONTROL_VALUE 1034
#define _APS_NEXT_CONTROL_VALUE 1036
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
4 changes: 3 additions & 1 deletion 4 src/NppJsonViewer/resource.rc
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ BEGIN
CONTROL "",IDC_DIVIDER,"Static",SS_ETCHEDVERT,56,1,2,16
EDITTEXT IDC_EDT_SEARCH,60,2,99,12,ES_AUTOHSCROLL
PUSHBUTTON "",IDC_BTN_SEARCH,160,2,16,12,BS_ICON
CONTROL "",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_FULLROWSELECT | WS_HSCROLL | WS_TABSTOP,2,18,173,274,WS_EX_CLIENTEDGE
CONTROL "",IDC_ZOOM_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,2,16,58,12
RTEXT "100%",IDC_ZOOM_PERCENT,60,16,22,12,SS_NOTIFY | NOT WS_GROUP,WS_EX_RIGHT
CONTROL "",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_FULLROWSELECT | WS_HSCROLL | WS_TABSTOP,2,30,173,264,WS_EX_CLIENTEDGE
EDITTEXT IDC_EDT_NODEPATH,2,296,173,12,ES_AUTOHSCROLL | ES_READONLY
END

Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.