Added ChangeListPane widget to snapshot diff window

This commit is contained in:
Nav
2023-08-24 00:39:28 +01:00
parent 3bc63d9560
commit 9e4f5988fb
11 changed files with 720 additions and 2 deletions

View File

@@ -115,6 +115,8 @@ target_sources(
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/DifferentialHexViewerWidget/DifferentialHexViewerWidget.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/DifferentialHexViewerWidget/DifferentialItemGraphicsView.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/DifferentialHexViewerWidget/DifferentialItemGraphicsScene.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListItem.cpp
# Memory region manager window
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp
@@ -208,6 +210,7 @@ qt_add_resources(
"./UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/Images/sync-hex-viewer-scroll.svg"
"./UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/Images/sync-hex-viewer-hover.svg"
"./UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/Images/sync-hex-viewer-selection.svg"
"./UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/Images/view-change-list-icon.svg"
# Memory region manager window
"./UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/UiFiles/MemoryRegionManagerWindow.ui"

View File

@@ -0,0 +1,94 @@
#include "ChangeListItem.hpp"
#include <QString>
#include <QLocale>
namespace Widgets
{
ChangeListItem::ChangeListItem(const Targets::TargetMemoryAddressRange& addressRange)
: addressRange(addressRange)
{
this->size = QSize(0, ChangeListItem::HEIGHT);
}
void ChangeListItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
static constexpr auto margins = QMargins(7, 5, 7, 0);
static auto font = QFont("'Ubuntu', sans-serif");
font.setPixelSize(14);
static auto secondaryFont = QFont("'Ubuntu', sans-serif");
secondaryFont.setPixelSize(13);
static constexpr auto fontColor = QColor(0xAF, 0xB1, 0xB3);
static constexpr auto secondaryFontColor = QColor(0x8A, 0x8A, 0x8D);
if (this->selected) {
static constexpr auto selectedBackgroundColor = QColor(0x3C, 0x59, 0x5C);
painter->setBrush(selectedBackgroundColor);
painter->setPen(Qt::PenStyle::NoPen);
painter->drawRect(QRect(QPoint(0, 0), this->size));
}
painter->setFont(font);
painter->setPen(fontColor);
auto fontMetrics = painter->fontMetrics();
const auto byteCount = this->addressRange.endAddress - this->addressRange.startAddress + 1;
const auto byteCountText = QLocale(QLocale::English).toString(byteCount)
+ (byteCount == 1 ? " byte" : " bytes");
const auto byteCountTextSize = fontMetrics.size(Qt::TextSingleLine, byteCountText);
const auto byteCountTextRect = QRect(
margins.left(),
margins.top(),
byteCountTextSize.width(),
byteCountTextSize.height()
);
painter->drawText(byteCountTextRect, Qt::AlignLeft, byteCountText);
painter->setFont(secondaryFont);
fontMetrics = painter->fontMetrics();
if (!this->selected) {
painter->setPen(secondaryFontColor);
}
auto addressRangeText = "0x" + QString::number(
this->addressRange.startAddress,
16
).rightJustified(8, '0').toUpper();
if (byteCount > 1) {
addressRangeText += " -> 0x" + QString::number(
this->addressRange.endAddress,
16
).rightJustified(8, '0').toUpper();
}
const auto availableAddressRangeTextWidth = this->size.width() - margins.left() - margins.right();
addressRangeText = fontMetrics.elidedText(
addressRangeText,
Qt::TextElideMode::ElideRight,
availableAddressRangeTextWidth
);
const auto addressRangeTextSize = fontMetrics.size(Qt::TextSingleLine, addressRangeText);
const auto addressRangeTextRect = QRect(
margins.left(),
byteCountTextRect.bottom() + 5,
addressRangeTextSize.width(),
addressRangeTextSize.height()
);
painter->drawText(addressRangeTextRect, Qt::AlignLeft, addressRangeText);
static constexpr auto borderColor = QColor(0x41, 0x42, 0x3F);
painter->setPen(borderColor);
painter->drawLine(0, this->size.height() - 1, this->size.width(), this->size.height() - 1);
}
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListItem.hpp"
#include "src/Targets/TargetMemory.hpp"
namespace Widgets
{
class ChangeListItem: public ListItem
{
public:
Targets::TargetMemoryAddressRange addressRange;
ChangeListItem(const Targets::TargetMemoryAddressRange& addressRange);
bool operator < (const ListItem& rhs) const override {
const auto& rhsSnapshotItem = dynamic_cast<const ChangeListItem&>(rhs);
return this->addressRange.startAddress < rhsSnapshotItem.addressRange.startAddress;
}
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
private:
static constexpr int HEIGHT = 50;
};
}

View File

@@ -0,0 +1,123 @@
#include "ChangeListPane.hpp"
#include <QFile>
#include <QVBoxLayout>
#include <algorithm>
#include <QScrollBar>
#include "src/Insight/UserInterfaces/InsightWindow/UiLoader.hpp"
#include "src/Services/PathService.hpp"
#include "src/Exceptions/Exception.hpp"
namespace Widgets
{
using Exceptions::Exception;
ChangeListPane::ChangeListPane(
DifferentialHexViewerWidget* hexViewerWidgetA,
DifferentialHexViewerWidget* hexViewerWidgetB,
PaneState& state,
PanelWidget* parent
)
: PaneWidget(state, parent)
, hexViewerWidgetA(hexViewerWidgetA)
, hexViewerWidgetB(hexViewerWidgetB)
{
this->setObjectName("change-list-pane");
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
auto widgetUiFile = QFile(
QString::fromStdString(Services::PathService::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager"
+ "/SnapshotDiff/ChangeListPane/UiFiles/ChangeListPane.ui"
)
);
if (!widgetUiFile.open(QFile::ReadOnly)) {
throw Exception("Failed to open ChangeListPane UI file");
}
auto uiLoader = UiLoader(this);
this->container = uiLoader.load(&widgetUiFile, this);
this->container->setFixedSize(this->size());
this->container->setContentsMargins(0, 0, 0, 0);
auto* containerLayout = this->container->findChild<QVBoxLayout*>();
this->changeListView = new ListView({}, this);
this->changeListView->viewport()->installEventFilter(parent);
this->changeListView->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
this->changeListScene = this->changeListView->listScene();
this->changeListScene->setSelectionLimit(1);
containerLayout->addWidget(this->changeListView);
QObject::connect(
this->changeListView->verticalScrollBar(),
&QScrollBar::rangeChanged,
this,
&ChangeListPane::refreshChangeListViewSize
);
QObject::connect(
this->changeListScene,
&ListScene::selectionChanged,
this,
&ChangeListPane::onItemSelectionChanged
);
this->show();
}
void ChangeListPane::setDiffRanges(const std::vector<Targets::TargetMemoryAddressRange>& diffRanges) {
this->changeListScene->clearListItems();
for (const auto& diffRange : diffRanges) {
this->changeListScene->addListItem(new ChangeListItem(diffRange));
}
this->changeListScene->refreshGeometry();
// Trigger a resize event
this->resize(this->size());
}
void ChangeListPane::resizeEvent(QResizeEvent* event) {
const auto size = this->size();
this->container->setFixedSize(size.width() - 1, size.height());
this->refreshChangeListViewSize();
PaneWidget::resizeEvent(event);
}
void ChangeListPane::showEvent(QShowEvent* event) {
this->refreshChangeListViewSize();
PaneWidget::showEvent(event);
}
void ChangeListPane::onItemSelectionChanged(const std::list<ListItem*>& selectedItems) {
if (selectedItems.size() < 1) {
return;
}
const auto* item = dynamic_cast<ChangeListItem*>(selectedItems.front());
this->hexViewerWidgetA->selectAndHighlightBytes({item->addressRange});
this->hexViewerWidgetA->centerOnByte(item->addressRange.startAddress);
this->hexViewerWidgetB->selectAndHighlightBytes({item->addressRange});
this->hexViewerWidgetB->centerOnByte(item->addressRange.startAddress);
}
void ChangeListPane::refreshChangeListViewSize() {
this->changeListView->setFixedWidth(
this->container->width() - (
this->changeListView->verticalScrollBar()->isVisible() ? this->parentPanel->getHandleSize() : 0
)
);
}
}

View File

@@ -0,0 +1,47 @@
#pragma once
#include <QWidget>
#include <QResizeEvent>
#include <QShowEvent>
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListView.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/DifferentialHexViewerWidget/DifferentialHexViewerWidget.hpp"
#include "src/Targets/TargetMemory.hpp"
#include "ChangeListItem.hpp"
namespace Widgets
{
class ChangeListPane: public PaneWidget
{
Q_OBJECT
public:
explicit ChangeListPane(
DifferentialHexViewerWidget* hexViewerWidgetA,
DifferentialHexViewerWidget* hexViewerWidgetB,
PaneState& state,
PanelWidget* parent = nullptr
);
void setDiffRanges(const std::vector<Targets::TargetMemoryAddressRange>& diffRanges);
protected:
void resizeEvent(QResizeEvent* event) override;
void showEvent(QShowEvent* event) override;
private:
DifferentialHexViewerWidget* hexViewerWidgetA;
DifferentialHexViewerWidget* hexViewerWidgetB;
QWidget* container = nullptr;
ListView* changeListView = nullptr;
ListScene* changeListScene = nullptr;
void onItemSelectionChanged(const std::list<ListItem*>& selectedItems);
void refreshChangeListViewSize();
};
}

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<widget class="QWidget" name="container">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"/>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="title-bar">
<property name="minimumHeight">
<number>28</number>
</property>
<property name="maximumHeight">
<number>28</number>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"/>
</property>
<layout class="QHBoxLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<spacer name="horizontal-spacer">
<property name="sizeHint">
<size>
<width>5</width>
</size>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
</spacer>
</item>
<item>
<widget class="Label" name="change-list-title-label">
<property name="text">
<string>Differences</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<spacer name="horizontal-spacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</ui>

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="22"
height="15"
viewBox="0 0 5.8208333 3.96875"
version="1.1"
id="svg974"
sodipodi:docname="view-change-list-icon.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs968" />
<sodipodi:namedview
id="base"
pagecolor="#343532"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="27.557152"
inkscape:cx="8.4732995"
inkscape:cy="7.0399148"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
units="px"
inkscape:snap-page="true"
inkscape:window-width="3440"
inkscape:window-height="1353"
inkscape:window-x="2560"
inkscape:window-y="34"
inkscape:window-maximized="1"
inkscape:pagecheckerboard="0" />
<metadata
id="metadata971">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
sodipodi:type="star"
style="fill:#838382;fill-opacity:1;stroke:none;stroke-width:3.15673;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path954"
inkscape:flatsided="false"
sodipodi:sides="3"
sodipodi:cx="3.6919894"
sodipodi:cy="6.7028265"
sodipodi:r1="8.1449661"
sodipodi:r2="4.0724831"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 10.745737,10.77531 -7.0537475,0 -7.0537477,0 3.52687378,-6.1087249 3.52687392,-6.1087247 3.5268737,6.1087245 z"
transform="matrix(0.22505767,0,0,0.23821803,2.0795061,0.87271031)"
inkscape:transform-center-y="-0.48506947" />
<path
sodipodi:type="star"
style="fill:#343532;fill-opacity:1;stroke:none;stroke-width:3.15673;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path954-6"
inkscape:flatsided="false"
sodipodi:sides="3"
sodipodi:cx="3.6919894"
sodipodi:cy="6.7028265"
sodipodi:r1="8.1449661"
sodipodi:r2="4.0724831"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0"
inkscape:randomized="0"
transform="matrix(0.07501922,0,0,0.08662474,2.6334465,1.8447166)"
inkscape:transform-center-y="-0.17638902"
d="m 10.745737,10.77531 -7.0537475,0 -7.0537477,0 3.52687378,-6.1087249 3.52687392,-6.1087247 3.5268737,6.1087245 z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -128,7 +128,12 @@ namespace Widgets
}
void SnapshotDiff::resizeEvent(QResizeEvent* event) {
this->container->setFixedSize(this->size());
const auto windowSize = this->size();
this->container->setFixedSize(windowSize);
const auto maxLeftPanelSize = static_cast<int>(windowSize.width() / 3);
this->leftPanel->setMaximumResize(maxLeftPanelSize);
this->leftPanel->setMinimumResize(std::min(this->leftPanel->getMinimumResize(), maxLeftPanelSize));
QWidget::resizeEvent(event);
}
@@ -176,6 +181,19 @@ namespace Widgets
this->syncHexViewerHoverButton = toolBar->findChild<SvgToolButton*>("sync-hover-btn");
this->syncHexViewerSelectionButton = toolBar->findChild<SvgToolButton*>("sync-selection-btn");
this->viewChangeListButton = this->container->findChild<QToolButton*>("change-list-btn");
this->viewChangeListButton->layout()->setContentsMargins(0, 0, 0, 0);
auto* subContainerLayout = this->container->findChild<QWidget*>(
"sub-container"
)->findChild<QHBoxLayout*>("sub-layout");
this->leftPanel = new PanelWidget(PanelWidgetType::LEFT, this->leftPanelState, this);
this->leftPanel->setObjectName("left-panel");
this->leftPanel->setMinimumResize(200);
this->leftPanel->setHandleSize(6);
subContainerLayout->insertWidget(1, this->leftPanel, 0, Qt::AlignLeft);
this->dataAContainer = this->container->findChild<QWidget*>("data-a-container");
this->dataBContainer = this->container->findChild<QWidget*>("data-b-container");
@@ -220,6 +238,15 @@ namespace Widgets
snapshotAContainerLayout->addWidget(this->hexViewerWidgetA);
snapshotBContainerLayout->addWidget(this->hexViewerWidgetB);
this->changeListPane = new ChangeListPane(
this->hexViewerWidgetA,
this->hexViewerWidgetB,
this->changeListPaneState,
this->leftPanel
);
this->leftPanel->layout()->addWidget(this->changeListPane);
this->viewChangeListButton->setChecked(this->changeListPane->state.activated);
this->bottomBar = this->container->findChild<QWidget*>("bottom-bar");
this->bottomBarLayout = this->bottomBar->findChild<QHBoxLayout*>();
@@ -240,6 +267,13 @@ namespace Widgets
this->setSyncHexViewerHoverEnabled(this->settings.syncHexViewerHover);
this->setSyncHexViewerSelectionEnabled(this->settings.syncHexViewerSelection);
QObject::connect(
this->viewChangeListButton,
&QToolButton::clicked,
this,
&SnapshotDiff::toggleChangeListPane
);
QObject::connect(
this->syncHexViewerSettingsButton,
&QToolButton::clicked,
@@ -308,10 +342,13 @@ namespace Widgets
}
void SnapshotDiff::refreshDifferences() {
using Targets::TargetMemoryAddressRange;
assert(this->hexViewerDataA.has_value());
assert(this->hexViewerDataB.has_value());
this->differentialHexViewerSharedState.differences.clear();
auto diffRanges = std::vector<TargetMemoryAddressRange>();
const auto& dataA = *(this->hexViewerDataA);
const auto& dataB = *(this->hexViewerDataB);
@@ -333,16 +370,32 @@ namespace Widgets
};
const auto& memoryStartAddress = this->memoryDescriptor.addressRange.startAddress;
auto lastDiffRange = std::optional<TargetMemoryAddressRange>();
for (Targets::TargetMemoryBuffer::size_type i = 0; i < dataA.size(); ++i) {
const auto address = memoryStartAddress + static_cast<Targets::TargetMemoryAddress>(i);
if (dataA[i] != dataB[i] && !isAddressExcluded(address)) {
this->differentialHexViewerSharedState.differences.insert(address);
if (lastDiffRange.has_value() && address > 0 && lastDiffRange->endAddress == (address - 1)) {
lastDiffRange->endAddress = address;
} else {
if (lastDiffRange.has_value()) {
diffRanges.push_back(*lastDiffRange);
}
lastDiffRange = TargetMemoryAddressRange(address, address);
}
}
}
const auto count = this->differentialHexViewerSharedState.differences.size();
if (lastDiffRange.has_value()) {
diffRanges.push_back(*lastDiffRange);
}
this->changeListPane->setDiffRanges(diffRanges);
this->diffCountLabel->setText(
count == 0
? "Contents are identical"
@@ -350,6 +403,17 @@ namespace Widgets
);
}
void SnapshotDiff::toggleChangeListPane() {
if (!this->changeListPane->state.activated) {
this->changeListPane->activate();
this->viewChangeListButton->setChecked(true);
return;
}
this->changeListPane->deactivate();
this->viewChangeListButton->setChecked(false);
}
void SnapshotDiff::setSyncHexViewerSettingsEnabled(bool enabled) {
this->settings.syncHexViewerSettings = enabled;
this->syncHexViewerSettingsButton->setChecked(this->settings.syncHexViewerSettings);

View File

@@ -9,6 +9,7 @@
#include "SnapshotDiffSettings.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/Label.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TaskProgressIndicator/TaskProgressIndicator.hpp"
@@ -17,6 +18,7 @@
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp"
#include "DifferentialHexViewerWidget/DifferentialHexViewerWidget.hpp"
#include "ChangeListPane/ChangeListPane.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ContextMenuAction.hpp"
namespace Widgets
@@ -66,6 +68,14 @@ namespace Widgets
SvgToolButton* syncHexViewerHoverButton = nullptr;
SvgToolButton* syncHexViewerSelectionButton = nullptr;
QToolButton* viewChangeListButton = nullptr;
PanelWidget* leftPanel = nullptr;
PanelState leftPanelState = PanelState(300, true);
PaneState changeListPaneState = PaneState(true, true, std::nullopt);
ChangeListPane* changeListPane = nullptr;
QWidget* dataAContainer = nullptr;
QWidget* dataBContainer = nullptr;
@@ -108,6 +118,8 @@ namespace Widgets
void refreshDifferences();
void toggleChangeListPane();
void setSyncHexViewerSettingsEnabled(bool enabled);
void setSyncHexViewerScrollEnabled(bool enabled);
void setSyncHexViewerHoverEnabled(bool enabled);

View File

@@ -41,6 +41,62 @@
max-width: 1px;
}
#snapshot-diff #lh-side-bar {
border-right: 1px solid #41423f;
}
#snapshot-diff #rh-side-bar {
border-left: 1px solid #41423f;
}
#snapshot-diff #lh-side-bar QToolButton,
#snapshot-diff #rh-side-bar QToolButton {
border: none;
margin: 0;
}
#snapshot-diff #lh-side-bar #change-list-btn {
border: none;
margin: 0;
}
#snapshot-diff #lh-side-bar #change-list-btn #label {
qproperty-bottomMargin: 1;
color: #999a9d;
}
#snapshot-diff #lh-side-bar #change-list-btn:hover {
background-color: #2F2F2D;
border: none;
}
#snapshot-diff #lh-side-bar #change-list-btn:checked {
background-color: #2F2F2D;
}
#snapshot-diff #left-panel {
border-right: 1px solid #41423f;
background-color: transparent;
}
/* ChangeListPane */
#change-list-pane #title-bar {
background-color: transparent;
border-bottom: 1px solid #41423f;
}
#change-list-pane #title-bar #change-list-title-label {
color: #8a8a8d;
}
#change-list-pane QScrollBar {
margin: 0;
padding: 1px 0 0 6px;
width: 14px;
border-left: 1px solid #41423f;
}
#snapshot-diff #data-details-container {
border-bottom: 1px solid #41423f;
color: #8a8a8d;

