Skip to content

Commit

Permalink
Add Location Pane (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
sdottaka authored Jan 14, 2024
1 parent b8cc49a commit a22a6b3
Show file tree
Hide file tree
Showing 13 changed files with 875 additions and 249 deletions.
39 changes: 37 additions & 2 deletions src/WinWebDiff/WinWebDiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,28 @@ struct CmdLineInfo
int nUrls;
};

static HRESULT OnWebDiffEvent(const WebDiffEvent& e);

struct CallbackImpl: public IWebDiffEventHandler
{
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override { return E_NOTIMPL; }
ULONG STDMETHODCALLTYPE AddRef(void) override { return ++m_nRef; }
ULONG STDMETHODCALLTYPE Release(void) override { if (--m_nRef == 0) { delete this; return 0; } return m_nRef; }
HRESULT STDMETHODCALLTYPE Invoke(const WebDiffEvent& event) { return OnWebDiffEvent(event); }
int m_nRef = 0;
};

HINSTANCE m_hInstance;
HINSTANCE hInstDLL;
HWND m_hWnd;
HWND m_hwndWebToolWindow;
WCHAR m_szTitle[256] = L"WinWebDiff";
WCHAR m_szWindowClass[256] = L"WINWEBDIFF";
IWebDiffWindow* m_pWebDiffWindow = nullptr;
IWebToolWindow *m_pWebToolWindow = nullptr;
std::list<TempFile> m_tempFiles;
std::list<TempFolder> m_tempFolders;
CallbackImpl m_callback;

ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
Expand Down Expand Up @@ -185,7 +199,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg) && m_hwndWebToolWindow == 0 || !IsDialogMessage(m_hwndWebToolWindow, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
Expand Down Expand Up @@ -372,6 +386,14 @@ void UpdateMenuState(HWND hWnd)
CheckMenuItem(hMenu, IDM_SYNC_CLICK, m_pWebDiffWindow->GetSyncEventFlag(IWebDiffWindow::EVENT_CLICK) ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu, IDM_SYNC_INPUT, m_pWebDiffWindow->GetSyncEventFlag(IWebDiffWindow::EVENT_INPUT) ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu, IDM_SYNC_GOBACKFORWARD, m_pWebDiffWindow->GetSyncEventFlag(IWebDiffWindow::EVENT_GOBACKFORWARD) ? MF_CHECKED : MF_UNCHECKED);
m_pWebToolWindow->Sync();
}

