Skip to content

Commit 0d4eeac

Browse files
Merge pull request #4 from Nanticock/PM-140-Eliminate-the-need-to-explicitly-set-the-built-in-PropertyEditors-for-each-new-PropertyGrid
PM-140 eliminate the need to explicitly set the built in property editors for each new property grid
2 parents 498eaa4 + 1c7f1e6 commit 0d4eeac

21 files changed

Lines changed: 469 additions & 245 deletions

.github/workflows/linux.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ on:
44
workflow_dispatch:
55
push:
66
branches: [main, develop]
7+
paths-ignore:
8+
- '*.md'
9+
710
pull_request:
811
branches: [main, develop]
12+
paths-ignore:
13+
- '*.md'
914

1015
jobs:
1116
get-matrix:
12-
uses: ./.github/workflows/matrix-config.yml
17+
uses: ./.github/workflows/_matrix-config.yml
1318

1419
build-linux:
1520
name: linux-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}
@@ -25,7 +30,7 @@ jobs:
2530
- c_compiler: clang
2631
cpp_compiler: clang++
2732

28-
uses: ./.github/workflows/build-shared.yml
33+
uses: ./.github/workflows/_build-shared.yml
2934
with:
3035
os: ubuntu-latest
3136
c_compiler: ${{ matrix.c_compiler }}

.github/workflows/macos.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ on:
44
workflow_dispatch:
55
push:
66
branches: [main, develop]
7+
paths-ignore:
8+
- '*.md'
9+
710
pull_request:
811
branches: [main, develop]
12+
paths-ignore:
13+
- '*.md'
914

1015
jobs:
1116
get-matrix:
12-
uses: ./.github/workflows/matrix-config.yml
17+
uses: ./.github/workflows/_matrix-config.yml
1318

1419
build-macos-intel:
1520
name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-intel
@@ -25,7 +30,7 @@ jobs:
2530
- c_compiler: clang
2631
cpp_compiler: clang++
2732

28-
uses: ./.github/workflows/build-shared.yml
33+
uses: ./.github/workflows/_build-shared.yml
2934
with:
3035
os: macos-13 # Intel-based macOS
3136
c_compiler: ${{ matrix.c_compiler }}
@@ -51,7 +56,7 @@ jobs:
5156
- qt_version: "5.12.*"
5257
- qt_version: "5.15.*"
5358

54-
uses: ./.github/workflows/build-shared.yml
59+
uses: ./.github/workflows/_build-shared.yml
5560
with:
5661
os: macos-latest # Apple Silicon macOS
5762
c_compiler: ${{ matrix.c_compiler }}

.github/workflows/windows.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ on:
44
workflow_dispatch:
55
push:
66
branches: [main, develop]
7+
paths-ignore:
8+
- '*.md'
9+
710
pull_request:
811
branches: [main, develop]
12+
paths-ignore:
13+
- '*.md'
914

1015
jobs:
1116
get-matrix:
12-
uses: ./.github/workflows/matrix-config.yml
17+
uses: ./.github/workflows/_matrix-config.yml
1318

1419
build-windows:
1520
name: windows-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}
@@ -27,7 +32,7 @@ jobs:
2732
- c_compiler: clang
2833
cpp_compiler: clang++
2934

30-
uses: ./.github/workflows/build-shared.yml
35+
uses: ./.github/workflows/_build-shared.yml
3136
with:
3237
os: windows-latest
3338
c_compiler: ${{ matrix.c_compiler }}

README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,6 @@ int main(int argc, char *argv[])
7171
QApplication app(argc, argv);
7272

7373
PM::PropertyGrid propertyGrid;
74-
//
75-
// ONLY FOR NOW...
76-
//
77-
// Add editors for the property types that you're using
78-
// This won't be required in the future
79-
//
80-
propertyGrid.addPropertyEditor<PM::BoolPropertyEditor>();
81-
propertyGrid.addPropertyEditor<PM::ColorPropertyEditor>();
8274

8375
// Add simple properties
8476
propertyGrid.addProperty("Name", QString("My Object"));

examples/property_grid_showcase/main.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,6 @@ int main(int argc, char **argv)
4646
QApplication app(argc, argv);
4747

4848
PM::PropertyGrid propertyGrid;
49-
propertyGrid.addPropertyEditor<PM::FontPropertyEditor>();
50-
propertyGrid.addPropertyEditor<PM::SizePropertyEditor>();
51-
propertyGrid.addPropertyEditor<PM::BoolPropertyEditor>();
52-
propertyGrid.addPropertyEditor<PM::RectPropertyEditor>();
53-
propertyGrid.addPropertyEditor<PM::ColorPropertyEditor>();
54-
propertyGrid.addPropertyEditor<PM::ImagesPropertyEditor>();
55-
propertyGrid.addPropertyEditor<PM::CursorPropertyEditor>();
5649

5750
// add properties
5851
addProperty(propertyGrid, "Property1", "Value1", "Description of property1");

src/CMakeLists.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets REQUIRED)
1212

1313
set(PUBLIC_HEADERS
1414
Property.h
15+
QtCompat_p.h
1516
PropertyGrid.h
1617
PropertyEditor.h
17-
QtCompat_p.h
18+
PropertyContext.h
1819
)
1920