View File

@@ -134,6 +134,116 @@
<property name="margin">
<number>0</number>
</property>
<item alignment="Qt::AlignLeft">
<widget class="QWidget" name="lh-side-bar">
<property name="minimumWidth">
<number>23</number>
</property>
<property name="maximumWidth">
<number>23</number>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"/>
</property>
<layout class="QVBoxLayout" name="lh-side-bar-layout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<spacer name="vertical-spacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</spacer>
</item>
<item alignment="Qt::AlignLeft">
<widget class="QToolButton" name="change-list-btn">
<property name="minimumWidth">
<number>22</number>
</property>
<property name="maximumWidth">
<number>22</number>
</property>
<property name="minimumHeight">
<number>108</number>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolTip">
<string>View differences</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<spacer name="vertical-spacer">
<property name="sizeHint">
<size>
<height>10</height>
</size>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
</spacer>
</item>
<item alignment="Qt::AlignTop">
<widget class="RotatableLabel" name="label">
<property name="angle">
<number>270</number>
</property>
<property name="text">
<string>Differences</string>
</property>
</widget>
</item>
<item>
<spacer name="vertical-spacer">
<property name="sizeHint">
<size>
<height>2</height>
</size>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
</spacer>
</item>
<item alignment="Qt::AlignTop">
<widget class="SvgWidget" name="icon">
<property name="containerHeight">
<number>15</number>
</property>
<property name="containerWidth">
<number>22</number>
</property>
<property name="svgFilePath">
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/Images/view-change-list-icon.svg</string>
</property>
</widget>
</item>
<item>
<spacer name="vertical-spacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="data-a-container">
<property name="sizePolicy">
@@ -280,6 +390,35 @@
</layout>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<widget class="QWidget" name="rh-side-bar">
<property name="minimumWidth">
<number>23</number>
</property>
<property name="maximumWidth">
<number>23</number>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"/>
</property>
<layout class="QVBoxLayout" name="rh-side-bar-layout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<spacer name="vertical-spacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</spacer>
</item>
<!-- Button items here -->
</layout>
</widget>
</item>
</layout>
</widget>
</item>