HRESULT OnWebDiffEvent(const WebDiffEvent& e)
{
if (WebDiffEvent::CompareScreenshotsSelected <= e.type && e.type <= WebDiffEvent::CompareResourceTreesSelected)
PostMessage(m_hWnd, WM_COMMAND, IDM_COMPARE_SCREENSHOTS + e.type - WebDiffEvent::CompareScreenshotsSelected, 0);
return S_OK;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
Expand All @@ -380,13 +402,20 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
case WM_CREATE:
m_pWebDiffWindow = WinWebDiff_CreateWindow(hInstDLL, hWnd);
m_pWebToolWindow = WinWebDiff_CreateToolWindow(hInstDLL, hWnd, m_pWebDiffWindow);
m_hwndWebToolWindow = m_pWebToolWindow->GetHWND();
m_callback.AddRef();
m_pWebDiffWindow->AddEventListener(&m_callback);
UpdateMenuState(hWnd);
break;
case WM_SIZE:
{
RECT rc;
RECT rc, rcToolWindow;
GetClientRect(hWnd, &rc);
GetClientRect(m_hwndWebToolWindow, &rcToolWindow);
rc.right -= rcToolWindow.right;
m_pWebDiffWindow->SetWindowRect(rc);
MoveWindow(m_hwndWebToolWindow, rc.right, 0, rcToolWindow.right, rc.bottom, TRUE);
break;
}
case WM_COMMAND:
Expand Down Expand Up @@ -447,26 +476,32 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case IDM_VIEW_SIZE_FIT_TO_WINDOW:
m_pWebDiffWindow->SetFitToWindow(true);
m_pWebToolWindow->Sync();
break;
case IDM_VIEW_SIZE_320x512:
m_pWebDiffWindow->SetFitToWindow(false);
m_pWebDiffWindow->SetSize({ 320, 512 });
m_pWebToolWindow->Sync();
break;
case IDM_VIEW_SIZE_375x600:
m_pWebDiffWindow->SetFitToWindow(false);
m_pWebDiffWindow->SetSize({ 375, 600 });
m_pWebToolWindow->Sync();
break;
case IDM_VIEW_SIZE_1024x640:
m_pWebDiffWindow->SetFitToWindow(false);
m_pWebDiffWindow->SetSize({ 1024, 640 });
m_pWebToolWindow->Sync();
break;
case IDM_VIEW_SIZE_1280x800:
m_pWebDiffWindow->SetFitToWindow(false);
m_pWebDiffWindow->SetSize({ 1280, 800 });
m_pWebToolWindow->Sync();
break;
case IDM_VIEW_SIZE_1440x900:
m_pWebDiffWindow->SetFitToWindow(false);
m_pWebDiffWindow->SetSize({ 1440, 900});
m_pWebToolWindow->Sync();
break;
case IDM_VIEW_SPLITHORIZONTALLY:
m_pWebDiffWindow->SetHorizontalSplit(!m_pWebDiffWindow->GetHorizontalSplit());
Expand Down
Binary file modified src/WinWebDiff/WinWebDiff.rc
Binary file not shown.
227 changes: 227 additions & 0 deletions src/WinWebDiffLib/DiffLocation.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
#include <vector>
#include <map>
#include <string>
#include <rapidjson/document.h>

using WDocument = rapidjson::GenericDocument<rapidjson::UTF16<>>;
using WValue = rapidjson::GenericValue<rapidjson::UTF16<>>;

class DiffLocation
{
public:
struct Rect
{
float left;
float top;
float width;
float height;
};
struct ContainerRect : public Rect
{
int id;
int containerId;
float scrollLeft;
float scrollTop;
float scrollWidth;
float scrollHeight;
float clientWidth;
float clientHeight;
};
struct DiffRect : public Rect
{
int id;
int containerId;
};

void read(const WDocument& doc)
{
std::wstring window = doc[L"window"].GetString();
std::vector<ContainerRect> containerRects;
std::vector<DiffRect> diffRects;
for (const auto& value : doc[L"diffRects"].GetArray())
{
DiffRect rect;
rect.id = value[L"id"].GetInt();
rect.containerId = value[L"containerId"].GetInt();
rect.left = value[L"left"].GetFloat();
rect.top = value[L"top"].GetFloat();
rect.width = value[L"width"].GetFloat();
rect.height = value[L"height"].GetFloat();
diffRects.push_back(rect);
}
for (const auto& value : doc[L"containerRects"].GetArray())
{
ContainerRect rect;
rect.id = value[L"id"].GetInt();
rect.containerId = value[L"containerId"].GetInt();
rect.left = value[L"left"].GetFloat();
rect.top = value[L"top"].GetFloat();
rect.width = value[L"width"].GetFloat();
rect.height = value[L"height"].GetFloat();
rect.scrollLeft = value[L"scrollLeft"].GetFloat();
rect.scrollTop = value[L"scrollTop"].GetFloat();
rect.scrollWidth = value[L"scrollWidth"].GetFloat();
rect.scrollHeight = value[L"scrollHeight"].GetFloat();
rect.clientWidth = value[L"clientWidth"].GetFloat();
rect.clientHeight = value[L"clientHeight"].GetFloat();
containerRects.push_back(rect);
}
for (auto it = doc[L"frameRects"].MemberBegin(); it != doc[L"frameRects"].MemberEnd(); ++it)
{
Rect rect;
rect.left = it->value[L"left"].GetFloat();
rect.top = it->value[L"top"].GetFloat();
rect.width = it->value[L"width"].GetFloat();
rect.height = it->value[L"height"].GetFloat();
m_frameRects.insert_or_assign(it->name.GetString(), rect);
}
m_diffRects.insert_or_assign(window, diffRects);
m_containerRects.insert_or_assign(window, containerRects);
if (window == L"")
{
m_scrollX = doc[L"scrollX"].GetFloat();
m_scrollY = doc[L"scrollY"].GetFloat();
m_clientWidth = doc[L"clientWidth"].GetFloat();
m_clientHeight = doc[L"clientHeight"].GetFloat();
}
}

void clear()
{
m_diffRects.clear();
m_containerRects.clear();
m_scrollX = 0.0f;
m_scrollY = 0.0f;
m_clientWidth = 0.0f;
m_clientHeight = 0.0f;
}

void calcGlobalPosition(Rect& rect, std::wstring window)
{
while (!window.empty())
{
rect.left += m_frameRects[window].left;
rect.top += m_frameRects[window].top;
size_t lastOpeningBracketPos = window.find_last_of('[');
if (lastOpeningBracketPos != std::string::npos) {
window = window.substr(0, lastOpeningBracketPos);
}
}
}

std::vector<DiffRect> getDiffRectArray()
{
std::vector<DiffRect> diffRectsSerialized;
for (const auto& pair: m_diffRects)
{
const auto& window = pair.first;
for (const auto& diffRect : pair.second)
{
DiffRect rect;
rect.id = diffRect.id;
rect.containerId = diffRect.containerId;
rect.left = diffRect.left;
rect.top = diffRect.top;
rect.width = diffRect.width;
rect.height = diffRect.height;
for (int containerId = diffRect.containerId; containerId != -1; )
{
const ContainerRect& containerRect = m_containerRects[window][containerId];
if (containerRect.id == 0 && (containerRect.width == 0 || containerRect.height == 0))
break;
clip(rect, containerRect);
containerId = containerRect.containerId;
}
rect.left += m_scrollX;
rect.top += m_scrollY;
if (!window.empty())
{
calcGlobalPosition(rect, window);
Rect rcFrame = m_frameRects[window];
rcFrame.left += m_scrollX;
rcFrame.top += m_scrollY;
clip(rect, rcFrame);
}
diffRectsSerialized.push_back(rect);
}
}
return diffRectsSerialized;
}

std::vector<ContainerRect> getContainerRectArray()
{
std::vector<ContainerRect> containerRectsSerialized;
for (const auto& pair: m_containerRects)
{
const auto& window = pair.first;
for (const auto& containerRect : pair.second)
{
ContainerRect rect;
rect.id = containerRect.id;
rect.containerId = containerRect.containerId;
rect.left = containerRect.left + m_scrollX;
rect.top = containerRect.top + m_scrollY;
rect.width = containerRect.width;
rect.height = containerRect.height;
rect.scrollLeft = containerRect.scrollLeft;
rect.scrollTop = containerRect.scrollTop;
rect.scrollWidth = containerRect.scrollWidth;
rect.scrollHeight = containerRect.scrollHeight;
rect.clientWidth = containerRect.clientWidth;
rect.clientHeight = containerRect.clientHeight;
if (!window.empty())
{
calcGlobalPosition(rect, window);
Rect rcFrame = m_frameRects[window];
rcFrame.left += m_scrollX;
rcFrame.top += m_scrollY;
clip(rect, rcFrame);
}
containerRectsSerialized.push_back(rect);
}
}
return containerRectsSerialized;
}

Rect getVisibleAreaRect()
{
return { m_scrollX, m_scrollY, m_clientWidth, m_clientHeight };
}

private:
bool clip(Rect& rect, const Rect& containerRect)
{
if (rect.left + rect.width < containerRect.left ||
rect.top + rect.height < containerRect.top ||
rect.left > containerRect.left + containerRect.width ||
rect.top > containerRect.top + containerRect.height)
{
rect.left = rect.top = -99999.9f;
rect.width = rect.height = 0.0f;
return true;
}
if (rect.left < containerRect.left) {
rect.width -= containerRect.left - rect.left;
rect.left = containerRect.left;
}
if (rect.top < containerRect.top) {
rect.height -= containerRect.top - rect.top;
rect.top = containerRect.top;
}
if (rect.left + rect.width > containerRect.left + containerRect.width) {
rect.width = containerRect.left + containerRect.width - rect.left;
}
if (rect.top + rect.height > containerRect.top + containerRect.height) {
rect.height = containerRect.top + containerRect.height - rect.top;
}
return false;
}

std::map<std::wstring, std::vector<DiffRect>> m_diffRects;
std::map<std::wstring, std::vector<ContainerRect>> m_containerRects;
std::map<std::wstring, Rect> m_frameRects;
float m_scrollX = 0.0f;
float m_scrollY = 0.0f;
float m_clientWidth = 0.0f;
float m_clientHeight = 0.0f;
};
44 changes: 38 additions & 6 deletions src/WinWebDiffLib/Resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,52 @@
#define IDD_DIALOGBAR 103
#define IDC_DIFFMAP 112
#define IDR_SCRIPT 130
#define IDC_MENU 1021
#define IDC_ZOOM 1022
#define IDC_WIDTH 1023
#define IDC_HEIGHT 1024
#define IDR_POPUP_WEBPAGE_COMPARE 131
#define IDR_POPUP_WEBPAGE_SYNC_EVENTS 132
#define IDC_COMPARE 1021
#define IDC_ZOOM_LABEL 1022
#define IDC_ZOOM 1023
#define IDC_WIDTH 1024
#define IDC_BY 1025
#define IDC_HEIGHT 1026
#define IDC_FITTOWINDOW 1027
#define IDC_USERAGENT 1028
#define IDC_SHOWDIFFERENCES 1029
#define IDC_SYNC_EVENTS 1030
#define ID_WEB_COMPARE_SCREENSHOTS 1633
#define ID_WEB_COMPARE_FULLSIZE_SCREENSHOTS 1634
#define ID_WEB_COMPARE_HTMLS 1635
#define ID_WEB_COMPARE_TEXTS 1636
#define ID_WEB_COMPARE_RESOURCETREES 1637
#define ID_WEB_SYNC_ENABLED 1638
#define ID_WEB_SYNC_SCROLL 1639
#define ID_WEB_SYNC_CLICK 1640
#define ID_WEB_SYNC_INPUT 1641
#define ID_WEB_SYNC_GOBACKFORWARD 1642
#define IDS_COMPARE 2000
#define IDS_ZOOM 2001
#define IDS_SYNC_EVENTS 2002
#define IDS_SHOWDIFFERENCES 2003
#define IDS_WEB_COMPARE_SCREENSHOTS 2004
#define IDS_WEB_COMPARE_FULLSIZE_SCREENSHOTS 2005
#define IDS_WEB_COMPARE_HTMLS 2006
#define IDS_WEB_COMPARE_TEXTS 2007
#define IDS_WEB_COMPARE_RESOURCETREES 2008
#define IDS_WEB_SYNC_ENABLED 2009
#define IDS_WEB_SYNC_SCROLL 2010
#define IDS_WEB_SYNC_CLICK 2011
#define IDS_WEB_SYNC_INPUT 2012
#define IDS_WEB_SYNC_GOBACKFORWARD 2013
#define IDC_STATIC -1

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_RESOURCE_VALUE 133
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_CONTROL_VALUE 1031
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
Loading

0 comments on commit a22a6b3

Please sign in to comment.