2021
add_library(PmPropertyGrid STATIC
@@ -23,10 +24,13 @@ add_library(PmPropertyGrid STATIC
2324
PropertyGrid.ui
2425
PropertyGrid_p.h
2526
PropertyGrid.cpp
26-
PropertyGridTreeItem.h
27+
PropertyGridTreeItem_p.h
2728
PropertyGridTreeItem.cpp
28-
PropertyGridTreeModel.h
29+
PropertyGridTreeModel_p.h
2930
PropertyGridTreeModel.cpp
31+
PropertyContext_p.h
32+
PropertyContext.cpp
33+
3034
${PUBLIC_HEADERS}
3135
)
3236

src/PropertyContext.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include "PropertyContext.h"
2+
#include "PropertyContext_p.h"
3+
4+
#include "PropertyGrid.h"
5+
6+
using namespace PM;
7+
8+
PropertyContext &PropertyContextPrivate::invalidContext()
9+
{
10+
static PropertyContext result;
11+
12+
return result;
13+
}
14+
15+
PropertyContext PropertyContextPrivate::createContext(const Property &property)
16+
{
17+
return PropertyContext(property, QVariant(), nullptr, nullptr);
18+
}
19+
20+
PropertyContext PropertyContextPrivate::createContext(const QVariant &value, bool valid)
21+
{
22+
PropertyContext result;
23+
result.m_value = value;
24+
result.m_isValid = valid;
25+
26+
return result;
27+
}
28+
29+
PropertyContext PropertyContextPrivate::createContext(const PropertyContext &other, const QVariant &newValue)
30+
{
31+
PropertyContext result = other;
32+
result.m_value = newValue;
33+
34+
return result;
35+
}
36+
37+
PropertyContext PropertyContextPrivate::createContext(const Property &property, const QVariant &value, void *object, PropertyGrid *propertyGrid)
38+
{
39+
return PropertyContext(property, value, object, propertyGrid);
40+
}
41+
42+
void PropertyContextPrivate::setValue(PropertyContext &context, const QVariant &value)
43+
{
44+
context.m_value = value;
45+
notifyValueChanged(context, value);
46+
}
47+
48+
PropertyContextPrivate::valueChangedSlot_t PropertyContextPrivate::defaultValueChangedSlot()
49+
{
50+
static valueChangedSlot_t result = [](const QVariant &) {};
51+
52+
return result;
53+
}
54+
55+
void PropertyContextPrivate::disconnectValueChangedSlot(PropertyContext &context)
56+
{
57+
context.m_valueChangedSlot = defaultValueChangedSlot();
58+
}
59+
60+
void PropertyContextPrivate::connectValueChangedSlot(PropertyContext &context, const valueChangedSlot_t &slot)
61+
{
62+
context.m_valueChangedSlot = slot;
63+
}
64+
65+
void PropertyContextPrivate::notifyValueChanged(const PropertyContext &context, const QVariant &newValue)
66+
{
67+
context.m_valueChangedSlot(newValue);
68+
}
69+
70+
Property PropertyContext::property() const
71+
{
72+
return m_property;
73+
}
74+
75+
QVariant PropertyContext::value() const
76+
{
77+
return m_value;
78+
}
79+
80+
bool PropertyContext::isValid() const
81+
{
82+
return m_isValid;
83+
}
84+
85+
PropertyGrid *PropertyContext::propertyGrid() const
86+
{
87+
return m_propertyGrid;
88+
}
89+
90+
PropertyContext::PropertyContext() : PropertyContext(Property(), QVariant(), nullptr, nullptr)
91+
{
92+
}
93+
94+
PropertyContext::PropertyContext(const Property &property, const QVariant &value, void *object, PropertyGrid *propertyGrid) :
95+
m_property(property),
96+
m_value(value),
97+
m_object(object),
98+
m_propertyGrid(propertyGrid),
99+
m_isValid(!property.name().isEmpty()),
100+
m_valueChangedSlot(PropertyContextPrivate::defaultValueChangedSlot())
101+
{
102+
}

src/PropertyContext.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#ifndef PROPERTYCONTEXT_H
2+
#define PROPERTYCONTEXT_H
3+
4+
#include "Property.h"
5+
6+
#include <QPointer>
7+
8+
namespace PM
9+
{
10+
class PropertyGrid;
11+
class PropertyContextPrivate;
12+
13+
class PropertyContext
14+
{
15+
friend class PM::PropertyContextPrivate;
16+
17+
public:
18+
Property property() const;
19+
QVariant value() const;
20+
21+
bool isValid() const;
22+
23+
template <typename T>
24+
T object() const // WARNING: this function doesn't perform any checks for type-safety
25+
{
26+
return getObjectValue<T>(std::is_pointer<T>());
27+
}
28+
29+
PropertyGrid *propertyGrid() const;
30+
31+
private: // TODO: wouldn't this cause problems when writing unit tests for user property editors?
32+
PropertyContext();
33+
PropertyContext(const Property &property, const QVariant &value, void *object, PropertyGrid *propertyGrid);
34+
35+
// function for pointer types
36+
template <typename T>
37+
T getObjectValue(std::true_type) const
38+
{
39+
return static_cast<T>(m_object);
40+
}
41+
42+
// function for non-pointer types
43+
template <typename T>
44+
T getObjectValue(std::false_type) const
45+
{
46+
T *result = static_cast<T *>(m_object);
47+
if (result == nullptr)
48+
return T();
49+
50+
return *result;
51+
}
52+
53+
private:
54+
Property m_property;
55+
QVariant m_value;
56+
void *m_object; // TODO: use std::any
57+
QPointer<PropertyGrid> m_propertyGrid;
58+
59+
// Meta values
60+
bool m_isValid;
61+
std::function<void(const QVariant &)> m_valueChangedSlot;
62+
};
63+
} // namespace PM
64+
65+
#endif // PROPERTYCONTEXT_H

0 commit comments

Comments
 (0)