Compare commits
50 Commits
1031ba5808
...
3f1421a1bd
Author | SHA1 | Date |
---|---|---|
karlis | 3f1421a1bd | |
karlis | 4c9fe168a9 | |
karlis | de9d7143b6 | |
karlis | ed4c3c0064 | |
wuyize | 0d42af9200 | |
ArgonarioD | acd25b4964 | |
karlis | e3217aa134 | |
karlis | 2cb25b8607 | |
yang.yongquan | 631f0f8af7 | |
yang.yongquan | 50acb3b625 | |
karlis | c92a3553ce | |
wuyize | 4bfdb0d9f6 | |
karlis | ca8d68fe93 | |
karlis | 3dd7fd7c0f | |
wuyize | 6508f54333 | |
ArgonarioD | b981056674 | |
ArgonarioD | 293c1f3096 | |
ArgonarioD | 65e03ed3ba | |
ArgonarioD | 94b16ac536 | |
ArgonarioD | 7c7cd02d71 | |
wuyize | 520597e288 | |
ArgonarioD | 15e2522591 | |
ArgonarioD | 14a1502a22 | |
ArgonarioD | 846f334d54 | |
karlis | fedb147dd3 | |
wuyize | d0cbdd65ec | |
wuyize | f504480050 | |
ArgonarioD | 52734adda8 | |
ArgonarioD | e7bce3f93e | |
karlis | 25eec60e5c | |
ArgonarioD | 652fa483ba | |
karlis | 6f8bfa1558 | |
karlis | ef990cd4b4 | |
wuyize | c2dd8271e3 | |
wuyize | 6412d9c865 | |
yang.yongquan | 11c9ccc3a9 | |
wuyize | 08e54cfc30 | |
wuyize | f4f1547d21 | |
yang.yongquan | 7d4a191f02 | |
yang.yongquan | 1118dc819a | |
karlis | 477517d919 | |
karlis | 368eaa6c89 | |
karlis | edb7e37b91 | |
karlis | 06c96144e4 | |
wuyize | 526f33ceba | |
yang.yongquan | 6a4a724f00 | |
yang.yongquan | 53025b93e4 | |
yang.yongquan | a28e484cb2 | |
yang.yongquan | f578fe6184 | |
wuyize | 56f64f00f0 |
|
@ -104,10 +104,12 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.cpp" />
|
||||
<ClCompile Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.cpp" />
|
||||
<ClCompile Include="src\Editor\EditorWidget.cpp" />
|
||||
<ClCompile Include="src\CaptionButton.cpp" />
|
||||
<ClCompile Include="src\Editor\EditorWidgetItem.cpp" />
|
||||
<ClCompile Include="src\Editor\ElementManager.cpp" />
|
||||
<ClCompile Include="src\Editor\ElementPoolWidget.cpp" />
|
||||
<ClCompile Include="src\Editor\GraphicElement.cpp" />
|
||||
<ClCompile Include="src\Editor\LayerManager.cpp" />
|
||||
<ClCompile Include="src\Editor\LayerStyle.cpp" />
|
||||
|
@ -119,9 +121,10 @@
|
|||
<ClCompile Include="src\Editor\ThirdPartyLib\qquick\qquicksvgparser.cpp" />
|
||||
<ClCompile Include="src\Editor\ThirdPartyLib\SvgHelper.cpp" />
|
||||
<ClCompile Include="src\Editor\util\PainterPathUtil.cpp" />
|
||||
<ClCompile Include="src\Editor\util\PaintingUtil.cpp" />
|
||||
<ClCompile Include="src\Editor\util\SvgFileLoader.cpp" />
|
||||
<ClCompile Include="src\FluentMenu.cpp" />
|
||||
<ClCompile Include="src\gl.c" />
|
||||
<ClCompile Include="src\IconWidget.cpp" />
|
||||
<ClCompile Include="src\main.cpp" />
|
||||
<ClCompile Include="src\MainWindow.cpp" />
|
||||
<ClCompile Include="src\NavigationBarWidget.cpp" />
|
||||
|
@ -149,13 +152,11 @@
|
|||
<ClCompile Include="src\Renderer\Painting\StraightLine.cpp" />
|
||||
<ClCompile Include="src\Renderer\VirtualTextureManager.cpp" />
|
||||
<ClCompile Include="src\SvgParser.cpp" />
|
||||
<ClCompile Include="src\TitleWidget.cpp" />
|
||||
<QtUic Include="EditorWidgetItem.ui" />
|
||||
<QtUic Include="FramelessWindow.ui" />
|
||||
<QtUic Include="MainWindow.ui" />
|
||||
<QtUic Include="NavigationBarWidget.ui" />
|
||||
<QtUic Include="RendererWidget.ui" />
|
||||
<QtUic Include="EditorWidget.ui" />
|
||||
<QtUic Include="EditorWidgetItem.ui" />
|
||||
<QtUic Include="MainWindow.ui" />
|
||||
<QtUic Include="RendererWidget.ui" />
|
||||
<QtUic Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.ui" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\data.json" />
|
||||
|
@ -190,7 +191,10 @@
|
|||
<QtMoc Include="src\Editor\RightBar\InfoDisplayWidget.h" />
|
||||
<QtMoc Include="src\MainWindow.h" />
|
||||
<QtMoc Include="src\Editor\EditorWidget.h" />
|
||||
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.h" />
|
||||
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h" />
|
||||
<ClInclude Include="src\Editor\ElementManager.h" />
|
||||
<QtMoc Include="src\Editor\ElementPoolWidget.h" />
|
||||
<ClInclude Include="src\Editor\GraphicElement.h" />
|
||||
<ClInclude Include="src\Editor\LayerManager.h" />
|
||||
<ClInclude Include="src\Editor\LayerStyle.h" />
|
||||
|
@ -201,7 +205,9 @@
|
|||
<ClInclude Include="src\Editor\ThirdPartyLib\qquick\qtquickglobal_p.h" />
|
||||
<ClInclude Include="src\Editor\ThirdPartyLib\SvgHelper.h" />
|
||||
<ClInclude Include="src\Editor\util\PainterPathUtil.h" />
|
||||
<ClInclude Include="src\Editor\util\PaintingUtil.h" />
|
||||
<ClInclude Include="src\Editor\util\SvgFileLoader.h" />
|
||||
<QtMoc Include="src\FluentMenu.h" />
|
||||
<ClInclude Include="src\Renderer\IblUtils.h" />
|
||||
<ClInclude Include="src\Renderer\Painting\BaseStyle.h" />
|
||||
<ClInclude Include="src\Renderer\Painting\CubicBezierSignedDistance.h" />
|
||||
|
@ -214,9 +220,6 @@
|
|||
<ClInclude Include="src\Renderer\Preview\ElementRenderer.h" />
|
||||
<ClInclude Include="src\Renderer\VirtualTextureManager.h" />
|
||||
<ClInclude Include="src\SvgParser.h" />
|
||||
<QtMoc Include="src\TitleWidget.h" />
|
||||
<QtMoc Include="src\IconWidget.h" />
|
||||
<QtMoc Include="src\CaptionButton.h" />
|
||||
<QtMoc Include="src\NavigationBarWidget.h" />
|
||||
<QtMoc Include="src\Renderer\RendererWidget.h" />
|
||||
<QtMoc Include="src\Editor\EditorWidgetItem.h" />
|
||||
|
|
|
@ -70,15 +70,12 @@
|
|||
<QtUic Include="MainWindow.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="NavigationBarWidget.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="FramelessWindow.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="EditorWidget.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Editor\EditorWidgetItem.cpp">
|
||||
|
@ -117,15 +114,6 @@
|
|||
<ClCompile Include="src\NavigationBarWidget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CaptionButton.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\IconWidget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\TitleWidget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Renderer\Painting\BvhTree.cpp">
|
||||
<Filter>Source Files\Renderer\Painting</Filter>
|
||||
</ClCompile>
|
||||
|
@ -219,6 +207,21 @@
|
|||
<ClCompile Include="src\Editor\EditorWidget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Editor\ElementPoolWidget.cpp">
|
||||
<Filter>Source Files\Editor</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\FluentMenu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Editor\util\PaintingUtil.cpp">
|
||||
<Filter>Source Files\Editor\util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="src\Renderer\RendererGLWidget.h">
|
||||
|
@ -233,15 +236,6 @@
|
|||
<QtMoc Include="src\NavigationBarWidget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\CaptionButton.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\IconWidget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\TitleWidget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\MainWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
|
@ -257,6 +251,18 @@
|
|||
<QtMoc Include="src\Editor\EditorWidget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\Editor\ElementPoolWidget.h">
|
||||
<Filter>Header Files\Editor</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\FluentMenu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\data.json" />
|
||||
|
@ -390,9 +396,6 @@
|
|||
<ClInclude Include="src\Editor\GraphicElement.h">
|
||||
<Filter>Header Files\Editor</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Editor\LayerStyle.h">
|
||||
<Filter>Header Files\Editor</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Editor\LayerManager.h">
|
||||
<Filter>Header Files\Editor</Filter>
|
||||
</ClInclude>
|
||||
|
@ -450,6 +453,12 @@
|
|||
<ClInclude Include="src\Renderer\VirtualTextureManager.h">
|
||||
<Filter>Header Files\Renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Editor\util\PaintingUtil.h">
|
||||
<Filter>Header Files\Editor\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Editor\LayerStyle.h">
|
||||
<Filter>Header Files\Editor</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtRcc Include="res\MainWindow.qrc">
|
||||
|
|
|
@ -7,42 +7,53 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1139</width>
|
||||
<height>685</height>
|
||||
<height>862</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,1,1,20">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,20">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1,1,1,1,0">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="createButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
|
@ -61,7 +72,7 @@
|
|||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
|
@ -80,7 +91,7 @@
|
|||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
|
@ -99,7 +110,7 @@
|
|||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
|
@ -115,10 +126,16 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
|
@ -132,13 +149,8 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
|
@ -150,10 +162,21 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>800</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
|
|
|
@ -6,14 +6,23 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1124</width>
|
||||
<height>695</height>
|
||||
<width>1473</width>
|
||||
<height>1103</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>RendererWidget</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -28,53 +37,98 @@
|
|||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="MainWindow" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,30">
|
||||
<item>
|
||||
<widget class="QLabel" name="Title">
|
||||
<property name="text">
|
||||
<string/>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="30">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,18,5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,12,5">
|
||||
<item>
|
||||
<widget class="QWidget" name="LeftBar" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="PreviewWindow" name="Preview"/>
|
||||
<widget class="PreviewWindow" name="Preview">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>1080</width>
|
||||
<height>1080</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>1080</width>
|
||||
<height>1080</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="RightBar" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="1,2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="3,2">
|
||||
<property name="spacing">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="DisplayTab">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="InfoDisplayWidget" name="LayerDisplay">
|
||||
<attribute name="title">
|
||||
<string>Layer</string>
|
||||
<string>图层信息</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="ElementDisplay">
|
||||
<widget class="ElementPoolWidget" name="ElementDisplay">
|
||||
<attribute name="title">
|
||||
<string>Element</string>
|
||||
<string>图元池</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LayerTreeWidget" name="LayerTree">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string/>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
<string>图层树</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
|
@ -107,6 +161,12 @@
|
|||
<header location="global">InfoDisplayWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ElementPoolWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>ElementPoolWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FramelessWindow</class>
|
||||
<widget class="QWidget" name="FramelessWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>560</width>
|
||||
<height>544</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="windowFrame" native="true">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="windowContent" native="true">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindowClass</class>
|
||||
<widget class="QMainWindow" name="MainWindowClass">
|
||||
<widget class="QWidget" name="MainWindowClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@ -10,19 +10,9 @@
|
|||
<height>722</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font: 10pt "Segoe UI, Microsoft YaHei UI";</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
|
@ -40,73 +30,26 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="1">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Segoe UI, Microsoft YaHei UI</family>
|
||||
<pointsize>10</pointsize>
|
||||
<weight>50</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">
|
||||
QTabBar::tab.rendererWidget {
|
||||
height: 0px;
|
||||
margin-top:0px;
|
||||
}
|
||||
QTabWidget::tab-bar.rendererWidget
|
||||
{
|
||||
height: 0px;
|
||||
top:0px;
|
||||
}
|
||||
QTabWidget::pane.rendererWidget {
|
||||
border: 0px;
|
||||
background-color: transparent;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="tabPosition">
|
||||
<enum>QTabWidget::North</enum>
|
||||
</property>
|
||||
<property name="tabShape">
|
||||
<enum>QTabWidget::Rounded</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="elideMode">
|
||||
<enum>Qt::ElideNone</enum>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="tabsClosable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="EditorWidget" name="editorWidget">
|
||||
<attribute name="title">
|
||||
<string>纹理编辑</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="Renderer::RendererWidget" name="rendererWidget">
|
||||
<attribute name="title">
|
||||
<string>场景渲染</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<item row="0" column="0">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<widget class="EditorWidget" name="editorWidget"/>
|
||||
<widget class="Renderer::RendererWidget" name="rendererWidget"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
@ -120,8 +63,6 @@
|
|||
<header>Editor/EditorWidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="MainWindow.qrc"/>
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
17876391417123941155.jpg 0.json 0 0 1 1
|
||||
11474523244911310074.jpg 1.json 0 0 1 1
|
|
@ -1,100 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>NavigationBarWidgetClass</class>
|
||||
<widget class="QWidget" name="NavigationBarWidgetClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>612</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>NavigationBarWidget</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QRadioButton::indicator {
|
||||
width: 0px;
|
||||
border: 0px;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="radioButton0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>纹理编辑</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="radioButton1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>场景渲染</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -13,7 +13,7 @@
|
|||
<property name="windowTitle">
|
||||
<string>RendererWidget</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -31,25 +31,37 @@
|
|||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="openButton">
|
||||
<widget class="QtMaterialFlatButton" name="openButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
<width>50</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>打开</string>
|
||||
<string>文件</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
|
@ -71,34 +83,6 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Ignored">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>打开</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menu"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
|
||||
<property name="sizeConstraint">
|
||||
|
@ -180,6 +164,11 @@
|
|||
<extends>QOpenGLWidget</extends>
|
||||
<header>RendererGLWidget.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QtMaterialFlatButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header location="global">qtmaterialflatbutton.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -1190,7 +1190,7 @@ void main()
|
|||
//imageStore(gBaseColor, pixelLocation, vec4(uv,1,1));
|
||||
//imageStore(gMetallicRoughness, pixelLocation, vec4(uv,1,1));
|
||||
//return;
|
||||
uv = vec2(1)-uv*2;
|
||||
uv = uv*2-vec2(1);
|
||||
//vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg;
|
||||
|
||||
vec3 debugBVH = vec3(0);
|
||||
|
|
|
@ -1,261 +0,0 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2018-2022 Antonio Dias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "CaptionButton.h"
|
||||
|
||||
CaptionButton::CaptionButton(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
m_is_active = false;
|
||||
m_is_under_mouse = false;
|
||||
m_is_pressed = false;
|
||||
m_icon_dark = false;
|
||||
|
||||
setAttribute(Qt::WA_Hover);
|
||||
}
|
||||
|
||||
CaptionButton::~CaptionButton()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QPixmap CaptionButton::drawIcon(const QPixmap &icon, bool active, bool force_light)
|
||||
{
|
||||
QImage tmp = icon.toImage();
|
||||
|
||||
if (!active)
|
||||
{
|
||||
for (int i = 0; i < tmp.height(); i++)
|
||||
{
|
||||
for (int j = 0; j < tmp.width(); j++)
|
||||
{
|
||||
QColor pixel = QColor::fromRgba(tmp.pixel(j, i));
|
||||
|
||||
pixel.setRedF(pixel.redF() * 0.5f);
|
||||
pixel.setGreenF(pixel.greenF() * 0.5f);
|
||||
pixel.setBlueF(pixel.blueF() * 0.5f);
|
||||
|
||||
tmp.setPixel(j, i, pixel.rgba());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_icon_dark && !force_light)
|
||||
tmp.invertPixels();
|
||||
|
||||
return QPixmap::fromImage(tmp);
|
||||
}
|
||||
|
||||
void CaptionButton::init(IconType type)
|
||||
{
|
||||
m_type = type;
|
||||
|
||||
setColors();
|
||||
drawIcons();
|
||||
}
|
||||
|
||||
void CaptionButton::drawIcons()
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case IconType::Minimize:
|
||||
{
|
||||
QPixmap icon = QPixmap(":/images/icon_window_minimize.png");
|
||||
|
||||
m_active_icon = drawIcon(icon, true);
|
||||
m_inactive_icon = drawIcon(icon, false);
|
||||
|
||||
break;
|
||||
}
|
||||
case IconType::Restore:
|
||||
{
|
||||
QPixmap icon = QPixmap(":/images/icon_window_restore.png");
|
||||
|
||||
m_active_icon = drawIcon(icon, true);
|
||||
m_inactive_icon = drawIcon(icon, false);
|
||||
|
||||
break;
|
||||
}
|
||||
case IconType::Maximize:
|
||||
{
|
||||
QPixmap icon = QPixmap(":/images/icon_window_maximize.png");
|
||||
|
||||
m_active_icon = drawIcon(icon, true);
|
||||
m_inactive_icon = drawIcon(icon, false);
|
||||
|
||||
break;
|
||||
}
|
||||
case IconType::Close:
|
||||
{
|
||||
QPixmap icon = QPixmap(":/images/icon_window_close.png");
|
||||
|
||||
m_active_icon = drawIcon(icon, true);
|
||||
m_inactive_icon = drawIcon(icon, false);
|
||||
m_close_icon_hover = drawIcon(icon, true, true);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CaptionButton::setColors()
|
||||
{
|
||||
if (m_icon_dark)
|
||||
{
|
||||
if (m_type == IconType::Close)
|
||||
{
|
||||
m_normal = QColor("transparent");
|
||||
m_hover = QColor("#F00000");
|
||||
m_pressed = QColor("#F1707A");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_normal = QColor("transparent");
|
||||
m_hover = QColor("#E5E5E5");
|
||||
m_pressed = QColor("#CACACB");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_type == IconType::Close)
|
||||
{
|
||||
m_normal = QColor("transparent");
|
||||
m_hover = QColor("#F00000");
|
||||
m_pressed = QColor("#F1707A");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_normal = QColor("transparent");
|
||||
m_hover = QColor("#505050");
|
||||
m_pressed = QColor("#3F3F3F");
|
||||
}
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void CaptionButton::setIconMode(bool icon_dark)
|
||||
{
|
||||
m_icon_dark = icon_dark;
|
||||
|
||||
drawIcons();
|
||||
setColors();
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void CaptionButton::setActive(bool is_active)
|
||||
{
|
||||
m_is_active = is_active;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void CaptionButton::setState(int state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case QEvent::HoverEnter:
|
||||
{
|
||||
m_is_under_mouse = true;
|
||||
|
||||
repaint();
|
||||
|
||||
break;
|
||||
}
|
||||
case QEvent::HoverLeave:
|
||||
{
|
||||
m_is_under_mouse = false;
|
||||
|
||||
repaint();
|
||||
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonPress:
|
||||
{
|
||||
m_is_pressed = true;
|
||||
|
||||
m_is_under_mouse = true;
|
||||
|
||||
repaint();
|
||||
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonRelease:
|
||||
{
|
||||
m_is_pressed = false;
|
||||
|
||||
m_is_under_mouse = false;
|
||||
|
||||
repaint();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CaptionButton::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
QPixmap current_icon = m_active_icon;
|
||||
QColor current_color = m_normal;
|
||||
|
||||
//Change icon if needed
|
||||
if (m_is_under_mouse)
|
||||
{
|
||||
if (m_type == IconType::Close)
|
||||
current_icon = m_close_icon_hover;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_is_active)
|
||||
current_icon = m_inactive_icon;
|
||||
}
|
||||
|
||||
//Change background color if needed
|
||||
if (m_is_pressed)
|
||||
{
|
||||
if (m_is_under_mouse)
|
||||
current_color = m_pressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_is_under_mouse)
|
||||
current_color = m_hover;
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
|
||||
painter.fillRect(rect(), current_color);
|
||||
|
||||
QRect target_rect;
|
||||
target_rect = current_icon.rect();
|
||||
target_rect.setSize(QSize(16, 16));
|
||||
target_rect = QRect(rect().center() - target_rect.center(), target_rect.size());
|
||||
painter.drawPixmap(target_rect, current_icon);
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2018-2022 Antonio Dias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CAPTIONBUTTON_H
|
||||
#define CAPTIONBUTTON_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
|
||||
class CaptionButton : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CaptionButton(QWidget *parent = nullptr);
|
||||
~CaptionButton();
|
||||
|
||||
enum class IconType
|
||||
{
|
||||
Minimize,
|
||||
Restore,
|
||||
Maximize,
|
||||
Close
|
||||
};
|
||||
|
||||
void init(IconType type);
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
|
||||
public slots:
|
||||
void setIconMode(bool icon_dark);
|
||||
void setActive(bool is_active);
|
||||
void setState(int state);
|
||||
|
||||
private:
|
||||
//Functions
|
||||
QPixmap drawIcon(const QPixmap &icon, bool active, bool force_light = false);
|
||||
void setColors();
|
||||
void drawIcons();
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
//Variables
|
||||
QPixmap m_inactive_icon;
|
||||
QPixmap m_active_icon;
|
||||
|
||||
QPixmap m_close_icon_hover;
|
||||
|
||||
QColor m_normal;
|
||||
QColor m_hover;
|
||||
QColor m_pressed;
|
||||
|
||||
IconType m_type;
|
||||
bool m_is_active;
|
||||
bool m_is_under_mouse;
|
||||
bool m_is_pressed;
|
||||
bool m_icon_dark;
|
||||
};
|
||||
|
||||
#endif // CAPTIONBUTTON_H
|
|
@ -0,0 +1,54 @@
|
|||
#include "LayerCreateWidget.h"
|
||||
#include <QComboBox>
|
||||
|
||||
LayerCreateWidget::LayerCreateWidget(ElementManager* elementManager, QWidget* parent) :
|
||||
QDialog(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(ui.comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
|
||||
elementPool = new ElementPoolWidget(ui.elementPool);
|
||||
elementPool->setElementList(elementManager->elements);
|
||||
}
|
||||
|
||||
LayerCreateWidget::~LayerCreateWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void LayerCreateWidget::accept()
|
||||
{
|
||||
QJsonObject jsonObj;
|
||||
jsonObj.insert("name", ui.name->text());
|
||||
if (ui.comboBox->currentIndex() == 0) {
|
||||
jsonObj.insert("is-folder", false);
|
||||
jsonObj.insert("element", elementPool->currentIndex);
|
||||
}
|
||||
else {
|
||||
jsonObj.insert("is-folder", true);
|
||||
jsonObj.insert("children", QJsonArray());
|
||||
}
|
||||
QJsonObject transform;
|
||||
QJsonObject offset;
|
||||
QJsonObject scale;
|
||||
scale.insert("x", 1);
|
||||
scale.insert("y", 1);
|
||||
offset.insert("x", 0);
|
||||
offset.insert("y", 0);
|
||||
transform.insert("offset", offset);
|
||||
transform.insert("scale", scale);
|
||||
transform.insert("rotation", 0);
|
||||
jsonObj.insert("transform", transform);
|
||||
jsonObj.insert("referenced-by", QJsonValue());
|
||||
emit LayerInfoReturned(jsonObj);
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void LayerCreateWidget::onCurrentIndexChanged(int index) {
|
||||
if (index == 0) {// leaf layer
|
||||
elementPool->setVisible(true);
|
||||
}
|
||||
else {// folder layer
|
||||
elementPool->setVisible(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
#include <QDialog>
|
||||
#include <QJsonObject>
|
||||
#include "ElementPoolWidget.h"
|
||||
#include "ElementManager.h"
|
||||
#include "ui_LayerCreateWidget.h"
|
||||
|
||||
class LayerCreateWidget :
|
||||
public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Ui::LayerCreateWidget ui;
|
||||
ElementPoolWidget* elementPool;
|
||||
|
||||
|
||||
public:
|
||||
LayerCreateWidget(ElementManager* elementManager,QWidget* parent = nullptr);
|
||||
~LayerCreateWidget();
|
||||
void accept() override;
|
||||
|
||||
public slots:
|
||||
void onCurrentIndexChanged(int index);
|
||||
|
||||
signals:
|
||||
void LayerInfoReturned(QJsonObject jsonObj);
|
||||
};
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LayerCreateWidget</class>
|
||||
<widget class="QWidget" name="LayerCreateWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>326</width>
|
||||
<height>355</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,5,1,0">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maxCount">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::NoInsert</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>叶子节点</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>组合节点</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>图层名:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="name"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="elementPool" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,88 @@
|
|||
#include "LayerStyleDialog.h"
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QDebug>
|
||||
#include <unordered_set>
|
||||
|
||||
LayerStyleDialog::LayerStyleDialog(
|
||||
QWidget* parent,
|
||||
std::shared_ptr<LayerStyle> existedStyle,
|
||||
std::vector<std::shared_ptr<LayerStyle>>* excludeStyles
|
||||
) : QDialog(parent)
|
||||
{
|
||||
QVBoxLayout* dialogLayout = new QVBoxLayout(this);
|
||||
dialogLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter);
|
||||
this->setLayout(dialogLayout);
|
||||
|
||||
if (existedStyle)
|
||||
{
|
||||
this->modifyingStyle = existedStyle->clonePtr();
|
||||
|
||||
this->styleContainer = nullptr;
|
||||
this->styleWidget = modifyingStyle->getInputWidget();
|
||||
this->styleWidget->setParent(this);
|
||||
dialogLayout->addWidget(styleWidget);
|
||||
// do something
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unordered_set<QString> excludeStyleNames;
|
||||
for(auto &style : *excludeStyles)
|
||||
{
|
||||
excludeStyleNames.insert(style->getStyleName());
|
||||
}
|
||||
|
||||
QComboBox* typeSelector = new QComboBox(this);
|
||||
|
||||
for (auto& pair : LayerStyle::types)
|
||||
{
|
||||
if (!excludeStyleNames.contains(pair.first))
|
||||
{
|
||||
typeSelector->addItem(pair.first);
|
||||
if (!this->modifyingStyle)
|
||||
{
|
||||
this->modifyingStyle = std::move(pair.second());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeSelector->count() > 0)
|
||||
{
|
||||
dialogLayout->addWidget(typeSelector);
|
||||
this->styleContainer = new QGridLayout(this);
|
||||
dialogLayout->addLayout(styleContainer);
|
||||
|
||||
this->styleWidget = this->modifyingStyle->getInputWidget();
|
||||
this->styleWidget->setParent(this);
|
||||
this->styleContainer->addWidget(styleWidget);
|
||||
connect(typeSelector, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &LayerStyleDialog::onStyleTypeSelectorChanged);
|
||||
}
|
||||
}
|
||||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &LayerStyleDialog::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &LayerStyleDialog::reject);
|
||||
dialogLayout->addWidget(buttonBox);
|
||||
}
|
||||
|
||||
void LayerStyleDialog::accept()
|
||||
{
|
||||
this->layerStyle = std::move(this->modifyingStyle);
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void LayerStyleDialog::onStyleTypeSelectorChanged(int index)
|
||||
{
|
||||
if (this->styleWidget)
|
||||
{
|
||||
this->styleContainer->removeWidget(this->styleWidget);
|
||||
this->styleWidget->setParent(nullptr);
|
||||
delete styleWidget;
|
||||
}
|
||||
this->modifyingStyle = std::move(LayerStyle::types[index].second());
|
||||
this->styleWidget = this->modifyingStyle->getInputWidget();
|
||||
this->styleWidget->setParent(this);
|
||||
this->styleContainer->addWidget(styleWidget, 0, 0, 1, 1);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include "LayerStyle.h"
|
||||
#include <QDialog>
|
||||
#include <QGridLayout>
|
||||
|
||||
class LayerStyleDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QWidget* styleWidget;
|
||||
QGridLayout* styleContainer;
|
||||
std::unique_ptr<LayerStyle> modifyingStyle;
|
||||
public:
|
||||
LayerStyleDialog(
|
||||
QWidget* parent = nullptr,
|
||||
std::shared_ptr<LayerStyle> existedStyle = nullptr,
|
||||
std::vector<std::shared_ptr<LayerStyle>>* excludeStyles = nullptr);
|
||||
std::shared_ptr<LayerStyle> layerStyle;
|
||||
private slots:
|
||||
void onStyleTypeSelectorChanged(int index);
|
||||
void accept() override;
|
||||
};
|
||||
|
|
@ -11,7 +11,13 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p
|
|||
tabWidget = ui.DisplayTab;
|
||||
this->filePath = filePath;
|
||||
layerInfoDisplayWidget = dynamic_cast<InfoDisplayWidget *>(tabWidget->widget(0));
|
||||
elementInfoDisplayWidget = dynamic_cast<InfoDisplayWidget *>(tabWidget->widget(1));
|
||||
elementInfoDisplayWidget = dynamic_cast<ElementPoolWidget *>(tabWidget->widget(1));
|
||||
qDebug() << layerInfoDisplayWidget;
|
||||
qDebug() << elementInfoDisplayWidget;
|
||||
connect(previewWindow, &PreviewWindow::layerInfoChanged, layerInfoDisplayWidget, &InfoDisplayWidget::triggerSelfRefresh);
|
||||
connect(treeWidget, &LayerTreeWidget::displayLayerChange, previewWindow, &PreviewWindow::currentLayerChanged);
|
||||
connect(treeWidget, &LayerTreeWidget::requireRefreshElementWidget, elementInfoDisplayWidget, &ElementPoolWidget::refresh);
|
||||
connect(layerInfoDisplayWidget, &InfoDisplayWidget::requireRefreshElementWidget, elementInfoDisplayWidget, &ElementPoolWidget::refresh);
|
||||
connect(treeWidget, &LayerTreeWidget::displayLayerChange, this, &EditorWidgetItem::onLayerChange);
|
||||
connect(layerInfoDisplayWidget, &InfoDisplayWidget::requireRefreshPreview, this,
|
||||
&EditorWidgetItem::triggerRefreshPreview);
|
||||
|
@ -33,8 +39,12 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p
|
|||
QJsonObject source = jsonDoc.object();
|
||||
elementManager = new ElementManager(source,previewWindow->getRenderer());
|
||||
layerManager = new LayerManager(source, elementManager);
|
||||
elementInfoDisplayWidget->setElementManager(elementManager);
|
||||
treeWidget->elementManager = elementManager;
|
||||
qDebug() << layerManager->toJson();
|
||||
previewWindow->initialize(layerManager,QSize(jsonDoc.object().value("width").toDouble(),jsonDoc.object().value("height").toDouble()));
|
||||
|
||||
|
||||
if (layerManager->getRoot() != nullptr)
|
||||
{
|
||||
treeWidget->root = layerManager->getRoot();
|
||||
|
@ -49,6 +59,11 @@ EditorWidgetItem::~EditorWidgetItem()
|
|||
|
||||
void EditorWidgetItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
// 设置画刷的颜色为灰色,并填充整个窗口区域
|
||||
painter.setBrush(Qt::gray);
|
||||
painter.drawRect(this->rect());
|
||||
}
|
||||
|
||||
void EditorWidgetItem::onLayerChange(LayerWrapper *layer)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "ElementManager.h"
|
||||
#include "ElementPoolWidget.h"
|
||||
#include "InfoDisplayWidget.h"
|
||||
#include "LayerManager.h"
|
||||
#include "LayerTreeWidget.h"
|
||||
|
@ -23,7 +24,8 @@ class EditorWidgetItem : public QWidget
|
|||
Ui::EditorWidgetItem ui;
|
||||
LayerTreeWidget *treeWidget;
|
||||
QTabWidget *tabWidget;
|
||||
InfoDisplayWidget *layerInfoDisplayWidget, *elementInfoDisplayWidget;
|
||||
InfoDisplayWidget* layerInfoDisplayWidget;
|
||||
ElementPoolWidget* elementInfoDisplayWidget;
|
||||
// QT DATA PART
|
||||
LayerWrapper *displayLayer;
|
||||
GraphicElement *displayElement;
|
||||
|
|
|
@ -10,7 +10,7 @@ ElementManager::ElementManager(QJsonObject source,Renderer::ElementRenderer* ren
|
|||
elements.push_back(new GroupElement());
|
||||
else
|
||||
elements.push_back(new SimpleElement(elementJson.toObject()));
|
||||
|
||||
(*elements.rbegin())->name = elementJson.toObject().value("name").toString();
|
||||
(*elements.rbegin())->renderer = renderer;
|
||||
}
|
||||
for (auto element : elements)
|
||||
|
@ -19,10 +19,19 @@ ElementManager::ElementManager(QJsonObject source,Renderer::ElementRenderer* ren
|
|||
|
||||
void ElementManager::addElement(GraphicElement *element)
|
||||
{
|
||||
this->elements.push_back(element);
|
||||
}
|
||||
|
||||
void ElementManager::removeElement(GraphicElement *pElement)
|
||||
{
|
||||
for (auto& element : elements)
|
||||
{
|
||||
if (element == pElement)
|
||||
{
|
||||
elements.erase(std::find(elements.begin(), elements.end(), element));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GraphicElement *ElementManager::getElementById(int index)
|
||||
|
@ -46,3 +55,48 @@ QJsonObject ElementManager::toJson() const
|
|||
result.insert("elements", elementsJson);
|
||||
return result;
|
||||
}
|
||||
|
||||
int ElementManager::getElementIndex(GraphicElement* pelement)
|
||||
{
|
||||
for (int i = 0; i < elements.size(); i++)
|
||||
if (elements[i] == pelement)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ElementManager::getLayerReferencedBy(const FolderLayerWrapper* layer)
|
||||
{
|
||||
for (int i = 0; i < elements.size(); i++)
|
||||
if (typeid(*elements[i]) == typeid(GroupElement)) {
|
||||
qDebug() << ((GroupElement*)elements[i])->sourceLayer;
|
||||
qDebug() << layer;
|
||||
qDebug() << "------------";
|
||||
if (((GroupElement*)elements[i])->sourceLayer == layer)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void ElementManager::removeElement(int index)
|
||||
{
|
||||
if (index < elements.size())
|
||||
elements.erase(elements.begin() + index);
|
||||
}
|
||||
|
||||
void ElementManager::createGroupElement(QString name, FolderLayerWrapper* sourceLayer) {
|
||||
auto element = new GroupElement();
|
||||
element->name = name;
|
||||
element->setSourceLayer(sourceLayer);
|
||||
addElement(element);
|
||||
}
|
||||
void ElementManager::createSimpleElement(QString name, QString filePath) {
|
||||
QJsonObject json;
|
||||
QJsonObject data;
|
||||
data.insert("include", filePath);
|
||||
json.insert("data", data);
|
||||
auto element = new SimpleElement(json);
|
||||
element->name = name;
|
||||
addElement(element);
|
||||
}
|
|
@ -8,10 +8,11 @@ using std::vector;
|
|||
class LayerManager;
|
||||
class GraphicElement;
|
||||
class Renderer::ElementRenderer;
|
||||
class FolderLayerWrapper;
|
||||
|
||||
class ElementManager
|
||||
{
|
||||
private:
|
||||
public:
|
||||
vector<GraphicElement *> elements;
|
||||
|
||||
public:
|
||||
|
@ -19,9 +20,14 @@ class ElementManager
|
|||
~ElementManager();
|
||||
void addElement(GraphicElement *element);
|
||||
void removeElement(GraphicElement *pElement);
|
||||
void removeElement(int index);
|
||||
void createGroupElement(QString name, FolderLayerWrapper* sourceLayer);
|
||||
void createSimpleElement(QString name, QString filePath);
|
||||
QJsonObject toJson()const;
|
||||
/**
|
||||
* only used in initialization
|
||||
*/
|
||||
GraphicElement *getElementById(int index);
|
||||
int getElementIndex(GraphicElement* pElement);
|
||||
int getLayerReferencedBy(const FolderLayerWrapper* layer);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
#include "ElementPoolWidget.h"
|
||||
|
||||
ElementPoolWidget::ElementPoolWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
elementManager = nullptr;
|
||||
iconWidth = 120, iconHeight = 90;
|
||||
pictureList = new QListWidget();
|
||||
pictureList->setIconSize(QSize(iconWidth, iconHeight));
|
||||
pictureList->setWindowFlags(Qt::FramelessWindowHint);
|
||||
pictureList->setResizeMode(QListWidget::Adjust);
|
||||
pictureList->setViewMode(QListWidget::IconMode);
|
||||
pictureList->setMovement(QListWidget::Static);
|
||||
pictureList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
pictureList->setWrapping(true);
|
||||
pictureList->setSpacing(5);
|
||||
pictureList->setStyleSheet("QListWidget::Item:hover{background-color: #f5f5f5;border-radius:5px; }"
|
||||
"QListWidget::item:selected{background-color:rgba(234,234,234,1);color:rgb(61,61,61);border:1px solid #778899;border-radius:2px; }"
|
||||
"QScrollBar:vertical{width:6px}"
|
||||
"QListWidget{outline:none;border:0px}");
|
||||
pictureList->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
QLayout* layout = new QHBoxLayout();
|
||||
layout->addWidget(pictureList);
|
||||
setLayout(layout);
|
||||
//pictureList->setFixedSize(600, 800);
|
||||
|
||||
connect(pictureList, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(pictureItemClicked(QListWidgetItem*)));
|
||||
}
|
||||
|
||||
void ElementPoolWidget::setElementList(std::vector<GraphicElement*> elements) {
|
||||
pictureList->clear();
|
||||
this->elements = elements;
|
||||
for (int index = 0; index < elements.size(); index++) {
|
||||
//
|
||||
//QString strPath = QString("C:\\Users\\86177\\Pictures\\Screenshots\\test.png");
|
||||
//QPixmap itemPixmap(strPath);
|
||||
//QPixmap itemPixmap(QSize(200, 200));
|
||||
//itemPixmap.fill(Qt::red);
|
||||
QPixmap itemPixmap = elements[index]->getPaintObject().getDetail();
|
||||
qDebug() << this->parentWidget()->size();
|
||||
//auto p = new QWidget();
|
||||
//auto lb = new QLabel(p);
|
||||
//lb->setPixmap(itemPixmap);
|
||||
//lb->setFixedSize(1920, 1080);
|
||||
//p->setFixedSize(1920, 1080);
|
||||
//lb->show();
|
||||
//p->show();
|
||||
|
||||
QListWidgetItem* pItem = new QListWidgetItem(
|
||||
itemPixmap.scaled(QSize(iconWidth - 25, iconHeight - 25)),
|
||||
elements[index]->name);
|
||||
pItem->setSizeHint(QSize(iconWidth, iconHeight));
|
||||
pictureList->insertItem(index, pItem);
|
||||
}
|
||||
if(elements.size() > 0)
|
||||
pictureList->setCurrentRow(0),
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
ElementPoolWidget::~ElementPoolWidget() {
|
||||
|
||||
}
|
||||
|
||||
int ElementPoolWidget::pictureItemClicked(QListWidgetItem* item) {
|
||||
//qDebug() << pictureList->currentRow();
|
||||
currentIndex = pictureList->currentRow();
|
||||
emit elementSelected(this->elements[pictureList->currentRow()]);
|
||||
return pictureList->currentRow();
|
||||
}
|
||||
|
||||
void ElementPoolWidget::setElementManager(ElementManager* element)
|
||||
{
|
||||
this->elementManager = element;
|
||||
this->setElementList(this->elementManager->elements);
|
||||
}
|
||||
|
||||
void ElementPoolWidget::refresh() {
|
||||
this->setElementList(this->elementManager->elements);
|
||||
// update();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <vector>
|
||||
#include <GraphicElement.h>
|
||||
#include <QListWidget>
|
||||
#include <ElementManager.h>
|
||||
#include <QLayout>
|
||||
|
||||
class ElementPoolWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
std::vector<GraphicElement*> elements;
|
||||
QListWidget* pictureList;
|
||||
int iconWidth, iconHeight;
|
||||
ElementManager* elementManager;
|
||||
|
||||
public:
|
||||
int currentIndex = -1;
|
||||
ElementPoolWidget(QWidget* parent = nullptr);
|
||||
void setElementList(std::vector<GraphicElement*> elementList);
|
||||
void setElementManager(ElementManager* element);
|
||||
~ElementPoolWidget();
|
||||
|
||||
signals:
|
||||
void elementSelected(GraphicElement* element);
|
||||
|
||||
public slots:
|
||||
int pictureItemClicked(QListWidgetItem* item);
|
||||
void refresh();
|
||||
};
|
||||
|
|
@ -43,10 +43,11 @@ PixelPath GroupElement::getPaintObject() const
|
|||
}
|
||||
|
||||
//TODO: apply styles and send back
|
||||
PixelPath SimpleElement::getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo> styles) const {
|
||||
PixelPath SimpleElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
|
||||
PixelPath result;
|
||||
Renderer::ElementStyleStrokeDemo demo(2);
|
||||
auto [img, mov] = renderer->drawElement(painterPath, demo, 1.0, false);
|
||||
auto [img, mov] = renderer->drawElement(painterPath, demo, 1.0);
|
||||
//qDebug() << mov;
|
||||
//qDebug() << img << " ------";
|
||||
result.addImage(img, mov);
|
||||
//result.addPath(painterPath);
|
||||
|
@ -59,7 +60,7 @@ PixelPath SimpleElement::getPaintObject(std::vector<Renderer::ElementStyleStroke
|
|||
return result;
|
||||
}
|
||||
|
||||
PixelPath GroupElement::getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo> styles) const {
|
||||
PixelPath GroupElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
|
||||
return getPaintObject();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "LayerWrapper.h"
|
||||
#include "LayerStyle.h"
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QPainterPath>
|
||||
|
@ -26,7 +27,7 @@ public:
|
|||
// TODO: ¸ÄΪBitmapPath
|
||||
virtual QJsonObject toJson() const;
|
||||
virtual PixelPath getPaintObject() const = 0;
|
||||
virtual PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const = 0;
|
||||
virtual PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const = 0;
|
||||
};
|
||||
|
||||
class SimpleElement : public GraphicElement
|
||||
|
@ -39,9 +40,10 @@ private:
|
|||
|
||||
public:
|
||||
SimpleElement(QJsonObject jsonSource);
|
||||
SimpleElement(QString filePath);
|
||||
~SimpleElement() = default;
|
||||
PixelPath getPaintObject() const override;
|
||||
PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const override;
|
||||
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
|
||||
};
|
||||
|
||||
class GroupElement : public GraphicElement
|
||||
|
@ -54,7 +56,7 @@ public:
|
|||
GroupElement(FolderLayerWrapper* mSourceLayer);
|
||||
~GroupElement() = default;
|
||||
PixelPath getPaintObject() const override;
|
||||
PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const override;
|
||||
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
|
||||
void setSourceLayer(FolderLayerWrapper* sourceLayer);
|
||||
};
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@ LayerWrapper *LayerManager::getRoot() const
|
|||
{
|
||||
return root;
|
||||
}
|
||||
void LayerManager::paint(QPainter *painter, QSize size) const
|
||||
void LayerManager::paint(QPainter *painter, QSize size,LayerWrapper* selecetedLayer) const
|
||||
{
|
||||
auto p = root->getCache().resizedPixel(size);
|
||||
painter->drawPixmap(0, 0, p);
|
||||
root->getCache();
|
||||
root->paint(painter);
|
||||
}
|
||||
bool LayerManager::singleSelectedCheck() const
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ class LayerManager
|
|||
LayerManager() = default;
|
||||
LayerManager(QJsonObject source, ElementManager* elementManager);
|
||||
QJsonObject toJson() const;
|
||||
void paint(QPainter *painter, QSize size) const;
|
||||
void paint(QPainter *painter, QSize size, LayerWrapper* selecetedLayer=nullptr) const;
|
||||
bool rename(QString newName) const;
|
||||
bool combine() const;
|
||||
// bool seperate() const;
|
||||
|
|
|
@ -1,6 +1,103 @@
|
|||
#include "LayerStyle.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
std::vector<Renderer::BaseStyle> StrokeElementStyle::toBaseStyles() const
|
||||
const std::vector<std::pair<QString, std::function<std::unique_ptr<LayerStyle>()>>> LayerStyle::types = {
|
||||
{
|
||||
QStringLiteral("Ãè±ß"),
|
||||
[]() { return std::make_unique<StrokeElementLayerStyle>(); }
|
||||
},
|
||||
{
|
||||
QStringLiteral("Ìî³ä"),
|
||||
[]() { return std::make_unique<FillElementLayerStyle>(); }
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<Renderer::BaseStyle> StrokeElementLayerStyle::toBaseStyles() const
|
||||
{
|
||||
return std::vector<Renderer::BaseStyle>();
|
||||
}
|
||||
|
||||
QString StrokeElementLayerStyle::getStyleName() const
|
||||
{
|
||||
return QStringLiteral("Ãè±ß");
|
||||
}
|
||||
|
||||
QWidget* StrokeElementLayerStyle::getInputWidget() const
|
||||
{
|
||||
// TODO
|
||||
QLabel* le = new QLabel;
|
||||
le->setText(QStringLiteral("Ãè±ß"));
|
||||
return le;
|
||||
}
|
||||
|
||||
QWidget* StrokeElementLayerStyle::getListDisplayWidget() const
|
||||
{
|
||||
QWidget* w = new QWidget;
|
||||
QLabel* name = new QLabel(w);
|
||||
name->setText(QStringLiteral("Ãè±ß"));
|
||||
QHBoxLayout* layout = new QHBoxLayout(w);
|
||||
layout->setMargin(0);
|
||||
layout->addWidget(name);
|
||||
return w;
|
||||
}
|
||||
|
||||
StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other)
|
||||
{
|
||||
materialStyles = std::vector<std::shared_ptr<Renderer::MaterialStyleStroke>>(other.materialStyles.size());
|
||||
for (size_t i = 0; i < other.materialStyles.size(); i++)
|
||||
{
|
||||
materialStyles[i] = std::make_shared<Renderer::MaterialStyleStroke>(*other.materialStyles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<LayerStyle> StrokeElementLayerStyle::clonePtr() const
|
||||
{
|
||||
return std::make_unique<StrokeElementLayerStyle>(StrokeElementLayerStyle(*this));
|
||||
}
|
||||
|
||||
std::vector<Renderer::BaseStyle> FillElementLayerStyle::toBaseStyles() const
|
||||
{
|
||||
return std::vector<Renderer::BaseStyle>();
|
||||
}
|
||||
|
||||
QString FillElementLayerStyle::getStyleName() const
|
||||
{
|
||||
return QStringLiteral("Ìî³ä");
|
||||
}
|
||||
|
||||
QWidget* FillElementLayerStyle::getInputWidget() const
|
||||
{
|
||||
// TODO
|
||||
QLineEdit* name = new QLineEdit;
|
||||
name->setText(QStringLiteral("Ìî³ä"));
|
||||
return name;
|
||||
}
|
||||
|
||||
QWidget* FillElementLayerStyle::getListDisplayWidget() const
|
||||
{
|
||||
QWidget* w = new QWidget;
|
||||
QLabel* name = new QLabel(w);
|
||||
name->setText(QStringLiteral("Ìî³ä"));
|
||||
QHBoxLayout* layout = new QHBoxLayout(w);
|
||||
layout->setMargin(0);
|
||||
layout->addWidget(name);
|
||||
return w;
|
||||
}
|
||||
|
||||
FillElementLayerStyle::FillElementLayerStyle(const FillElementLayerStyle& other)
|
||||
{
|
||||
materialStyles = std::vector<std::shared_ptr<Renderer::MaterialStyleFill>>(other.materialStyles.size());
|
||||
for (size_t i = 0; i < other.materialStyles.size(); i++)
|
||||
{
|
||||
materialStyles[i] = std::make_shared<Renderer::MaterialStyleFill>(*other.materialStyles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<LayerStyle> FillElementLayerStyle::clonePtr() const
|
||||
{
|
||||
return std::make_unique<FillElementLayerStyle>(FillElementLayerStyle(*this));
|
||||
}
|
||||
|
|
|
@ -1,24 +1,56 @@
|
|||
#pragma once
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <QWidget>
|
||||
#include <QObject>
|
||||
#include <QListWidget>
|
||||
#include "../Renderer/Painting/ElementStyle.h"
|
||||
#include "../Renderer/Painting/MaterialStyleStroke.h"
|
||||
#include "../Renderer/Painting/MaterialStyleFill.h"
|
||||
|
||||
/**
|
||||
* 在进行Style的添加时,首先创建空对象,然后直接调用getInputWidget()方法
|
||||
* 在进行Style的修改时,直接调用getInputWidget()方法
|
||||
*
|
||||
* 对于LayerStyle的实现类,应该同时实现ElementStyle,并将相同种类的(如描边或填充)的style整合成一个类,
|
||||
* 对于相同的类,一个图层应该只拥有一个
|
||||
*/
|
||||
class LayerStyle
|
||||
{
|
||||
public:
|
||||
virtual void apply() = 0;
|
||||
public:
|
||||
const static std::vector<std::pair<QString, std::function<std::unique_ptr<LayerStyle>()>>> types;
|
||||
virtual QString getStyleName() const = 0;
|
||||
virtual QWidget* getInputWidget() const = 0;
|
||||
virtual QWidget* getListDisplayWidget() const = 0;
|
||||
virtual ~LayerStyle() {};
|
||||
virtual std::unique_ptr<LayerStyle> clonePtr() const = 0;
|
||||
};
|
||||
|
||||
struct EditorStrokeMaterialStyle
|
||||
{
|
||||
float applyWidth;
|
||||
Renderer::StrokeType strokeType;
|
||||
Renderer::StrokeEndType endType;
|
||||
std::shared_ptr<Renderer::MaterialStroke> materialStroke;
|
||||
};
|
||||
|
||||
class StrokeElementStyle : Renderer::ElementStyle
|
||||
class StrokeElementLayerStyle : public Renderer::ElementStyle, public LayerStyle
|
||||
{
|
||||
public:
|
||||
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
||||
std::vector<EditorStrokeMaterialStyle> materialStyles;
|
||||
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
||||
QString getStyleName() const override;
|
||||
QWidget* getInputWidget() const override;
|
||||
QWidget* getListDisplayWidget() const override;
|
||||
StrokeElementLayerStyle() = default;
|
||||
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
|
||||
~StrokeElementLayerStyle() = default;
|
||||
std::vector<std::shared_ptr<Renderer::MaterialStyleStroke>> materialStyles;
|
||||
std::unique_ptr<LayerStyle> clonePtr() const override;
|
||||
};
|
||||
|
||||
class FillElementLayerStyle : public Renderer::ElementStyle, public LayerStyle
|
||||
{
|
||||
public:
|
||||
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
||||
QString getStyleName() const override;
|
||||
QWidget* getInputWidget() const override;
|
||||
QWidget* getListDisplayWidget() const override;
|
||||
FillElementLayerStyle() = default;
|
||||
FillElementLayerStyle(const FillElementLayerStyle& other);
|
||||
~FillElementLayerStyle() = default;
|
||||
std::vector<std::shared_ptr<Renderer::MaterialStyleFill>> materialStyles;
|
||||
std::unique_ptr<LayerStyle> clonePtr() const override;
|
||||
};
|
|
@ -23,16 +23,22 @@ FolderLayerWrapper*LayerWrapper::getParent() const
|
|||
return this == nullptr ? nullptr : this->parent;
|
||||
}
|
||||
|
||||
PixelPath LayerWrapper::getCache()
|
||||
PixelPath LayerWrapper::getCache(LayerWrapper* selectedLayer)
|
||||
{
|
||||
this->refresh();
|
||||
this->refresh(selectedLayer);
|
||||
if (selectedLayer == this)
|
||||
{
|
||||
this->cache.highLight();
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
// TODO: undone
|
||||
LayerWrapper::LayerWrapper(QJsonObject json, FolderLayerWrapper*parent)
|
||||
LayerWrapper::LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager)
|
||||
{
|
||||
this->parent = parent;
|
||||
this->elementManager = elementManager;
|
||||
this->qTreeWidgetItem = new QTreeWidgetItem();
|
||||
auto transformJson = json.value("transform").toObject();
|
||||
property.name = json.value("name").toString();
|
||||
property.offset = {transformJson.value("offset").toObject().value("x").toDouble(),
|
||||
|
@ -43,7 +49,7 @@ LayerWrapper::LayerWrapper(QJsonObject json, FolderLayerWrapper*parent)
|
|||
}
|
||||
|
||||
FolderLayerWrapper::FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent)
|
||||
: LayerWrapper(json, parent)
|
||||
: LayerWrapper(json, parent, elementManager)
|
||||
{
|
||||
qDebug() << json.value("name").toString() << " " << this;
|
||||
QJsonArray childrenJson = json.value("children").toArray();
|
||||
|
@ -73,6 +79,7 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana
|
|||
int elementIndex = json.value("element").toInt();
|
||||
wrappedElement = elementManager->getElementById(elementIndex);
|
||||
}
|
||||
|
||||
void LayerWrapper::SimpleProperty::apply(PixelPath&cache) const
|
||||
{
|
||||
QTransform trans;
|
||||
|
@ -81,32 +88,48 @@ void LayerWrapper::SimpleProperty::apply(PixelPath&cache) const
|
|||
//qDebug() << name << " " << cache.boundingRect().center();
|
||||
//qDebug() << name << " " << cache.boundingRect();
|
||||
trans.translate(centerX, centerY);
|
||||
trans.scale(scale.x(), scale.y());
|
||||
trans.rotate(rotation);
|
||||
trans.translate(-centerX, -centerY);
|
||||
trans.translate(offset.x(), offset.y());
|
||||
trans.rotate(rotation);
|
||||
trans.scale(scale.x(), scale.y());
|
||||
trans.translate(-centerX, -centerY);
|
||||
cache = cache.trans(trans);
|
||||
}
|
||||
void LayerWrapper::refresh()
|
||||
|
||||
QTransform LayerWrapper::getTransform()
|
||||
{
|
||||
QTransform trans;
|
||||
double centerX = cache.getBoundingRect().center().x();
|
||||
double centerY = cache.getBoundingRect().center().y();
|
||||
//qDebug() << name << " " << cache.boundingRect().center();
|
||||
//qDebug() << name << " " << cache.boundingRect();
|
||||
trans.translate(centerX, centerY);
|
||||
trans.translate(property.offset.x(), property.offset.y());
|
||||
trans.rotate(property.rotation);
|
||||
trans.scale(property.scale.x(), property.scale.y());
|
||||
trans.translate(-centerX, -centerY);
|
||||
return trans;
|
||||
}
|
||||
|
||||
void LayerWrapper::refresh(LayerWrapper* layer)
|
||||
{
|
||||
property.apply(cache);
|
||||
}
|
||||
|
||||
void FolderLayerWrapper::refresh()
|
||||
void FolderLayerWrapper::refresh(LayerWrapper* layer)
|
||||
{
|
||||
cache.clear();
|
||||
for (auto& child : children) {
|
||||
cache.addPath(child.get()->getCache());
|
||||
cache.addPath(child.get()->getCache(layer));
|
||||
}
|
||||
LayerWrapper::refresh();
|
||||
}
|
||||
|
||||
void LeafLayerWrapper::refresh()
|
||||
void LeafLayerWrapper::refresh(LayerWrapper* layer)
|
||||
{
|
||||
cache.clear();
|
||||
if (wrappedElement != nullptr)
|
||||
{
|
||||
cache.addPath(wrappedElement->getPaintObject(this->styles));
|
||||
cache.addPath(wrappedElement->getPaintObject(&(this->styles)));
|
||||
}
|
||||
LayerWrapper::refresh();
|
||||
}
|
||||
|
@ -119,22 +142,22 @@ void LayerWrapper::setParent(FolderLayerWrapper* newParent)
|
|||
void FolderLayerWrapper::removeAllChild()
|
||||
{
|
||||
children.clear();
|
||||
qTreeWidgetItem.takeChildren();
|
||||
qTreeWidgetItem->takeChildren();
|
||||
}
|
||||
|
||||
void LayerWrapper::del() {
|
||||
qDebug() << "LayerWrapper::del()";
|
||||
if (parent != nullptr){
|
||||
qTreeWidgetItem.takeChildren();
|
||||
parent->qTreeWidgetItem.removeChild(&qTreeWidgetItem);
|
||||
qTreeWidgetItem->takeChildren();
|
||||
parent->qTreeWidgetItem->removeChild(qTreeWidgetItem);
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWrapper::delSelf() {
|
||||
qDebug() << "LayerWrapper::delSelf()";
|
||||
if (parent != nullptr) {
|
||||
qTreeWidgetItem.takeChildren();
|
||||
parent->qTreeWidgetItem.removeChild(&qTreeWidgetItem);
|
||||
qTreeWidgetItem->takeChildren();
|
||||
parent->qTreeWidgetItem->removeChild(qTreeWidgetItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +177,7 @@ void FolderLayerWrapper::delSelf() {
|
|||
qDebug() << this;
|
||||
for (auto& child : this->children) {
|
||||
this->parent->addChild(child);
|
||||
this->parent->qTreeWidgetItem.addChild(&child.get()->qTreeWidgetItem);
|
||||
this->parent->qTreeWidgetItem->addChild(child.get()->qTreeWidgetItem);
|
||||
child->setParent(this->parent);
|
||||
}
|
||||
while (!this->children.empty()) {
|
||||
|
@ -166,18 +189,18 @@ void FolderLayerWrapper::delSelf() {
|
|||
|
||||
QTreeWidgetItem* LayerWrapper::getQTreeItem()
|
||||
{
|
||||
this->qTreeWidgetItem.setText(0, this->property.name);
|
||||
this->qTreeWidgetItem.setData(0, Qt::UserRole, QVariant::fromValue(this));
|
||||
return &this->qTreeWidgetItem;
|
||||
this->qTreeWidgetItem->setText(0, this->property.name);
|
||||
this->qTreeWidgetItem->setData(0, Qt::UserRole, QVariant::fromValue(this));
|
||||
return this->qTreeWidgetItem;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* FolderLayerWrapper::getQTreeItem()
|
||||
{
|
||||
while (this->qTreeWidgetItem.childCount() > 0) {
|
||||
this->qTreeWidgetItem.removeChild(this->qTreeWidgetItem.child(0));
|
||||
while (this->qTreeWidgetItem->childCount() > 0) {
|
||||
this->qTreeWidgetItem->removeChild(this->qTreeWidgetItem->child(0));
|
||||
}
|
||||
for (auto& child : this->children) {
|
||||
this->qTreeWidgetItem.addChild(child->getQTreeItem());
|
||||
this->qTreeWidgetItem->addChild(child->getQTreeItem());
|
||||
}
|
||||
return LayerWrapper::getQTreeItem();
|
||||
}
|
||||
|
@ -204,8 +227,8 @@ QJsonObject FolderLayerWrapper::toJson() const
|
|||
childrenJson.push_back(child->toJson());
|
||||
json.insert("children", childrenJson);
|
||||
json.insert("is-folder", true);
|
||||
if(this->referencedBy != -1)
|
||||
json.insert("referenced-by", this->referencedBy);
|
||||
if(this->getReferencedBy() != -1)
|
||||
json.insert("referenced-by", this->getReferencedBy());
|
||||
else
|
||||
json.insert("referenced-by", QJsonValue());
|
||||
return json;
|
||||
|
@ -218,3 +241,40 @@ QJsonObject LeafLayerWrapper::toJson() const
|
|||
json.insert("is-folder", false);
|
||||
return json;
|
||||
}
|
||||
|
||||
int FolderLayerWrapper::getReferencedBy()const
|
||||
{
|
||||
if (this->elementManager != nullptr)
|
||||
return this->elementManager->getLayerReferencedBy(this);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void LayerWrapper::paint(QPainter* painter)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FolderLayerWrapper::paint(QPainter* painter)
|
||||
{
|
||||
for (auto& child : children)
|
||||
child->paint(painter);
|
||||
}
|
||||
|
||||
void LeafLayerWrapper::paint(QPainter* painter)
|
||||
{
|
||||
if (wrappedElement != nullptr)
|
||||
{
|
||||
//painter->save();
|
||||
QTransform trans;
|
||||
LayerWrapper* layer = this;
|
||||
while (layer != nullptr) {
|
||||
trans *= layer->getTransform();
|
||||
layer = layer->getParent();
|
||||
}
|
||||
auto p = wrappedElement->getPaintObject(&this->styles);
|
||||
p.trans(trans);
|
||||
painter->drawPixmap(0, 0, p.getPixmap());
|
||||
//painter->restore();
|
||||
}
|
||||
}
|
|
@ -28,12 +28,13 @@ class LayerWrapper
|
|||
protected:
|
||||
FolderLayerWrapper* parent;
|
||||
QPointF referencePoint;
|
||||
ElementManager* elementManager;
|
||||
// vector<LayerStyle> styles;
|
||||
// TODO: 将cache移到子类,对Leaf用ComposedPainterPath,对Folder用FolderBitmapPath
|
||||
PixelPath cache;
|
||||
|
||||
public:
|
||||
QTreeWidgetItem qTreeWidgetItem;
|
||||
QTreeWidgetItem* qTreeWidgetItem;
|
||||
struct SimpleProperty
|
||||
{
|
||||
QString name = "";
|
||||
|
@ -46,13 +47,15 @@ class LayerWrapper
|
|||
void apply(PixelPath&cache) const;
|
||||
} property;
|
||||
virtual void setParent(FolderLayerWrapper*newParent);
|
||||
virtual void refresh();
|
||||
virtual void refresh(LayerWrapper* layer = nullptr);
|
||||
virtual QTreeWidgetItem* getQTreeItem();
|
||||
// TODO: 将QPainterPath改为BitmapPath/QImage,或者直接将其删除,绘制时直接使用BitmapPath的paint方法
|
||||
virtual PixelPath getCache();
|
||||
virtual PixelPath getCache(LayerWrapper* selectedLayer=nullptr);
|
||||
QTransform getTransform();
|
||||
FolderLayerWrapper*getParent() const; // invoke by manager, then invoke parent's applyStyles
|
||||
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent);
|
||||
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager=nullptr);
|
||||
LayerWrapper() = default;
|
||||
virtual void paint(QPainter* painter);
|
||||
// TODO : export Function
|
||||
// virtual LayerWrapper *addChild() = 0; // Leaf Child Only
|
||||
// virtual LayerWrapper *addParent() = 0; // Folder Parent Only
|
||||
|
@ -74,7 +77,7 @@ class FolderLayerWrapper : public LayerWrapper
|
|||
public:
|
||||
|
||||
~FolderLayerWrapper() = default;
|
||||
void refresh() override;
|
||||
void refresh(LayerWrapper* layer=nullptr) override;
|
||||
FolderLayerWrapper() = default;
|
||||
FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
|
||||
void addChild(shared_ptr<LayerWrapper> child);
|
||||
|
@ -84,20 +87,24 @@ class FolderLayerWrapper : public LayerWrapper
|
|||
void delSelf() override;
|
||||
QTreeWidgetItem* getQTreeItem() override;
|
||||
QJsonObject toJson() const override;
|
||||
int getReferencedBy()const;
|
||||
void paint(QPainter* painter) override;
|
||||
};
|
||||
|
||||
class LeafLayerWrapper : public LayerWrapper
|
||||
{
|
||||
public:
|
||||
GraphicElement *wrappedElement;
|
||||
const vector<Renderer::ElementStyleStrokeDemo> styles;
|
||||
//const vector<Renderer::ElementStyleStrokeDemo> styles;
|
||||
vector<std::shared_ptr<LayerStyle>> styles;
|
||||
|
||||
public:
|
||||
~LeafLayerWrapper() = default;
|
||||
void refresh() override;
|
||||
void refresh(LayerWrapper* layer = nullptr) override;
|
||||
LeafLayerWrapper() = default;
|
||||
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
|
||||
QJsonObject toJson() const override;
|
||||
void paint(QPainter* painter) override;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(LayerWrapper *)
|
||||
|
|
|
@ -32,10 +32,15 @@ QPixmap PixelPath::getPixmap() const
|
|||
return pixmap;
|
||||
}
|
||||
|
||||
QPainterPath PixelPath::getPainterPath() const {
|
||||
return painterPath;
|
||||
}
|
||||
|
||||
void PixelPath::addPath(const PixelPath& path)
|
||||
{
|
||||
QPainter painter(&pixmap);
|
||||
painter.drawPixmap(0, 0, path.getPixmap());
|
||||
this->painterPath.addPath(path.getPainterPath());
|
||||
boundingRect = boundingRect.united(path.getBoundingRect());
|
||||
}
|
||||
|
||||
|
@ -46,6 +51,7 @@ void PixelPath::addPath(const QPainterPath& path)
|
|||
painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
painter.setPen(QPen(Qt::black,1));
|
||||
painter.drawPath(path);
|
||||
this->painterPath.addPath(path);
|
||||
boundingRect = boundingRect.united(path.boundingRect());
|
||||
}
|
||||
|
||||
|
@ -83,5 +89,32 @@ QPixmap PixelPath::resizedPixel(QSize size)const
|
|||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
painter.drawPixmap(0, 0, pixmap.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QPixmap PixelPath::getDetail()const
|
||||
{
|
||||
QPixmap result;
|
||||
auto rect = boundingRect.toRect();
|
||||
rect.setHeight(rect.height() + 20);
|
||||
rect.setWidth(rect.width() + 20);
|
||||
qDebug() << rect;
|
||||
result = pixmap.copy(rect);
|
||||
return result;
|
||||
}
|
||||
|
||||
void PixelPath::highLight()
|
||||
{
|
||||
// 创建一个QPainter对象,关联到QPixmap对象
|
||||
QPainter painter(&pixmap);
|
||||
|
||||
// 设置画笔的颜色、宽度和样式
|
||||
painter.setPen(QPen(Qt::black, 1, Qt::DashLine));
|
||||
|
||||
// 绘制一个矩形,指定左上角和右下角的坐标
|
||||
painter.drawRect(boundingRect);
|
||||
|
||||
// 结束绘制
|
||||
painter.end();
|
||||
}
|
|
@ -10,17 +10,21 @@ class PixelPath
|
|||
private:
|
||||
QRectF boundingRect;
|
||||
QPixmap pixmap;
|
||||
QPainterPath painterPath;
|
||||
int w,h;
|
||||
public:
|
||||
PixelPath(int w=1920, int h= 1080);
|
||||
PixelPath(QPainterPath painterPath,int w = 1920, int h = 1080);
|
||||
PixelPath(int w=1080, int h= 1080);
|
||||
PixelPath(QPainterPath painterPath,int w = 1080, int h = 1080);
|
||||
~PixelPath() = default;
|
||||
QRectF getBoundingRect() const;
|
||||
QPixmap getPixmap() const;
|
||||
QPainterPath getPainterPath() const;
|
||||
void addPath(const PixelPath& path);
|
||||
void addPath(const QPainterPath& path);
|
||||
void addImage(const QImage& image,const QPointF& pos);
|
||||
void clear();
|
||||
PixelPath trans(QTransform& mat)const;
|
||||
QPixmap resizedPixel(QSize size)const;
|
||||
QPixmap getDetail()const;
|
||||
void highLight();
|
||||
};
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent)
|
||||
{
|
||||
this->renderer = new Renderer::ElementRenderer(this);
|
||||
this->setFixedSize(QSize(1080, 1080));
|
||||
this->renderer = Renderer::ElementRenderer::instance();
|
||||
QSurfaceFormat surfaceFormat;
|
||||
surfaceFormat.setSamples(16);
|
||||
setFormat(surfaceFormat);
|
||||
|
@ -10,6 +11,7 @@ PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent)
|
|||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
layerManager = nullptr;
|
||||
currentLayer = nullptr;
|
||||
}
|
||||
|
||||
void PreviewWindow::initialize(LayerManager *layerManager,QSize windowSize)
|
||||
|
@ -36,7 +38,6 @@ void PreviewWindow::show()
|
|||
|
||||
void PreviewWindow::initializeGL()
|
||||
{
|
||||
this->renderer->initialize();
|
||||
initializeOpenGLFunctions();
|
||||
}
|
||||
|
||||
|
@ -47,7 +48,7 @@ void PreviewWindow::paintGL()
|
|||
painter->begin(this);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
layerManager->paint(painter,this->size());
|
||||
layerManager->paint(painter,this->size(),currentLayer);
|
||||
painter->end();
|
||||
}
|
||||
|
||||
|
@ -58,3 +59,49 @@ void PreviewWindow::resizeGL(int w, int h)
|
|||
Renderer::ElementRenderer* const PreviewWindow::getRenderer()const {
|
||||
return this->renderer;
|
||||
}
|
||||
|
||||
void PreviewWindow::currentLayerChanged(LayerWrapper* layer)
|
||||
{
|
||||
this->currentLayer = layer;
|
||||
}
|
||||
|
||||
void PreviewWindow::refresh()
|
||||
{
|
||||
this->repaint();
|
||||
}
|
||||
|
||||
void PreviewWindow::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
// 当鼠标按下时,记录当前的位置
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
void PreviewWindow::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
// 当鼠标移动时,计算移动的距离,并根据需要更新图形的状态
|
||||
int dx = event->x() - m_lastPos.x();
|
||||
int dy = event->y() - m_lastPos.y();
|
||||
if (currentLayer != nullptr) {
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
// 如果按下的是左键,那么平移图形
|
||||
currentLayer->property.offset.setX(currentLayer->property.offset.x() + dx);
|
||||
currentLayer->property.offset.setY(currentLayer->property.offset.y() + dy);
|
||||
qDebug() << dx << "----" << dy;
|
||||
emit layerInfoChanged();
|
||||
}
|
||||
else if (event->buttons() & Qt::RightButton) {
|
||||
// 如果按下的是右键,那么旋转图形
|
||||
qreal angle = -sqrt(dx * dx + dy * dy) / 1.0;
|
||||
currentLayer->property.rotation += angle;
|
||||
emit layerInfoChanged();
|
||||
}
|
||||
}
|
||||
// 更新上一次的位置
|
||||
m_lastPos = event->pos();
|
||||
this->repaint();
|
||||
}
|
||||
|
||||
void PreviewWindow::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
// 当鼠标释放时,不做任何操作
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QMouseEvent>
|
||||
#include <QOpenGLWidget>
|
||||
#include "../Renderer/Preview/ElementRenderer.h"
|
||||
|
||||
|
@ -19,6 +20,12 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
|
|||
LayerManager *layerManager;
|
||||
Renderer::ElementRenderer* renderer;
|
||||
QSize logicalSize;
|
||||
QRectF viewportRect;
|
||||
LayerWrapper* currentLayer;
|
||||
QPointF m_lastPos;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
|
||||
public:
|
||||
PreviewWindow(QWidget *parent = nullptr);
|
||||
|
@ -28,4 +35,11 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
|
|||
void paintGL() override;
|
||||
void resizeGL(int w, int h) override;
|
||||
Renderer::ElementRenderer* const getRenderer()const;
|
||||
|
||||
public slots:
|
||||
void currentLayerChanged(LayerWrapper*);
|
||||
void refresh();
|
||||
|
||||
signals:
|
||||
void layerInfoChanged();
|
||||
};
|
||||
|
|
|
@ -1,27 +1,26 @@
|
|||
#include "InfoDisplayWidget.h"
|
||||
#include "./EditorWidgetComponent/LayerStyleDialog.h"
|
||||
#include <QLineEdit>
|
||||
#include <QTextBlock>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QDialog>
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <qtmaterialraisedbutton.h>
|
||||
#include <qtmaterialflatbutton.h>
|
||||
|
||||
void InfoDisplayWidget::setLayer(LayerWrapper *layer)
|
||||
{
|
||||
this->displayLayer = layer;
|
||||
generateLayerForm();
|
||||
}
|
||||
void InfoDisplayWidget::setElement(GraphicElement *element)
|
||||
{
|
||||
this->displayElement = element;
|
||||
generateElementForm();
|
||||
}
|
||||
|
||||
void InfoDisplayWidget::generateLayerForm()
|
||||
{
|
||||
QLayoutItem *item;
|
||||
if (this->layout() != nullptr)
|
||||
{
|
||||
while ((item = this->layout()->takeAt(0)) != nullptr)
|
||||
while (this->layout()->count() > 0 && (item = this->layout()->takeAt(0)) != nullptr)
|
||||
{
|
||||
delete item->widget();
|
||||
delete item;
|
||||
|
@ -47,26 +46,31 @@ void InfoDisplayWidget::generateLayerForm()
|
|||
rotation->setValidator(new QIntValidator(-10000, 10000, this));
|
||||
connect(rotation, &QLineEdit::textChanged, [=](QString content) {
|
||||
this->displayLayer->property.rotation = content.toDouble();
|
||||
emit requireRefreshElementWidget();
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
offsetX->setValidator(new QIntValidator(-10000, 10000, this));
|
||||
connect(offsetX, &QLineEdit::textChanged, [=](QString content) {
|
||||
this->displayLayer->property.offset = {content.toDouble(), this->displayLayer->property.offset.y()};
|
||||
emit requireRefreshElementWidget();
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
offsetY->setValidator(new QIntValidator(-10000, 10000, this));
|
||||
connect(offsetY, &QLineEdit::textChanged, [=](QString content) {
|
||||
this->displayLayer->property.offset = {this->displayLayer->property.offset.x(), content.toDouble()};
|
||||
emit requireRefreshElementWidget();
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
scaleX->setValidator(new QDoubleValidator(0.001, 1000, 4, this));
|
||||
connect(scaleX, &QLineEdit::textChanged, [=](QString content) {
|
||||
this->displayLayer->property.scale = {content.toDouble(), this->displayLayer->property.scale.y()};
|
||||
emit requireRefreshElementWidget();
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
scaleY->setValidator(new QDoubleValidator(0.001, 1000, 4, this));
|
||||
connect(scaleY, &QLineEdit::textChanged, [=](QString content) {
|
||||
this->displayLayer->property.scale = {this->displayLayer->property.scale.x(), content.toDouble()};
|
||||
emit requireRefreshElementWidget();
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
|
||||
|
@ -78,78 +82,165 @@ void InfoDisplayWidget::generateLayerForm()
|
|||
layout->addRow("scale-Y:", scaleY);
|
||||
layout->setRowWrapPolicy(QFormLayout::DontWrapRows);
|
||||
|
||||
bool styleEnabled = true;
|
||||
if (styleEnabled) {
|
||||
LeafLayerWrapper* leafP = dynamic_cast<LeafLayerWrapper*>(this->displayLayer);
|
||||
if (leafP) {
|
||||
QListWidget* styleList = new QListWidget(this);
|
||||
QListWidgetItem* item = new QListWidgetItem("样式列表");
|
||||
item->setFlags(Qt::NoItemFlags);
|
||||
styleList->addItem(item);
|
||||
static vector<QString> styleNames = { "样例1", "样例2", "样例3" };
|
||||
auto createStyleItem = [this, styleList](int index) {
|
||||
|
||||
QListWidgetItem* header = new QListWidgetItem;
|
||||
QWidget* headerWidget = new QWidget(styleList);
|
||||
QHBoxLayout* headerLayout = new QHBoxLayout;
|
||||
|
||||
QLabel* headerLabel = new QLabel(headerWidget);
|
||||
headerLabel->setText("样式列表");
|
||||
headerLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||
|
||||
//QtMaterialRaisedButton* addStyleButton = new QtMaterialRaisedButton("+", headerWidget);
|
||||
QPushButton* addStyleButton = new QPushButton("+", headerWidget);
|
||||
addStyleButton->setFixedSize(QSize(20, 20));
|
||||
if (leafP->styles.size() >= LayerStyle::types.size())
|
||||
{
|
||||
addStyleButton->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
connect(addStyleButton, &QPushButton::clicked, [&, leafP]() {
|
||||
LayerStyleDialog* dialog = new LayerStyleDialog(nullptr, nullptr, &(leafP->styles));
|
||||
dialog->exec();
|
||||
if (dialog->layerStyle)
|
||||
{
|
||||
leafP->styles.push_back(dialog->layerStyle);
|
||||
emit requireRefreshPreview();
|
||||
emit requireSelfRefresh();
|
||||
emit requireRefreshElementWidget();
|
||||
}
|
||||
dialog->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
headerLayout->addWidget(headerLabel);
|
||||
headerLayout->addWidget(addStyleButton);
|
||||
headerLayout->setContentsMargins(5, 0, 5, 0);
|
||||
headerWidget->setLayout(headerLayout);
|
||||
|
||||
header->setFlags(Qt::NoItemFlags);
|
||||
styleList->addItem(header);
|
||||
styleList->setItemWidget(header, headerWidget);
|
||||
//static vector<QString> styleNames = { "样例1", "样例2", "样例3" };
|
||||
// auto createStyleItem = [this, styleList](int index) {
|
||||
// QListWidgetItem* item = new QListWidgetItem;
|
||||
// QWidget* w = new QWidget;
|
||||
// item->setSizeHint(QSize(50, 40));
|
||||
// QHBoxLayout* layout = new QHBoxLayout;
|
||||
// QPushButton* deleteButton = new QPushButton(w);
|
||||
// QPushButton* detailButton = new QPushButton(w);
|
||||
// QLabel* name = new QLabel(w);
|
||||
// name->setText(styleNames[index]);
|
||||
// detailButton->setText("...");
|
||||
// detailButton->setFixedSize(QSize(20, 20));
|
||||
// deleteButton->setText("×");
|
||||
// deleteButton->setFixedSize(QSize(20, 20));
|
||||
// connect(detailButton, &QPushButton::clicked, [styleList, item, this, index]() {
|
||||
// QDialog dlg(this);
|
||||
// dlg.setWindowTitle("样式详情");
|
||||
// dlg.resize(400, 200);
|
||||
// QGridLayout *contentLayout = new QGridLayout(&dlg);
|
||||
// QLineEdit* name = new QLineEdit(styleNames[index], &dlg);
|
||||
// auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
||||
// contentLayout->addWidget(buttonBox);
|
||||
// connect(buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
|
||||
// connect(buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);
|
||||
// bool updateStyle = dlg.exec();
|
||||
// if (updateStyle) {
|
||||
// styleNames[index] = name->text();
|
||||
// qDebug() << name->text();
|
||||
// // 在此处修改新样式信息至内存
|
||||
// emit requireRefreshPreview();
|
||||
// emit requireSelfRefresh();
|
||||
// }
|
||||
// });
|
||||
// connect(deleteButton, &QPushButton::clicked, [styleList,item,this]() {
|
||||
// styleList->removeItemWidget(item);
|
||||
// delete item;
|
||||
// // 删除layer对应样式
|
||||
// emit requireRefreshPreview();
|
||||
// emit requireSelfRefresh();
|
||||
// });
|
||||
// layout->addWidget(name);
|
||||
// layout->addWidget(detailButton);
|
||||
// layout->addWidget(deleteButton);
|
||||
// w->setLayout(layout);
|
||||
// styleList->addItem(item);
|
||||
// styleList->setItemWidget(item, w);
|
||||
// };
|
||||
// for (int i = 0; i < styleNames.size(); i++)
|
||||
// createStyleItem(i);
|
||||
|
||||
/*if (leafP->styles.empty())
|
||||
{
|
||||
leafP->styles.push_back(std::shared_ptr<LayerStyle>(new StrokeElementLayerStyle()));
|
||||
}*/
|
||||
std::vector<std::shared_ptr<LayerStyle>>* styles = &(leafP->styles);
|
||||
for (auto styleIterator = styles->begin(); styleIterator != styles->end(); styleIterator++)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem;
|
||||
QWidget* w = new QWidget;
|
||||
item->setSizeHint(QSize(50, 40));
|
||||
QHBoxLayout* layout = new QHBoxLayout;
|
||||
QPushButton* deleteButton = new QPushButton(w);
|
||||
layout->setAlignment(Qt::AlignmentFlag::AlignRight);
|
||||
//QtMaterialFlatButton* detailButton = new QtMaterialFlatButton(w);
|
||||
//QtMaterialFlatButton* removeButton = new QtMaterialFlatButton(w);
|
||||
QPushButton* detailButton = new QPushButton(w);
|
||||
QLabel* name = new QLabel(w);
|
||||
name->setText(styleNames[index]);
|
||||
QPushButton* removeButton = new QPushButton(w);
|
||||
detailButton->setText("...");
|
||||
detailButton->setFixedSize(QSize(20, 20));
|
||||
deleteButton->setText("×");
|
||||
deleteButton->setFixedSize(QSize(20, 20));
|
||||
connect(detailButton, &QPushButton::clicked, [styleList, item, this, index]() {
|
||||
QDialog dlg(this);
|
||||
dlg.setWindowTitle("样式详情");
|
||||
dlg.resize(400, 200);
|
||||
QGridLayout *contentLayout = new QGridLayout(&dlg);
|
||||
QLineEdit* name = new QLineEdit(styleNames[index], &dlg);
|
||||
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
||||
contentLayout->addWidget(buttonBox);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);
|
||||
bool updateStyle = dlg.exec();
|
||||
if (updateStyle) {
|
||||
styleNames[index] = name->text();
|
||||
qDebug() << name->text();
|
||||
// 在此处修改新样式信息至内存
|
||||
removeButton->setText("×");
|
||||
removeButton->setFixedSize(QSize(20, 20));
|
||||
|
||||
connect(detailButton, &QPushButton::clicked, this,
|
||||
[this, styleIterator]()
|
||||
{
|
||||
LayerStyleDialog* dialog = new LayerStyleDialog(nullptr, *styleIterator);
|
||||
dialog->exec();
|
||||
|
||||
if (dialog->layerStyle)
|
||||
{
|
||||
(*styleIterator) = dialog->layerStyle;
|
||||
emit requireRefreshPreview();
|
||||
emit requireSelfRefresh();
|
||||
emit requireRefreshElementWidget();
|
||||
}
|
||||
dialog->deleteLater();
|
||||
});
|
||||
connect(deleteButton, &QPushButton::clicked, [styleList,item,this]() {
|
||||
styleList->removeItemWidget(item);
|
||||
delete item;
|
||||
// 删除layer对应样式
|
||||
|
||||
connect(removeButton, &QPushButton::clicked, this,
|
||||
[this, styleIterator, styles]()
|
||||
{
|
||||
styles->erase(styleIterator);
|
||||
emit requireRefreshPreview();
|
||||
emit requireSelfRefresh();
|
||||
emit requireRefreshElementWidget();
|
||||
});
|
||||
layout->addWidget(name);
|
||||
|
||||
QWidget* styleDisplayWidget = (*styleIterator)->getListDisplayWidget();
|
||||
styleDisplayWidget->setParent(w);
|
||||
styleDisplayWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||
|
||||
layout->addWidget(styleDisplayWidget);
|
||||
layout->addWidget(detailButton);
|
||||
layout->addWidget(deleteButton);
|
||||
layout->addWidget(removeButton);
|
||||
w->setLayout(layout);
|
||||
|
||||
styleList->addItem(item);
|
||||
styleList->setItemWidget(item, w);
|
||||
};
|
||||
for (int i = 0; i < styleNames.size(); i++)
|
||||
createStyleItem(i);
|
||||
|
||||
|
||||
}
|
||||
layout->addRow(styleList);
|
||||
}
|
||||
}
|
||||
this->setLayout(layout);
|
||||
}
|
||||
|
||||
|
||||
void InfoDisplayWidget::generateElementForm()
|
||||
{
|
||||
}
|
||||
|
||||
void InfoDisplayWidget::triggerSelfRefresh()
|
||||
{
|
||||
if (this->displayLayer != nullptr)
|
||||
this->generateLayerForm();
|
||||
if (this->displayElement != nullptr)
|
||||
this->generateElementForm();
|
||||
}
|
|
@ -4,19 +4,18 @@
|
|||
#include <QFormLayout>
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
#include "ElementPoolWidget.h"
|
||||
|
||||
class InfoDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
LayerWrapper *displayLayer;
|
||||
GraphicElement *displayElement;
|
||||
|
||||
|
||||
public:
|
||||
void setLayer(LayerWrapper *layer);
|
||||
void setElement(GraphicElement *element);
|
||||
void generateLayerForm();
|
||||
void generateElementForm();
|
||||
|
||||
public slots:
|
||||
void triggerSelfRefresh();
|
||||
|
@ -24,6 +23,6 @@ class InfoDisplayWidget : public QWidget
|
|||
signals:
|
||||
void requireRefreshPreview();
|
||||
void requireSelfRefresh();
|
||||
|
||||
void requireRefreshElementWidget();
|
||||
|
||||
};
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "LayerTreeWidget.h"
|
||||
#include <QInputDialog>
|
||||
#include <QMenu>
|
||||
#include "./EditorWidgetComponent/LayerCreateWidget.h"
|
||||
|
||||
LayerTreeWidget::LayerTreeWidget(QWidget *parent)
|
||||
{
|
||||
emit displayLayerChange(nullptr);
|
||||
|
@ -11,10 +13,14 @@ LayerTreeWidget::LayerTreeWidget(QWidget *parent)
|
|||
connect(this, &QTreeWidget::customContextMenuRequested, this, &LayerTreeWidget::popMenu);
|
||||
connect(this, &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem *currentItem) {
|
||||
this->selectedItem = currentItem;
|
||||
if(this->selectedItem !=nullptr)
|
||||
emit displayLayerChange(this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper *>());
|
||||
else
|
||||
if (this->selectedItem != nullptr) {
|
||||
auto layer = this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>();
|
||||
emit displayLayerChange(layer);
|
||||
}
|
||||
else {
|
||||
emit displayLayerChange(nullptr);
|
||||
}
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
// connect(this, &QTreeWidget::itemDoubleClicked, this, &LayerTreeWidget::onItemDoubleClicked);
|
||||
}
|
||||
|
@ -35,32 +41,64 @@ void LayerTreeWidget::popMenu(const QPoint &pos)
|
|||
QMenu menu;
|
||||
QTreeWidgetItem *item = itemAt(pos);
|
||||
this->selectedItem = item;
|
||||
// TODO
|
||||
menu.addAction(QString::fromLocal8Bit("´´½¨×Ó½Úµã"), this, &LayerTreeWidget::onRenameEvent);
|
||||
//if (item != root->getQTreeItem())
|
||||
//{
|
||||
menu.addAction(QString::fromLocal8Bit("ÖØÃüÃû"), this, &LayerTreeWidget::onRenameEvent);
|
||||
// menu.addAction("Copy", this, &LayerTreeWidget::onRenameEvent);
|
||||
if (item != nullptr && item->childCount() > 0)
|
||||
if (item != nullptr) {
|
||||
auto layer = this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>();
|
||||
if (layer != nullptr) {
|
||||
if (typeid(*layer) == typeid(FolderLayerWrapper)) {
|
||||
menu.addAction(QString::fromLocal8Bit("创建子节点"), this, [this, layer]() {
|
||||
auto dialog = new LayerCreateWidget(elementManager, this);
|
||||
connect(dialog, &LayerCreateWidget::LayerInfoReturned, this, [this, layer](QJsonObject jsonObj) {
|
||||
auto folderLayer = dynamic_cast<FolderLayerWrapper*>(layer);
|
||||
LayerWrapper* newLayer;
|
||||
if(jsonObj.value("is-folder").toBool())
|
||||
newLayer = new FolderLayerWrapper(jsonObj, this->elementManager, folderLayer);
|
||||
else
|
||||
newLayer = new LeafLayerWrapper(jsonObj, this->elementManager, folderLayer);
|
||||
|
||||
folderLayer->addChild(std::shared_ptr<LayerWrapper>(newLayer));
|
||||
folderLayer->qTreeWidgetItem->addChild(newLayer->getQTreeItem());
|
||||
qDebug() << jsonObj<<"----------------------";
|
||||
this->refresh();
|
||||
emit requireRefreshPreview();
|
||||
emit requireRefreshElementWidget();
|
||||
});
|
||||
dialog->exec();
|
||||
});
|
||||
menu.addAction(QString::fromLocal8Bit("删除(保留子节点)"), this, [this]() {
|
||||
if (this->selectedItem == nullptr)
|
||||
return;
|
||||
auto layer = this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>();
|
||||
layer->delSelf();
|
||||
layer->getParent()->removeChild(layer);
|
||||
this->refresh();
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
}
|
||||
if (layer != root) {
|
||||
menu.addAction(QString::fromLocal8Bit("删除"), this, [this]() {
|
||||
if (this->selectedItem == nullptr)
|
||||
return;
|
||||
auto layer = this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>();
|
||||
layer->del();
|
||||
layer->getParent()->removeChild(layer);
|
||||
this->refresh();
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
//}
|
||||
menu.addAction(QString::fromLocal8Bit("重命名"), this, &LayerTreeWidget::onRenameEvent);
|
||||
}
|
||||
if (typeid(*layer) == typeid(FolderLayerWrapper) && ((FolderLayerWrapper*)layer)->getReferencedBy() == -1) {
|
||||
menu.addAction(QString::fromLocal8Bit("创建组合元素"), this, [this]() {
|
||||
auto layer = dynamic_cast<FolderLayerWrapper*>(this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>());
|
||||
if (layer != nullptr) {
|
||||
bool ok;
|
||||
QString name = QInputDialog::getText(this, QString::fromLocal8Bit("创建组合元素"),
|
||||
QString::fromLocal8Bit("组合元素名称:"), QLineEdit::Normal,
|
||||
"", &ok);
|
||||
if (ok && !name.isEmpty()) {
|
||||
elementManager->createGroupElement(name, layer);
|
||||
emit requireRefreshElementWidget();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
menu.exec(mapToGlobal(pos));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "LayerWrapper.h"
|
||||
#include "ElementManager.h"
|
||||
#include <QPoint>
|
||||
#include <QTreeWidget>
|
||||
class LayerTreeWidget : public QTreeWidget
|
||||
|
@ -10,6 +11,7 @@ class LayerTreeWidget : public QTreeWidget
|
|||
LayerWrapper *copiedItem;
|
||||
|
||||
public:
|
||||
ElementManager* elementManager;
|
||||
LayerWrapper* root;
|
||||
LayerTreeWidget(QWidget *parent = nullptr);
|
||||
void onRenameEvent();
|
||||
|
@ -18,7 +20,8 @@ class LayerTreeWidget : public QTreeWidget
|
|||
// void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
// void onItemDoubleClicked(QTreeWidgetItem *item, int column = 0);
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void displayLayerChange(LayerWrapper *);
|
||||
void requireRefreshPreview();
|
||||
void requireRefreshElementWidget();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
#include "PaintingUtil.h"
|
||||
#include <QFile>
|
||||
#include <QJsondocument>
|
||||
#include "PainterPathUtil.h"
|
||||
|
||||
using Renderer::Painting;
|
||||
using Renderer::Element;
|
||||
using Renderer::ElementTransform;
|
||||
using glm::bvec2;
|
||||
using std::max;
|
||||
|
||||
QJsonObject PaintingUtil::readJsonFile(QString jsonFilePath) {
|
||||
QFile jsonFile(jsonFilePath);
|
||||
jsonFile.open(QFile::ReadOnly);
|
||||
QByteArray fileContent = jsonFile.readAll().trimmed();
|
||||
jsonFile.close();
|
||||
QJsonParseError jError;
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(fileContent, &jError));
|
||||
return jsonDoc.object();
|
||||
}
|
||||
|
||||
Painting PaintingUtil::transfromToPainting(QString jsonFilePath) {
|
||||
Painting painting;
|
||||
QTransform transform;
|
||||
glm::bvec2 flip(0, 0);
|
||||
QJsonObject jsonObj = readJsonFile(jsonFilePath);
|
||||
ElementManager *elementManager = new ElementManager(jsonObj, Renderer::ElementRenderer::instance());
|
||||
LayerManager* layerManager = new LayerManager(jsonObj, elementManager);
|
||||
traverseLayTree(layerManager->getRoot(), transform, flip, painting);
|
||||
// FIXME: 为了编译通过添加的返回
|
||||
return painting;
|
||||
}
|
||||
|
||||
void PaintingUtil::traverseLayTree(LayerWrapper* nowLayer, QTransform transform, bvec2 flip, Painting& painting) {
|
||||
LeafLayerWrapper* leafLayer = dynamic_cast<LeafLayerWrapper*>(nowLayer);
|
||||
PixelPath pixelPath = nowLayer->getCache();
|
||||
double centerX = pixelPath.getBoundingRect().center().x();
|
||||
double centerY = pixelPath.getBoundingRect().center().y();
|
||||
flip ^= bvec2(nowLayer->property.flipHorizontally, nowLayer->property.flipVertically);
|
||||
|
||||
QRectF transBound = transform.map(pixelPath.getPainterPath()).boundingRect();
|
||||
|
||||
transform.translate(nowLayer->property.offset.x(), nowLayer->property.offset.y())
|
||||
.translate(-centerX, -centerY)
|
||||
.rotate(nowLayer->property.rotation)
|
||||
.scale(nowLayer->property.scale.x(), nowLayer->property.scale.y())
|
||||
.translate(centerX, centerY);
|
||||
if (leafLayer != nullptr) {
|
||||
Element element;
|
||||
ElementTransform elementTrans;
|
||||
QRectF bound = pixelPath.getBoundingRect();
|
||||
element.ratio = bound.width() / bound.height();
|
||||
// transform to initial painterPath
|
||||
QTransform trans;
|
||||
trans.translate(-centerX, -centerY)
|
||||
.scale(1 / nowLayer->property.scale.x(), 1 / nowLayer->property.scale.y())
|
||||
.rotate(-nowLayer->property.rotation)
|
||||
.translate(centerX, centerY)
|
||||
.translate(-nowLayer->property.offset.x(), -nowLayer->property.offset.y());
|
||||
QPainterPath painterPath = trans.map(pixelPath.getPainterPath());
|
||||
// transfrom to -1, 1
|
||||
bound = painterPath.boundingRect();
|
||||
trans.reset();
|
||||
trans.translate(1, 1);
|
||||
trans.scale(2 / bound.width(), 2 / bound.height());
|
||||
trans.translate(bound.x(), bound.y());
|
||||
painterPath = trans.map(painterPath);
|
||||
|
||||
element.contour.reset(new vector<vector<Renderer::Point> >(PainterPathUtil::transformToLines(painterPath)));
|
||||
QSize screenSize = pixelPath.getPixmap().size();
|
||||
|
||||
elementTrans.center = glm::vec2(
|
||||
(2 * (transBound.x() + transBound.width()) - screenSize.width()) / screenSize.width(),
|
||||
(2 * (transBound.y() + transBound.height()) - screenSize.height()) / screenSize.height()
|
||||
);
|
||||
decomposeTransform(transform, elementTrans.rotation, elementTrans.scale);
|
||||
elementTrans.flip = glm::bvec2(
|
||||
nowLayer->property.flipHorizontally,
|
||||
nowLayer->property.flipVertically
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
FolderLayerWrapper* folderLayer = dynamic_cast<FolderLayerWrapper*>(nowLayer);
|
||||
for (auto sonLayer : folderLayer->children) {
|
||||
traverseLayTree(sonLayer.get(), transform, flip, painting);
|
||||
}
|
||||
return;
|
||||
}
|
||||
void PaintingUtil::decomposeTransform(QTransform trans, float& angle, glm::vec2& scale) {
|
||||
trans.translate(-trans.dx(), -trans.dy());
|
||||
int count = 0;
|
||||
double norm = 0, n = 0;
|
||||
QTransform R = trans, Rit, Rnext;
|
||||
do {
|
||||
++count;
|
||||
Rit = R.inverted();
|
||||
Rnext.setMatrix(
|
||||
(R.m11() + Rit.m11()) / 2,
|
||||
(R.m12() + Rit.m12()) / 2,
|
||||
(R.m13() + Rit.m13()) / 2,
|
||||
(R.m21() + Rit.m21()) / 2,
|
||||
(R.m22() + Rit.m22()) / 2,
|
||||
(R.m23() + Rit.m23()) / 2,
|
||||
(R.m31() + Rit.m31()) / 2,
|
||||
(R.m32() + Rit.m32()) / 2,
|
||||
(R.m33() + Rit.m33()) / 2
|
||||
);
|
||||
norm = 0;
|
||||
norm = max(norm,
|
||||
fabs(R.m11() - Rnext.m11())
|
||||
+ fabs(R.m12() - Rnext.m12())
|
||||
+ fabs(R.m13() - Rnext.m13()));
|
||||
norm = max(norm,
|
||||
fabs(R.m21() - Rnext.m21())
|
||||
+ fabs(R.m22() - Rnext.m22())
|
||||
+ fabs(R.m23() - Rnext.m23()));
|
||||
norm = max(norm,
|
||||
fabs(R.m31() - Rnext.m31())
|
||||
+ fabs(R.m32() - Rnext.m32())
|
||||
+ fabs(R.m33() - Rnext.m33()));
|
||||
R = Rnext;
|
||||
} while (count < 100 && norm > 0.0001);
|
||||
angle = acos(R.m11());
|
||||
R = R.inverted() * trans;
|
||||
scale = glm::vec2(R.m11(), R.m22());
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
#include "../../Renderer/Painting/Painting.h"
|
||||
#include <QJsonObject>
|
||||
#include <ElementManager.h>
|
||||
class PaintingUtil
|
||||
{
|
||||
private:
|
||||
static QJsonObject readJsonFile(QString jsonFilePath);
|
||||
static void traverseLayTree(LayerWrapper* nowLayer, QTransform transform, glm::bvec2 flip, Renderer::Painting& painting);
|
||||
static void decomposeTransform(QTransform trans, float& angle, glm::vec2& scale);
|
||||
public:
|
||||
static Renderer::Painting transfromToPainting(QString jsonFilePath);
|
||||
|
||||
};
|
||||
|
|
@ -86,7 +86,6 @@ QPolygonF SvgFileLoader::handleAttrPoints(QString points) {
|
|||
void SvgFileLoader::handleAttrTransform(QString transformStyle, QPainterPath& painterPath) {
|
||||
QTransform trans;
|
||||
QStringList ops = transformStyle.split(')');
|
||||
reverse(ops.begin(), ops.end());
|
||||
vector<double> numbers;
|
||||
for (auto op : ops) {
|
||||
op = op.simplified();
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#include "FluentMenu.h"
|
||||
#include <QPainter>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
::FluentMenu::FluentMenu(QWidget* parent) : QMenu(parent)
|
||||
{
|
||||
setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setStyleSheet(QString::fromStdString(std::format("QMenu {{margin:{}px;border-radius:{}px;padding:4px;border: 1px solid #c1c1c1;}}"
|
||||
"QMenu::item {{height:30px;width:100px;padding-left:20px;border-radius:{}px;}}"
|
||||
"QMenu::item:selected {{background-color:#dedede;}}", shadowRadius, borderRadius, itemBorderRadius)));
|
||||
}
|
||||
|
||||
void ::FluentMenu::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
for (qreal i = 0; i < shadowRadius; i += 1 / devicePixelRatioF())
|
||||
{
|
||||
painter.setPen(QColor(0, 0, 0, glm::mix(0.22 * 255, 0., glm::pow(i / shadowRadius, 0.2))));
|
||||
painter.drawRoundedRect(QRectF(shadowRadius - i, shadowRadius - i, width() - (shadowRadius - i) * 2, height() - (shadowRadius - i) * 2), borderRadius + i, borderRadius + i);
|
||||
}
|
||||
QMenu::paintEvent(event);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include <QMenu>
|
||||
|
||||
class FluentMenu : public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FluentMenu(QWidget* parent = nullptr);
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
int shadowRadius = 16;
|
||||
int borderRadius = 6;
|
||||
int itemBorderRadius = 4;
|
||||
};
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2018-2022 Antonio Dias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iconwidget.h"
|
||||
|
||||
#define ICONWIDTH 16
|
||||
#define ICONHEIGHT 16
|
||||
|
||||
IconWidget::IconWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
m_active = true;
|
||||
}
|
||||
|
||||
void IconWidget::setPixmap(const QPixmap &pixmap)
|
||||
{
|
||||
m_pixmap = pixmap;
|
||||
|
||||
QImage tmp = m_pixmap.toImage();
|
||||
|
||||
for (int i = 0; i < m_pixmap.width(); i++)
|
||||
{
|
||||
for (int j = 0; j < m_pixmap.height(); j++)
|
||||
{
|
||||
int gray = qGray(tmp.pixel(i, j));
|
||||
|
||||
int alpha = qAlpha(tmp.pixel(i, j));
|
||||
|
||||
tmp.setPixel(i, j, qRgba(gray, gray, gray, alpha));
|
||||
}
|
||||
}
|
||||
|
||||
m_grayed_pixmap = QPixmap::fromImage(tmp);
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void IconWidget::setActive(bool active)
|
||||
{
|
||||
m_active = active;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void IconWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
|
||||
painter.drawPixmap((width() - ICONWIDTH)/ 2,
|
||||
(height() - ICONHEIGHT) / 2,
|
||||
ICONWIDTH, ICONHEIGHT,
|
||||
m_active ? m_pixmap : m_grayed_pixmap);
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2018-2022 Antonio Dias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ICONWIDGET_H
|
||||
#define ICONWIDGET_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
|
||||
class IconWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit IconWidget(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void setPixmap(const QPixmap &pixmap);
|
||||
void setActive(bool active);
|
||||
|
||||
private:
|
||||
//Functions
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
//Variables
|
||||
QPixmap m_pixmap;
|
||||
QPixmap m_grayed_pixmap;
|
||||
bool m_active;
|
||||
};
|
||||
|
||||
#endif // ICONWIDGET_H
|
|
@ -2,6 +2,7 @@
|
|||
#include "Renderer/RendererGLWidget.h"
|
||||
#include "qslider.h"
|
||||
#include <QPushButton>
|
||||
#include <QScreen>
|
||||
#include "NavigationBarWidget.h"
|
||||
#include <FramelessHelper/Core/utils.h>
|
||||
#include <FramelessHelper/Widgets/standardtitlebar.h>
|
||||
|
@ -11,111 +12,13 @@
|
|||
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
|
||||
inline void fontTheme()
|
||||
{
|
||||
QFont defaultFont = qApp->font();
|
||||
defaultFont.setPointSize(defaultFont.pointSize() + 2);
|
||||
qApp->setFont(defaultFont);
|
||||
}
|
||||
|
||||
inline void setThemeStyleSheet(bool dark)
|
||||
{
|
||||
QFile file(dark ? ":/darkstyle.qss" : ":/lightstyle.qss");
|
||||
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
return;
|
||||
|
||||
const QString style_sheet = QLatin1String(file.readAll());
|
||||
|
||||
file.close();
|
||||
|
||||
qApp->setStyleSheet(style_sheet);
|
||||
}
|
||||
|
||||
inline void darkTheme()
|
||||
{
|
||||
QPalette darkPalette = qApp->palette();
|
||||
|
||||
darkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
|
||||
darkPalette.setColor(QPalette::WindowText, QColor(255, 255, 255));
|
||||
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127));
|
||||
darkPalette.setColor(QPalette::Base, QColor(42, 42, 42));
|
||||
darkPalette.setColor(QPalette::AlternateBase, QColor(66, 66, 66));
|
||||
darkPalette.setColor(QPalette::ToolTipBase, QColor(255, 255, 255));
|
||||
darkPalette.setColor(QPalette::ToolTipText, QColor(255, 255, 255));
|
||||
darkPalette.setColor(QPalette::Text, QColor(255, 255, 255));
|
||||
darkPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127));
|
||||
darkPalette.setColor(QPalette::Dark, QColor(35, 35, 35));
|
||||
darkPalette.setColor(QPalette::Shadow, QColor(20, 20, 20));
|
||||
darkPalette.setColor(QPalette::Button, QColor(53, 53, 53));
|
||||
darkPalette.setColor(QPalette::ButtonText, QColor(255, 255, 255));
|
||||
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127));
|
||||
darkPalette.setColor(QPalette::BrightText, QColor(255, 0, 0));
|
||||
darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
|
||||
darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
||||
darkPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(80, 80, 80));
|
||||
darkPalette.setColor(QPalette::HighlightedText, QColor(255, 255, 255));
|
||||
darkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(127, 127, 127));
|
||||
|
||||
qApp->setPalette(darkPalette);
|
||||
|
||||
setThemeStyleSheet(true /*dark*/);
|
||||
}
|
||||
|
||||
|
||||
inline void lightTheme()
|
||||
{
|
||||
QPalette lightPalette = qApp->palette();
|
||||
|
||||
lightPalette.setColor(QPalette::Window, QColor(240, 240, 240));
|
||||
lightPalette.setColor(QPalette::WindowText, QColor(0, 0, 0));
|
||||
lightPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(120, 120, 120));
|
||||
lightPalette.setColor(QPalette::Base, QColor(255, 255, 255));
|
||||
lightPalette.setColor(QPalette::AlternateBase, QColor(233, 231, 227));
|
||||
lightPalette.setColor(QPalette::ToolTipBase, QColor(255, 255, 220));
|
||||
lightPalette.setColor(QPalette::ToolTipText, QColor(0, 0, 0));
|
||||
lightPalette.setColor(QPalette::Text, QColor(0, 0, 0));
|
||||
lightPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(120, 120, 120));
|
||||
lightPalette.setColor(QPalette::Dark, QColor(160, 160, 160));
|
||||
lightPalette.setColor(QPalette::Shadow, QColor(105, 105, 105));
|
||||
lightPalette.setColor(QPalette::Button, QColor(240, 240, 240));
|
||||
lightPalette.setColor(QPalette::ButtonText, QColor(0, 0, 0));
|
||||
lightPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(120, 120, 120));
|
||||
lightPalette.setColor(QPalette::BrightText, QColor(0, 0, 255));
|
||||
lightPalette.setColor(QPalette::Link, QColor(51, 153, 255));
|
||||
lightPalette.setColor(QPalette::Highlight, QColor(0, 0, 255));
|
||||
lightPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(51, 153, 255));
|
||||
lightPalette.setColor(QPalette::HighlightedText, QColor(255, 255, 255));
|
||||
lightPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(255, 255, 255));
|
||||
|
||||
qApp->setPalette(lightPalette);
|
||||
|
||||
setThemeStyleSheet(false /*dark*/);
|
||||
}
|
||||
|
||||
FramelessWindow::FramelessWindow(QWidget* parent) : QWidget(parent), ui(new Ui::FramelessWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
FramelessWindow::~FramelessWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
CentralWidget::CentralWidget(QWidget* parent) : QMainWindow(parent)
|
||||
CentralWidget::CentralWidget(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
NavigationBarWidget* navigationBarWidget = new NavigationBarWidget();
|
||||
|
||||
QHBoxLayout* tabBarLayout = new QHBoxLayout(ui.tabWidget);
|
||||
tabBarLayout->setSpacing(0);
|
||||
tabBarLayout->setMargin(0);
|
||||
tabBarLayout->addWidget(navigationBarWidget, 0, Qt::AlignTop | Qt::AlignHCenter);
|
||||
|
||||
QObject::connect(navigationBarWidget->tabs, &QtMaterialTabs::currentChanged, ui.tabWidget, &QTabWidget::setCurrentIndex);
|
||||
QObject::connect(ui.tabWidget, &QTabWidget::currentChanged,
|
||||
ui.rendererWidget, &Renderer::RendererWidget::currentTabChanged);
|
||||
NavigationBarWidget* navigationBarWidget = new NavigationBarWidget(this);
|
||||
ui.gridLayout->addWidget(navigationBarWidget, 0, 0, 1, 1, Qt::AlignTop | Qt::AlignHCenter);
|
||||
QObject::connect(navigationBarWidget->tabs, &QtMaterialTabs::currentChanged, ui.stackedWidget, &QStackedWidget::setCurrentIndex);
|
||||
QObject::connect(ui.stackedWidget, &QStackedWidget::currentChanged, ui.rendererWidget, &Renderer::RendererWidget::currentTabChanged);
|
||||
}
|
||||
|
||||
CentralWidget::~CentralWidget()
|
||||
|
@ -133,38 +36,29 @@ MainWindow::MainWindow(QWidget* parent, const Qt::WindowFlags flags)
|
|||
m_titleBar->maximizeButton()->setFixedHeight(kTitleBarHeight);
|
||||
m_titleBar->closeButton()->setFixedHeight(kTitleBarHeight);
|
||||
m_titleBar->setTitleFont(QFont(QString("Segoe UI, Microsoft YaHei UI"), 10));
|
||||
m_titleBar->chromePalette()->setTitleBarActiveBackgroundColor(QColor(0,0,0,0));
|
||||
m_titleBar->chromePalette()->setTitleBarActiveBackgroundColor(QColor(0, 0, 0, 0));
|
||||
m_titleBar->chromePalette()->setTitleBarInactiveBackgroundColor(QColor(0, 0, 0, 0));
|
||||
|
||||
m_window = new FramelessWindow(this);
|
||||
m_central_widget = new CentralWidget(this);
|
||||
m_window->ui->windowContent->layout()->addWidget(m_central_widget);
|
||||
|
||||
setMenuWidget(m_titleBar);
|
||||
setCentralWidget(m_window);
|
||||
setCentralWidget(m_central_widget);
|
||||
|
||||
FramelessWidgetsHelper* helper = FramelessWidgetsHelper::get(this);
|
||||
helper->setTitleBarWidget(m_titleBar);
|
||||
#ifndef Q_OS_MACOS
|
||||
helper->setSystemButton(m_titleBar->minimizeButton(), Global::SystemButtonType::Minimize);
|
||||
helper->setSystemButton(m_titleBar->maximizeButton(), Global::SystemButtonType::Maximize);
|
||||
helper->setSystemButton(m_titleBar->closeButton(), Global::SystemButtonType::Close);
|
||||
#endif // Q_OS_MACOS
|
||||
|
||||
connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper]() {
|
||||
helper->moveWindowToDesktopCenter();
|
||||
|
||||
});
|
||||
|
||||
//connect(helper, &FramelessWidgetsHelper::ready, this, [this, helper]() {
|
||||
// helper->moveWindowToDesktopCenter();
|
||||
// });
|
||||
|
||||
setWindowIcon(QIcon(":/images/icon.png"));
|
||||
setWindowTitle("ArchitectureColoredPainting");
|
||||
|
||||
|
||||
resize(m_central_widget->size());
|
||||
//setCentralWidget(m_window);
|
||||
|
||||
//move(QGuiApplication::primaryScreen()->availableGeometry().center() - rect().center());
|
||||
move(QGuiApplication::primaryScreen()->availableGeometry().center() - rect().center());
|
||||
|
||||
}
|
||||
|
||||
|
@ -178,6 +72,5 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
|||
|
||||
if (result != QMessageBox::Yes)
|
||||
event->ignore();*/
|
||||
qDebug() << "closeEvent";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include "ui_MainWindow.h"
|
||||
#include "ui_FramelessWindow.h"
|
||||
|
||||
#include <FramelessHelper/Widgets/framelessmainwindow.h>
|
||||
|
||||
|
@ -10,20 +9,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class StandardTitleBar;
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
|
||||
class FramelessWindow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FramelessWindow(QWidget* parent = nullptr);
|
||||
|
||||
~FramelessWindow();
|
||||
|
||||
Ui::FramelessWindow* ui;
|
||||
};
|
||||
|
||||
|
||||
class CentralWidget : public QMainWindow
|
||||
class CentralWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -46,10 +32,7 @@ public:
|
|||
private:
|
||||
FRAMELESSHELPER_PREPEND_NAMESPACE(StandardTitleBar)* m_titleBar = nullptr;
|
||||
Ui::MainWindowClass ui;
|
||||
CentralWidget* m_central_widget = nullptr;
|
||||
|
||||
|
||||
void closeEvent(QCloseEvent* event);
|
||||
|
||||
FramelessWindow* m_window;
|
||||
CentralWidget* m_central_widget;
|
||||
void closeEvent(QCloseEvent * event);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "NavigationBarWidget.h"
|
||||
#include <qtmaterialraisedbutton.h>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDebug>
|
||||
|
||||
NavigationBarWidget::NavigationBarWidget(QWidget *parent)
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <QWidget>
|
||||
#include <QButtonGroup>
|
||||
#include <qtmaterialtabs.h>
|
||||
#include "ui_NavigationBarWidget.h"
|
||||
|
||||
class NavigationBarWidget : public QWidget
|
||||
{
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
#pragma once
|
||||
#include <QOpenGLFunctions_4_5_Core>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <vector>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLWidget>
|
||||
#include <assimp/vector3.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include "Drawable.h"
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
struct Vertex
|
||||
{
|
||||
QVector3D Position;
|
||||
QVector3D Normal;
|
||||
QVector2D TexCoords;
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Normal;
|
||||
glm::vec2 TexCoords;
|
||||
Vertex(const aiVector3D& position, const aiVector3D& Normal, const aiVector3D& TexCoords);
|
||||
};
|
||||
|
||||
|
@ -38,8 +37,8 @@ namespace Renderer
|
|||
class Mesh : public Drawable
|
||||
{
|
||||
public:
|
||||
QVector<Vertex> vertices;
|
||||
QVector<unsigned int> indices;
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
//QVector<Texture*> textures;
|
||||
GLuint textureBasecolor = 0;
|
||||
GLuint textureMetallicRoughness = 0;
|
||||
|
|
|
@ -45,26 +45,50 @@ void Model::drawShadow() {
|
|||
|
||||
void Renderer::Model::loadModel(QString path)
|
||||
{
|
||||
directory = path;
|
||||
QFileInfo modelFile(path);
|
||||
name = modelFile.baseName();
|
||||
directory = modelFile.dir();
|
||||
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||
const aiScene* scene = importer.ReadFile(modelFile.absoluteFilePath().toUtf8(), aiProcess_Triangulate /*| aiProcess_FlipUVs*/);
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
{
|
||||
qDebug() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
|
||||
qCritical() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
|
||||
return;
|
||||
}
|
||||
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
||||
qDebug() << modelFile.absoluteFilePath() << "Loaded Successfully";
|
||||
qDebug() << "NumMeshes: " << scene->mNumMeshes;
|
||||
qDebug() << "NumMaterials: " << scene->mNumMaterials;
|
||||
qDebug() << "NumTextures: " << scene->mNumTextures;
|
||||
directory.cdUp();
|
||||
|
||||
if (QFile paintingConfigFile(directory.filePath(name + ".txt")); paintingConfigFile.open(QFile::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
paintingMap.clear();
|
||||
QTextStream stream(&paintingConfigFile);
|
||||
while (!stream.atEnd())
|
||||
{
|
||||
QString source, target;
|
||||
glm::vec2 leftBottom, rightTop;
|
||||
stream >> source >> target >> leftBottom.x >> leftBottom.y >> rightTop.x >> rightTop.y;
|
||||
qDebug() << source << target << leftBottom.x << leftBottom.y << rightTop.x << rightTop.y;
|
||||
paintingMap.emplace(source.toStdString(), std::forward_as_tuple(target.toStdString(), leftBottom, rightTop));
|
||||
}
|
||||
paintingConfigFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "Painting Config Not Found!";
|
||||
}
|
||||
|
||||
minX = std::numeric_limits<float>::max();
|
||||
maxX = std::numeric_limits<float>::min();
|
||||
minY = std::numeric_limits<float>::max();
|
||||
maxY = std::numeric_limits<float>::min();
|
||||
minZ = std::numeric_limits<float>::max();
|
||||
maxZ = std::numeric_limits<float>::min();
|
||||
processNode(scene->mRootNode, scene);
|
||||
aiMatrix4x4 transform;
|
||||
aiMatrix4x4::Scaling(aiVector3D(1 / 0.008), transform);
|
||||
processNode(scene->mRootNode, scene, transform * scene->mRootNode->mTransformation);
|
||||
AABB.push_back(QVector3D(minX, minY, minZ));
|
||||
AABB.push_back(QVector3D(minX, minY, maxZ));
|
||||
AABB.push_back(QVector3D(minX, maxY, minZ));
|
||||
|
@ -93,86 +117,77 @@ void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4)
|
|||
|
||||
std::unique_ptr<Drawable> Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
|
||||
{
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
QMatrix4x4 modelQ((float*)&model);
|
||||
|
||||
aiString str;
|
||||
material->GetTexture(aiTextureType_BASE_COLOR, 0, &str);
|
||||
|
||||
if (paintingProgram != nullptr && (std::strcmp(str.C_Str(), "17876391417123941155.jpg") == 0 || std::strcmp(str.C_Str(), "11474523244911310074.jpg") == 0))
|
||||
{
|
||||
qDebug() << str.C_Str() << "Replaced";
|
||||
// 初始化网格
|
||||
auto m_mesh = std::make_unique<PaintingMesh>(glFunc, paintingProgram, shadowProgram, modelQ);
|
||||
// 遍历网格的每个顶点
|
||||
std::vector<Vertex> vertices;
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
if (mesh->mNormals && mesh->mTextureCoords[0])
|
||||
{
|
||||
Vertex vertex(mesh->mVertices[i], mesh->mNormals[i], mesh->mTextureCoords[0][i]);
|
||||
minX = std::min(minX, vertex.Position.x());
|
||||
maxX = std::max(maxX, vertex.Position.x());
|
||||
minY = std::min(minY, vertex.Position.y());
|
||||
maxY = std::max(maxY, vertex.Position.y());
|
||||
minZ = std::min(minZ, vertex.Position.z());
|
||||
maxZ = std::max(maxZ, vertex.Position.z());
|
||||
m_mesh->vertices.push_back(vertex);
|
||||
auto pos = mesh->mVertices[i];
|
||||
vertices.push_back(Vertex(pos, mesh->mNormals[i], mesh->mTextureCoords[0][i]));
|
||||
auto worldPos = model * pos;
|
||||
minX = std::min(minX, worldPos.x);
|
||||
maxX = std::max(maxX, worldPos.x);
|
||||
minY = std::min(minY, worldPos.y);
|
||||
maxY = std::max(maxY, worldPos.y);
|
||||
minZ = std::min(minZ, worldPos.z);
|
||||
maxZ = std::max(maxZ, worldPos.z);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
std::vector<unsigned int> indices;
|
||||
for (auto face = mesh->mFaces; face < mesh->mFaces + mesh->mNumFaces; face++)
|
||||
indices.insert(indices.end(), face->mIndices, face->mIndices + face->mNumIndices);
|
||||
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
|
||||
if (auto iter = paintingMap.find([&] {
|
||||
aiString str;
|
||||
material->GetTexture(aiTextureType_BASE_COLOR, 0, &str);
|
||||
return std::string(str.C_Str());
|
||||
}()); paintingProgram != nullptr && iter != paintingMap.end())
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
// 将所有面的索引数据添加到索引数组中
|
||||
for (unsigned int j = 0; j < face.mNumIndices; j++) {
|
||||
m_mesh->indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
qDebug() << iter->first.c_str() << "Replaced";
|
||||
|
||||
auto mesh = std::make_unique<PaintingMesh>(glFunc, paintingProgram, shadowProgram, modelQ);
|
||||
|
||||
auto& [paintingPath, leftBottom, rightTop] = iter->second;
|
||||
|
||||
for (auto& v : vertices)
|
||||
{
|
||||
//qDebug() << v.TexCoords.x << v.TexCoords.y;
|
||||
v.TexCoords = (v.TexCoords - leftBottom) / (rightTop - leftBottom);
|
||||
qDebug() << v.TexCoords.x << v.TexCoords.y;
|
||||
}
|
||||
|
||||
m_mesh->paintingId = loadPainting(std::string(str.C_Str()));
|
||||
auto& handle = vtManager->getPaintingHandle(m_mesh->paintingId);
|
||||
m_mesh->textureBasecolor = handle.baseColor;
|
||||
m_mesh->textureMetallicRoughness = handle.metallicRoughness;
|
||||
m_mesh->setupMesh();
|
||||
return m_mesh;
|
||||
mesh->vertices = vertices;
|
||||
mesh->indices = indices;
|
||||
|
||||
mesh->paintingId = loadPainting(paintingPath);
|
||||
auto& handle = vtManager->getPaintingHandle(mesh->paintingId);
|
||||
mesh->textureBasecolor = handle.baseColor;
|
||||
mesh->textureMetallicRoughness = handle.metallicRoughness;
|
||||
mesh->setupMesh();
|
||||
return mesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 初始化网格
|
||||
auto m_mesh = std::make_unique<Mesh>(glFunc, shaderProgram, shadowProgram, modelQ);
|
||||
// 遍历网格的每个顶点
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
if (mesh->mNormals && mesh->mTextureCoords[0])
|
||||
{
|
||||
Vertex vertex(mesh->mVertices[i], mesh->mNormals[i], mesh->mTextureCoords[0][i]);
|
||||
minX = std::min(minX, vertex.Position.x());
|
||||
maxX = std::max(maxX, vertex.Position.x());
|
||||
minY = std::min(minY, vertex.Position.y());
|
||||
maxY = std::max(maxY, vertex.Position.y());
|
||||
minZ = std::min(minZ, vertex.Position.z());
|
||||
maxZ = std::max(maxZ, vertex.Position.z());
|
||||
m_mesh->vertices.push_back(vertex);
|
||||
}
|
||||
}
|
||||
auto mesh = std::make_unique<Mesh>(glFunc, shaderProgram, shadowProgram, modelQ);
|
||||
mesh->vertices = vertices;
|
||||
mesh->indices = indices;
|
||||
|
||||
// 将所有面的索引数据添加到索引数组中
|
||||
for (auto face = mesh->mFaces; face < mesh->mFaces + mesh->mNumFaces; face++)
|
||||
for (auto indice = face->mIndices; indice < face->mIndices + face->mNumIndices; indice++)
|
||||
m_mesh->indices.push_back(*indice);
|
||||
|
||||
// 处理材质
|
||||
if (!(m_mesh->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR)))
|
||||
if (!(mesh->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR)))
|
||||
qWarning() << "Basecolor Texture Loading Failed!";
|
||||
if (!(m_mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS)))
|
||||
if (!(mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS)))
|
||||
qWarning() << "MetallicRoughness Texture Loading Failed!";
|
||||
if (!(m_mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS)))
|
||||
if (!(mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS)))
|
||||
qWarning() << "Normal Texture Loading Failed!";
|
||||
|
||||
if (m_mesh->textureBasecolor && m_mesh->textureMetallicRoughness && m_mesh->textureNormal)
|
||||
if (mesh->textureBasecolor && mesh->textureMetallicRoughness && mesh->textureNormal)
|
||||
{
|
||||
m_mesh->setupMesh();
|
||||
return m_mesh;
|
||||
mesh->setupMesh();
|
||||
return mesh;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
|
@ -203,7 +218,7 @@ GLuint Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type)
|
|||
texture.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
|
||||
texture.setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
|
||||
texture.setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
||||
texture.setData(data);
|
||||
texture.setData(data.mirrored());
|
||||
return texture.textureId();
|
||||
}
|
||||
|
||||
|
@ -250,7 +265,7 @@ GLuint Renderer::Model::loadPainting(std::string path)
|
|||
};
|
||||
Painting painting;
|
||||
|
||||
if (path == "17876391417123941155.jpg")
|
||||
if (path == "0.json")
|
||||
{
|
||||
painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,-0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
|
@ -266,7 +281,6 @@ GLuint Renderer::Model::loadPainting(std::string path)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
painting.generateBuffers(glFunc);
|
||||
|
||||
auto index = vtManager->createVirtualTexture(painting);
|
||||
|
|
|
@ -17,20 +17,24 @@ namespace Renderer
|
|||
void loadModel(QString path);
|
||||
Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, VirtualTextureManager* vtManager);
|
||||
private:
|
||||
QOpenGLContext* context;
|
||||
QOpenGLContext* context = nullptr;
|
||||
QOpenGLFunctions_4_5_Core* glFunc = nullptr;
|
||||
QOpenGLShaderProgram* shaderProgram = nullptr;
|
||||
QOpenGLShaderProgram* paintingProgram = nullptr;
|
||||
QOpenGLShaderProgram* shadowProgram = nullptr;
|
||||
VirtualTextureManager* vtManager = nullptr;
|
||||
|
||||
/* 模型数据 */
|
||||
/**
|
||||
* @param key BaseColor路径
|
||||
* @param value json路径, 纹理坐标
|
||||
*/
|
||||
std::unordered_map<std::string, std::tuple<std::string, glm::vec2, glm::vec2>> paintingMap;
|
||||
std::unordered_map<std::string, GLuint> paintingLoaded;
|
||||
std::unordered_map<std::string, QOpenGLTexture> texturesLoaded;
|
||||
std::vector<std::unique_ptr<Drawable>> meshes;
|
||||
|
||||
/// 模型所在路径
|
||||
QDir directory;
|
||||
QDir directory; /// 模型所在路径
|
||||
QString name; /// 模型文件名
|
||||
|
||||
float minX, maxX, minY, maxY, minZ, maxZ;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Renderer
|
|||
public:
|
||||
virtual MaterialStyleType type() const = 0;
|
||||
virtual std::vector<GLfloat> encoded() const = 0;
|
||||
virtual std::unique_ptr<MaterialStyle> clone() const = 0;
|
||||
virtual bool operator==(const MaterialStyle&) const = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,11 @@ std::vector<GLfloat> Renderer::FillPlain::encoded() const
|
|||
glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF())))};
|
||||
}
|
||||
|
||||
std::unique_ptr<MaterialFill> Renderer::FillPlain::clone() const
|
||||
{
|
||||
return std::make_unique<FillPlain>(*this);
|
||||
}
|
||||
|
||||
bool Renderer::FillPlain::operator==(const MaterialFill& m) const
|
||||
{
|
||||
return type() == m.type()
|
||||
|
@ -42,6 +47,11 @@ std::vector<GLfloat> Renderer::MaterialStyleFill::encoded() const
|
|||
return materialFill->encoded();
|
||||
}
|
||||
|
||||
std::unique_ptr<MaterialStyle> Renderer::MaterialStyleFill::clone() const
|
||||
{
|
||||
return std::make_unique<MaterialStyleFill>(materialFill->clone());
|
||||
}
|
||||
|
||||
bool Renderer::MaterialStyleFill::operator==(const MaterialStyle& m) const
|
||||
{
|
||||
return type() == m.type() && *materialFill == *static_cast<const MaterialStyleFill&>(m).materialFill;
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Renderer
|
|||
public:
|
||||
virtual MaterialFillType type() const = 0;
|
||||
virtual std::vector<GLfloat> encoded() const = 0;
|
||||
virtual std::unique_ptr<MaterialFill> clone() const = 0;
|
||||
virtual bool operator==(const MaterialFill&) const = 0;
|
||||
};
|
||||
|
||||
|
@ -19,6 +20,7 @@ namespace Renderer
|
|||
FillPlain(QColor color, float metallic, float roughness);
|
||||
virtual MaterialFillType type() const override;
|
||||
virtual std::vector<GLfloat> encoded() const override;
|
||||
virtual std::unique_ptr<MaterialFill> clone() const override;
|
||||
virtual bool operator==(const MaterialFill&) const override;
|
||||
|
||||
QColor color;
|
||||
|
@ -32,8 +34,9 @@ namespace Renderer
|
|||
MaterialStyleFill(std::shared_ptr<MaterialFill> materialFill);
|
||||
virtual MaterialStyleType type() const override;
|
||||
virtual std::vector<GLfloat> encoded() const override;
|
||||
virtual std::unique_ptr<MaterialStyle> clone() const override;
|
||||
virtual bool operator==(const MaterialStyle&) const override;
|
||||
protected:
|
||||
//protected:
|
||||
std::shared_ptr<MaterialFill> materialFill;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,11 @@ MaterialStrokeType Renderer::StrokePlain::type() const
|
|||
return MaterialStrokeType::kPlain;
|
||||
}
|
||||
|
||||
std::unique_ptr<MaterialStroke> Renderer::StrokePlain::clone() const
|
||||
{
|
||||
return std::make_unique<StrokePlain>(*this);
|
||||
}
|
||||
|
||||
std::vector<GLfloat> Renderer::StrokePlain::encoded() const
|
||||
{
|
||||
return { glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(material.toVec().second, 0.f, 0.f))),
|
||||
|
@ -58,6 +63,11 @@ std::vector<GLfloat> Renderer::StrokeRadialGradient::encoded() const
|
|||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<MaterialStroke> Renderer::StrokeRadialGradient::clone() const
|
||||
{
|
||||
return std::make_unique<StrokeRadialGradient>(*this);
|
||||
}
|
||||
|
||||
bool Renderer::StrokeRadialGradient::operator==(const MaterialStroke& m) const
|
||||
{
|
||||
return type() == m.type()
|
||||
|
@ -87,6 +97,11 @@ std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const
|
|||
return v;
|
||||
}
|
||||
|
||||
std::unique_ptr<MaterialStyle> Renderer::MaterialStyleStroke::clone() const
|
||||
{
|
||||
return std::make_unique<MaterialStyleStroke>(halfWidth*2, strokeType, endType, materialStroke->clone());
|
||||
}
|
||||
|
||||
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
|
||||
{
|
||||
return type() == m.type() && *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke;
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace Renderer
|
|||
public:
|
||||
virtual MaterialStrokeType type() const = 0;
|
||||
virtual std::vector<GLfloat> encoded() const = 0;
|
||||
virtual std::unique_ptr<MaterialStroke> clone() const = 0;
|
||||
virtual bool operator==(const MaterialStroke&) const = 0;
|
||||
};
|
||||
|
||||
|
@ -20,7 +21,9 @@ namespace Renderer
|
|||
StrokePlain(QColor color, float metallic, float roughness);
|
||||
StrokePlain(const Material& material);
|
||||
virtual MaterialStrokeType type() const override;
|
||||
virtual std::unique_ptr<MaterialStroke> clone() const override;
|
||||
virtual std::vector<GLfloat> encoded() const override;
|
||||
|
||||
virtual bool operator==(const MaterialStroke&) const override;
|
||||
|
||||
Material material;
|
||||
|
@ -32,6 +35,7 @@ namespace Renderer
|
|||
StrokeRadialGradient(const std::map<float, Material>& materialMap, bool gradual);
|
||||
virtual MaterialStrokeType type() const override;
|
||||
virtual std::vector<GLfloat> encoded() const override;
|
||||
virtual std::unique_ptr<MaterialStroke> clone() const override;
|
||||
virtual bool operator==(const MaterialStroke&) const override;
|
||||
|
||||
std::map<float, Material> materialMap;
|
||||
|
@ -47,9 +51,10 @@ namespace Renderer
|
|||
MaterialStyleStroke(float width, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke);
|
||||
virtual MaterialStyleType type() const override;
|
||||
virtual std::vector<GLfloat> encoded() const override;
|
||||
virtual std::unique_ptr<MaterialStyle> clone() const override;
|
||||
virtual bool operator==(const MaterialStyle&) const override;
|
||||
float getHalfWidth() const;
|
||||
protected:
|
||||
//protected:
|
||||
float halfWidth;
|
||||
StrokeType strokeType;
|
||||
StrokeEndType endType;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include <QOpenGLFunctions_4_5_Core>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <vector>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
@ -18,8 +18,8 @@ namespace Renderer
|
|||
class PaintingMesh : public Drawable
|
||||
{
|
||||
public:
|
||||
QVector<Vertex> vertices;
|
||||
QVector<GLuint> indices;
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<GLuint> indices;
|
||||
GLuint textureBasecolor;
|
||||
GLuint textureMetallicRoughness;
|
||||
QMatrix4x4 model;
|
||||
|
|
|
@ -12,22 +12,6 @@
|
|||
#include "../Painting/MaterialStyleStroke.h"
|
||||
using namespace Renderer;
|
||||
|
||||
Renderer::ElementRenderer::ElementRenderer(QOpenGLWidget* glWidget)
|
||||
: glWidget(glWidget)
|
||||
{
|
||||
}
|
||||
|
||||
void Renderer::ElementRenderer::initialize()
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
shader = std::make_unique<QOpenGLShaderProgram>();
|
||||
if (!shader->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/element.comp"))
|
||||
qDebug() << "ERROR: " << shader->log();
|
||||
if (!shader->link())
|
||||
qDebug() << "ERROR: " << shader->log();
|
||||
|
||||
}
|
||||
|
||||
std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
|
||||
{
|
||||
std::vector<glm::vec2> pathBuffer;
|
||||
|
@ -130,27 +114,51 @@ QRectF calcBoundingRect(const QPainterPath& path, const std::vector<BaseStyle>&
|
|||
return QRectF(QPointF(leftTop.x, leftTop.y), QPointF(rightBottom.x, rightBottom.y));
|
||||
}
|
||||
|
||||
std::pair<QImage, QPointF> Renderer::ElementRenderer::drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio, bool releaseContext)
|
||||
Renderer::ElementRenderer::ElementRenderer()
|
||||
{
|
||||
auto baseStyles = style.toBaseStyles();
|
||||
QRectF bound = calcBoundingRect(path, baseStyles);
|
||||
surface.create();
|
||||
thread = std::jthread([&](std::stop_token stop) {
|
||||
std::stop_callback cb(stop, [&] {
|
||||
draw.notify_all();
|
||||
});
|
||||
|
||||
QOpenGLContext context;
|
||||
context.create();
|
||||
context.makeCurrent(&surface);
|
||||
|
||||
auto gl = context.versionFunctions<QOpenGLFunctions_4_5_Core>();
|
||||
shader = std::make_unique<QOpenGLShaderProgram>();
|
||||
if (!shader->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/element.comp"))
|
||||
qDebug() << "ERROR: " << shader->log();
|
||||
if (!shader->link())
|
||||
qDebug() << "ERROR: " << shader->log();
|
||||
|
||||
initialized = true;
|
||||
|
||||
while (!stop.stop_requested())
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(drawMutex);
|
||||
draw.wait(lock, [&] {return needDraw || stop.stop_requested(); });
|
||||
if (needDraw)
|
||||
{
|
||||
needDraw = false;
|
||||
auto baseStyles = style->toBaseStyles();
|
||||
QRectF bound = calcBoundingRect(*path, baseStyles);
|
||||
QPointF leftTop = bound.topLeft();
|
||||
QSize size(ceil(bound.width() * pixelRatio), ceil(bound.height() * pixelRatio));
|
||||
|
||||
auto pathBuffer = generatePathBuffer(path);
|
||||
auto pathBuffer = generatePathBuffer(*path);
|
||||
auto styleBuffer = generateStyleBuffer(baseStyles);
|
||||
|
||||
if (releaseContext) glWidget->makeCurrent();
|
||||
|
||||
GLuint ssbo[2];
|
||||
glCreateBuffers(2, ssbo);
|
||||
glNamedBufferData(ssbo[0], pathBuffer.size() * sizeof(glm::vec2), pathBuffer.data(), GL_STATIC_READ);
|
||||
glNamedBufferData(ssbo[1], styleBuffer.size() * sizeof(GLfloat), styleBuffer.data(), GL_STATIC_READ);
|
||||
gl->glCreateBuffers(2, ssbo);
|
||||
gl->glNamedBufferData(ssbo[0], pathBuffer.size() * sizeof(glm::vec2), pathBuffer.data(), GL_STATIC_READ);
|
||||
gl->glNamedBufferData(ssbo[1], styleBuffer.size() * sizeof(GLfloat), styleBuffer.data(), GL_STATIC_READ);
|
||||
|
||||
auto fbo = QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D);
|
||||
fbo.bind();
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
gl->glClearColor(0, 0, 0, 0);
|
||||
gl->glClear(GL_COLOR_BUFFER_BIT);
|
||||
fbo.release();
|
||||
|
||||
shader->bind();
|
||||
|
@ -158,14 +166,42 @@ std::pair<QImage, QPointF> Renderer::ElementRenderer::drawElement(const QPainter
|
|||
shader->setUniformValue("styleSize", (GLint)styleBuffer.size());
|
||||
shader->setUniformValue("leftTop", leftTop);
|
||||
shader->setUniformValue("pixelRatio", pixelRatio);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 10, ssbo[0]);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 11, ssbo[1]);
|
||||
glBindImageTexture(0, fbo.texture(), 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
||||
glDispatchCompute(ceil(size.width() / 8.), ceil(size.height() / 8.), 1);
|
||||
gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 10, ssbo[0]);
|
||||
gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 11, ssbo[1]);
|
||||
gl->glBindImageTexture(0, fbo.texture(), 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
||||
gl->glDispatchCompute(ceil(size.width() / 8.), ceil(size.height() / 8.), 1);
|
||||
shader->release();
|
||||
|
||||
auto image = fbo.toImage(false);
|
||||
glDeleteBuffers(2, ssbo);
|
||||
if (releaseContext) glWidget->doneCurrent();
|
||||
return { image, leftTop };
|
||||
gl->glDeleteBuffers(2, ssbo);
|
||||
result = { image, leftTop };
|
||||
drawFinished = true;
|
||||
}
|
||||
draw.notify_all();
|
||||
}
|
||||
context.doneCurrent();
|
||||
});
|
||||
|
||||
while (!initialized)
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
ElementRenderer* Renderer::ElementRenderer::instance()
|
||||
{
|
||||
static ElementRenderer renderer;
|
||||
return &renderer;
|
||||
}
|
||||
|
||||
std::pair<QImage, QPointF> Renderer::ElementRenderer::drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(drawMutex);
|
||||
draw.wait(lock, [&] {return drawFinished; });
|
||||
drawFinished = false;
|
||||
this->path = &path;
|
||||
this->style = &style;
|
||||
this->pixelRatio = pixelRatio;
|
||||
needDraw = true;
|
||||
draw.notify_all();
|
||||
draw.wait(lock, [&] {return drawFinished; });
|
||||
return result;
|
||||
}
|
|
@ -3,32 +3,40 @@
|
|||
#include <QOpenGLFunctions_4_5_Core>
|
||||
#include <QOPenGLShaderProgram>
|
||||
#include "../Painting/ElementStyle.h"
|
||||
#include <QOffscreenSurface>
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
class ElementRenderer : protected QOpenGLFunctions_4_5_Core
|
||||
class ElementRenderer
|
||||
{
|
||||
public:
|
||||
ElementRenderer(QOpenGLWidget* glWidget);
|
||||
|
||||
/**
|
||||
* @brief 须在initializeGL函数中调用
|
||||
*/
|
||||
void initialize();
|
||||
static ElementRenderer* instance();
|
||||
|
||||
/**
|
||||
* @brief 将图元绘制到QImage
|
||||
* @param path 图元几何数据
|
||||
* @param style 图元样式
|
||||
* @param pixelRatio path中的单位坐标对应的像素大小
|
||||
* @param releaseContext 若在initializeGL, resizeGL或paintGL中调用须传入false
|
||||
* @return QImage 绘制得到的位图
|
||||
* @return QPointF 位图原点(左上角)在QPainterPath坐标系下的坐标
|
||||
*/
|
||||
std::pair<QImage, QPointF> drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio, bool releaseContext = true);
|
||||
std::pair<QImage, QPointF> drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio);
|
||||
protected:
|
||||
QOpenGLWidget* glWidget;
|
||||
std::unique_ptr<QOpenGLShaderProgram> shader;
|
||||
std::jthread thread;
|
||||
QOffscreenSurface surface;
|
||||
QOpenGLContext context;
|
||||
std::atomic<bool> initialized = false;
|
||||
bool drawFinished = true;
|
||||
bool needDraw = false;
|
||||
std::condition_variable draw;
|
||||
std::mutex drawMutex;
|
||||
const QPainterPath* path;
|
||||
const ElementStyle* style;
|
||||
float pixelRatio;
|
||||
std::pair<QImage, QPointF> result;
|
||||
|
||||
ElementRenderer();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -73,17 +73,14 @@ void RendererGLWidget::stopTimer()
|
|||
timerId = -1;
|
||||
}
|
||||
|
||||
void RendererGLWidget::setModel()
|
||||
void RendererGLWidget::setModel(QString path)
|
||||
{
|
||||
makeCurrent();
|
||||
model->loadModel("Models/Sponza/Sponza.gltf");
|
||||
//model = new Model("E:\\3D Objects\\gallery_gltf\\gallery_gltf.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper);
|
||||
//model->loadModel("Models/Sponza/Sponza.gltf");
|
||||
//model->loadModel("E:\\3D Objects\\Gate\\gltf\\Gate.gltf");
|
||||
model->loadModel(path);
|
||||
light.model = model;
|
||||
qDebug() << model->AABB;
|
||||
//paintingHelper->allocateBuffers();
|
||||
//paintingCompProgramPtr->bind();
|
||||
//paintingHelper->bindPaintingBuffers();
|
||||
//paintingCompProgramPtr->release();
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Renderer
|
|||
void startTimer();
|
||||
void stopTimer();
|
||||
public slots:
|
||||
void setModel();
|
||||
void setModel(QString path);
|
||||
void setMainLightPitch(float pitch);
|
||||
void setMainLightYaw(float yaw);
|
||||
void setExposure(float exposure);
|
||||
|
|
|
@ -1,29 +1,62 @@
|
|||
#include "RendererWidget.h"
|
||||
#include "RendererGLWidget.h"
|
||||
using namespace Renderer;
|
||||
RendererWidget::RendererWidget(QWidget *parent)
|
||||
#include "../FluentMenu.h"
|
||||
#include <QFileDialog>
|
||||
|
||||
Renderer::RendererWidget::RendererWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
FluentMenu* menu = new FluentMenu(this);
|
||||
auto openAction = new QAction(QStringLiteral("´ò¿ª"), menu);
|
||||
auto saveAction = new QAction(QStringLiteral("±£´æ"), menu);
|
||||
auto testAction = new QAction(QStringLiteral("²âÊÔ"), menu);
|
||||
menu->addAction(openAction);
|
||||
menu->addAction(saveAction);
|
||||
menu->addAction(testAction);
|
||||
|
||||
ui.openButton->setHaloVisible(false);
|
||||
ui.openButton->setOverlayStyle(::Material::TintedOverlay);
|
||||
ui.openButton->setCheckable(true);
|
||||
|
||||
QObject::connect(menu, &QMenu::aboutToShow, [&]() {
|
||||
ui.openButton->setChecked(true);
|
||||
});
|
||||
QObject::connect(menu, &QMenu::aboutToHide, [&]() {
|
||||
ui.openButton->setChecked(false);
|
||||
});
|
||||
QObject::connect(ui.openButton, &QPushButton::clicked, [&, menu]() {
|
||||
menu->exec(ui.openButton->mapToGlobal(QPoint(-menu->shadowRadius, ui.openButton->height() - menu->shadowRadius)));
|
||||
});
|
||||
|
||||
QObject::connect(ui.horizontalSlider, &QSlider::valueChanged,
|
||||
ui.openGLWidget, &RendererGLWidget::setMainLightPitch);
|
||||
ui.openGLWidget, &Renderer::RendererGLWidget::setMainLightPitch);
|
||||
QObject::connect(ui.horizontalSlider_2, &QSlider::valueChanged,
|
||||
ui.openGLWidget, &RendererGLWidget::setMainLightYaw);
|
||||
ui.openGLWidget, &Renderer::RendererGLWidget::setMainLightYaw);
|
||||
QObject::connect(ui.exposureSlider, &QSlider::valueChanged, [&](int value) {
|
||||
ui.openGLWidget->setExposure(value/100.f);
|
||||
ui.openGLWidget->setExposure(value / 100.f);
|
||||
});
|
||||
|
||||
QObject::connect(openAction, &QAction::triggered, [&] {
|
||||
QString fileName = QFileDialog::getOpenFileName(this, QStringLiteral("´ò¿ªÄ£ÐÍ"), QString(), QStringLiteral("glTF 2.0 (*.gltf)"));
|
||||
qDebug() << fileName;
|
||||
if (fileName != QString())
|
||||
ui.openGLWidget->setModel(fileName);
|
||||
});
|
||||
QObject::connect(testAction, &QAction::triggered, [&] {
|
||||
ui.openGLWidget->setModel("Models/Sponza/Sponza.gltf");
|
||||
});
|
||||
|
||||
ui.horizontalSlider->setValue(105);
|
||||
ui.horizontalSlider_2->setValue(80);
|
||||
ui.exposureSlider->setValue(60);
|
||||
QObject::connect(ui.openButton, &QPushButton::clicked,
|
||||
ui.openGLWidget, &RendererGLWidget::setModel);
|
||||
}
|
||||
|
||||
RendererWidget::~RendererWidget()
|
||||
Renderer::RendererWidget::~RendererWidget()
|
||||
{}
|
||||
|
||||
void RendererWidget::currentTabChanged(int index)
|
||||
void Renderer::RendererWidget::currentTabChanged(int index)
|
||||
{
|
||||
if (index == 1)
|
||||
{
|
||||
|
@ -34,3 +67,4 @@ void RendererWidget::currentTabChanged(int index)
|
|||
ui.openGLWidget->stopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMenu>
|
||||
#include "ui_RendererWidget.h"
|
||||
namespace Renderer
|
||||
{
|
||||
class RendererWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
RendererWidget(QWidget* parent = nullptr);
|
||||
~RendererWidget();
|
||||
public slots:
|
||||
|
|
|
@ -18,7 +18,7 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain)
|
|||
surface.create();
|
||||
mainContext->doneCurrent();
|
||||
|
||||
thread = std::jthread([&] {
|
||||
thread = std::jthread([&](std::stop_token stop) {
|
||||
QOpenGLContext context;
|
||||
context.setFormat(mainContext->format());
|
||||
context.setShareContext(mainContext);
|
||||
|
@ -67,7 +67,7 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain)
|
|||
GLuint pageLoadTimeQuery;
|
||||
gl->GenQueries(1, &pageLoadTimeQuery);
|
||||
|
||||
while (true)
|
||||
while (!stop.stop_requested())
|
||||
{
|
||||
if (needUpdate)
|
||||
{
|
||||
|
@ -85,6 +85,7 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain)
|
|||
//qDebug() << duration;
|
||||
pageLoadDuration += duration;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2018-2022 Antonio Dias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "titlewidget.h"
|
||||
|
||||
TitleWidget::TitleWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
void TitleWidget::setText(const QString &text)
|
||||
{
|
||||
m_title = text;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void TitleWidget::setActive(bool active)
|
||||
{
|
||||
m_active = active;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void TitleWidget::setTitleColor(const QColor &active_color, const QColor &inactive_color)
|
||||
{
|
||||
m_active_color = active_color;
|
||||
m_inactive_color = inactive_color;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void TitleWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing);
|
||||
|
||||
QFont font;
|
||||
font.setPointSize(10);
|
||||
#ifdef Q_OS_WIN
|
||||
font.setFamily("Segoe UI, Microsoft YaHei UI");
|
||||
#else
|
||||
font.setFamily(qApp->font().family());
|
||||
#endif
|
||||
|
||||
painter.setFont(font);
|
||||
|
||||
QPen pen;
|
||||
pen.setColor(m_active ? m_active_color : m_inactive_color);
|
||||
|
||||
painter.setPen(pen);
|
||||
|
||||
QFontMetrics metrics(painter.font());
|
||||
QSize title_size = metrics.size(0, m_title);
|
||||
|
||||
QString title = metrics.elidedText(m_title, Qt::ElideRight, width());
|
||||
|
||||
painter.drawText(0, (height() - title_size.height()) / 2, title_size.width(), title_size.height(), 0, title);
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2018-2022 Antonio Dias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TITLEWIDGET_H
|
||||
#define TITLEWIDGET_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
|
||||
class TitleWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TitleWidget(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void setText(const QString &text);
|
||||
void setActive(bool active);
|
||||
void setTitleColor(const QColor &active_color, const QColor &inactive_color);
|
||||
|
||||
private:
|
||||
//Functions
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
//Variables
|
||||
QString m_title;
|
||||
bool m_active;
|
||||
QColor m_active_color;
|
||||
QColor m_inactive_color;
|
||||
};
|
||||
|
||||
#endif // TITLEWIDGET_H
|
|
@ -52,7 +52,7 @@ int main(int argc, char* argv[])
|
|||
//FramelessHelper::Core::setApplicationOSThemeAware();
|
||||
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
|
||||
//FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
|
||||
FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
|
||||
//FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
|
|
|
@ -12,14 +12,20 @@ namespace UnitTest
|
|||
{
|
||||
TEST_CLASS(ElementRendererStokeTypeTest)
|
||||
{
|
||||
private:
|
||||
char* argv[1];
|
||||
int argc;
|
||||
public:
|
||||
TEST_METHOD(TestBothSidesRound)
|
||||
ElementRendererStokeTypeTest() :argv{ (char*)"" }, argc(1) {}
|
||||
|
||||
TEST_METHOD_INITIALIZE(initialize)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
char* argv[] = { (char*)"" };
|
||||
int argc = 1;
|
||||
}
|
||||
TEST_METHOD(TestBothSidesRound)
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||
{
|
||||
|
@ -41,11 +47,6 @@ namespace UnitTest
|
|||
}
|
||||
TEST_METHOD(TestBothSidesFlat)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
char* argv[] = { (char*)"" };
|
||||
int argc = 1;
|
||||
QApplication a(argc, argv);
|
||||
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||
{
|
||||
|
@ -67,11 +68,6 @@ namespace UnitTest
|
|||
}
|
||||
TEST_METHOD(TestLeftSideRound)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
char* argv[] = { (char*)"" };
|
||||
int argc = 1;
|
||||
QApplication a(argc, argv);
|
||||
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||
{
|
||||
|
@ -93,11 +89,6 @@ namespace UnitTest
|
|||
}
|
||||
TEST_METHOD(TestLeftSideFlat)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
char* argv[] = { (char*)"" };
|
||||
int argc = 1;
|
||||
QApplication a(argc, argv);
|
||||
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||
{
|
||||
|
@ -121,14 +112,13 @@ namespace UnitTest
|
|||
|
||||
TEST_CLASS(ElementRendererStokeMaterialTest)
|
||||
{
|
||||
private:
|
||||
char* argv[1];
|
||||
int argc;
|
||||
public:
|
||||
ElementRendererStokeMaterialTest() :argv{ (char*)"" }, argc(1) {}
|
||||
TEST_METHOD(TestStrokePlain)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
char* argv[] = { (char*)"" };
|
||||
int argc = 1;
|
||||
QApplication a(argc, argv);
|
||||
class StyleStrokePlain : public Renderer::ElementStyle
|
||||
{
|
||||
|
@ -145,11 +135,6 @@ namespace UnitTest
|
|||
}
|
||||
TEST_METHOD(TestStrokeRadialGradient1)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
char* argv[] = { (char*)"" };
|
||||
int argc = 1;
|
||||
QApplication a(argc, argv);
|
||||
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||
{
|
||||
|
@ -171,11 +156,6 @@ namespace UnitTest
|
|||
}
|
||||
TEST_METHOD(TestStrokeRadialGradient2)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
char* argv[] = { (char*)"" };
|
||||
int argc = 1;
|
||||
QApplication a(argc, argv);
|
||||
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||
{
|
||||
|
|
|
@ -14,15 +14,14 @@ namespace UnitTest
|
|||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
Renderer::ElementRenderer renderer;
|
||||
Renderer::ElementRenderer& renderer;
|
||||
Renderer::ElementStyle& style;
|
||||
public:
|
||||
TestGLWidget(Renderer::ElementStyle& style, QWidget* parent = nullptr)
|
||||
: QOpenGLWidget(parent), renderer(this), style(style) {};
|
||||
: QOpenGLWidget(parent), renderer(*Renderer::ElementRenderer::instance()), style(style) {};
|
||||
void initializeGL() override
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
renderer.initialize();
|
||||
};
|
||||
void paintGL() override
|
||||
{
|
||||
|
@ -35,7 +34,7 @@ namespace UnitTest
|
|||
transform.scale(10, 10);
|
||||
path = transform.map(path);
|
||||
float pixelRatio = devicePixelRatioF();
|
||||
auto [img, pos] = renderer.drawElement(path, style, pixelRatio, false);
|
||||
auto [img, pos] = renderer.drawElement(path, style, pixelRatio);
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#include "CppUnitTest.h"
|
||||
#include "PaintingTest.h"
|
||||
#include <QApplication>
|
||||
#include "Renderer/Painting/Painting.h"
|
||||
#include "Renderer/Painting/MaterialStyleStroke.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace Renderer;
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
TEST_CLASS(PaintingTest)
|
||||
{
|
||||
private:
|
||||
char* argv[1];
|
||||
int argc;
|
||||
public:
|
||||
PaintingTest() :argv{ (char*)"" }, argc(1) {}
|
||||
|
||||
TEST_METHOD_INITIALIZE(initialize)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
}
|
||||
TEST_METHOD(TestBothSidesRound)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
QApplication a(argc, argv);
|
||||
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||
{
|
||||
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
||||
{
|
||||
std::map<float, Material> materialMap = {
|
||||
{0.20, Material{QColor(255,255,255)}},
|
||||
{0.60, Material{QColor(165,176,207)}},
|
||||
{1.00, Material{QColor(58,64,151)}}
|
||||
};
|
||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||
}
|
||||
} style;
|
||||
TestPaintingGLWidget w(style);
|
||||
w.show();
|
||||
a.exec();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions_4_5_Core>
|
||||
#include "Renderer/Painting/ElementStyle.h"
|
||||
#include <ThirdPartyLib/qquick/qquicksvgparser_p.h>
|
||||
#include <util/SvgFileLoader.h>
|
||||
#include <util/PainterPathUtil.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class TestPaintingGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_5_Core
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
Renderer::ElementStyle& style;
|
||||
|
||||
public:
|
||||
TestPaintingGLWidget(Renderer::ElementStyle& style, QWidget* parent = nullptr)
|
||||
: QOpenGLWidget(parent), style(style) {};
|
||||
void initializeGL() override
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
/*std::vector<std::pair<std::shared_ptr<Contour>, float>> contours;
|
||||
|
||||
QPainterPath painterPaths[3];
|
||||
QQuickSvgParser::parsePathDataFast("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z",
|
||||
painterPaths[0]);
|
||||
if (!SvgFileLoader().loadSvgFile("../svg/2.svg", painterPaths[1]))
|
||||
qCritical() << "load error";
|
||||
QQuickSvgParser::parsePathDataFast("M377,459.61a11.26,11.26,0,0,1,11.27-11.27H696.12a11.27,11.27,0,0,0,11-8.62A359.84,359.84,0,0,0,708,280.56a11.26,11.26,0,0,0-11-8.73H388.27A11.26,11.26,0,0,1,377,260.57h0a11.26,11.26,0,0,1,11.27-11.26H683.71A11.32,11.32,0,0,0,694.28,234C649.8,113.69,542.57,23.85,412.3,4.12a11.22,11.22,0,0,0-12.76,11.17v158.9a11.26,11.26,0,0,0,11.26,11.27H583.12a11.32,11.32,0,0,0,9.26-17.75c-31.67-46.59-78.51-75.2-109.11-90.07a11.25,11.25,0,0,0-16.13,10.17V115.2a11.24,11.24,0,0,0,6.22,10.07l7.51,3.76a11.28,11.28,0,0,1,5,15.12h0a11.27,11.27,0,0,1-15.11,5l-20-10a11.27,11.27,0,0,1-6.22-10.07V54a11.27,11.27,0,0,1,14.62-10.75c5.11,1.59,125.66,40.35,172.24,149A11.27,11.27,0,0,1,621.11,208H388.27A11.26,11.26,0,0,1,377,196.73V11.36A11.32,11.32,0,0,0,365.89.08C363.34,0,360.79,0,358.22,0s-5.11,0-7.66.08a11.32,11.32,0,0,0-11.11,11.28V196.74A11.26,11.26,0,0,1,328.18,208H95.35A11.27,11.27,0,0,1,85,192.3c46.57-108.67,167.12-147.42,172.23-149A11.26,11.26,0,0,1,271.86,54v75.11a11.25,11.25,0,0,1-6.23,10.07l-20,10a11.27,11.27,0,0,1-15.11-5h0a11.26,11.26,0,0,1,5-15.11l7.52-3.76a11.27,11.27,0,0,0,6.22-10.07V87.82a11.25,11.25,0,0,0-16.14-10.16c-30.6,14.87-77.45,43.48-109.1,90.07a11.3,11.3,0,0,0,9.25,17.74H305.66a11.26,11.26,0,0,0,11.27-11.26V15.31A11.22,11.22,0,0,0,304.17,4.14C173.88,23.86,66.66,113.71,22.17,234a11.32,11.32,0,0,0,10.56,15.29H328.18a11.26,11.26,0,0,1,11.27,11.26v0a11.26,11.26,0,0,1-11.27,11.26H19.52a11.26,11.26,0,0,0-11,8.72,359.84,359.84,0,0,0,.83,159.16,11.26,11.26,0,0,0,11,8.61H328.18a11.26,11.26,0,0,1,11.27,11.27h0a11.26,11.26,0,0,1-11.27,11.26h-294a11.32,11.32,0,0,0-10.53,15.4C69,604.65,175.3,692.78,304.16,712.3a11.21,11.21,0,0,0,12.76-11.16V542.22A11.26,11.26,0,0,0,305.66,531h-166c-9.53,0-14.89,11.22-8.69,18.47,34.09,39.77,74.45,65.66,101.77,80.18a11.25,11.25,0,0,0,16.53-10V591a11.26,11.26,0,0,1,11.26-11.26h0A11.26,11.26,0,0,1,271.85,591v63.85A11.27,11.27,0,0,1,256.8,665.5c-4.45-1.59-109.58-40-171-139.9a11.27,11.27,0,0,1,9.59-17.17H328.18a11.26,11.26,0,0,1,11.27,11.26V705.08a11.32,11.32,0,0,0,11.11,11.28q3.82.07,7.66.08c2.57,0,5.12,0,7.67-.08A11.32,11.32,0,0,0,377,705.08V519.69a11.25,11.25,0,0,1,11.27-11.26H621.1a11.26,11.26,0,0,1,9.59,17.16c-61.46,99.87-166.59,138.3-171,139.9a11.27,11.27,0,0,1-15-10.61V591a11.26,11.26,0,0,1,11.26-11.26h0A11.26,11.26,0,0,1,467.14,591v28.6a11.25,11.25,0,0,0,16.53,10c27.33-14.53,67.68-40.42,101.77-80.19,6.2-7.23.85-18.46-8.69-18.46h-166a11.26,11.26,0,0,0-11.26,11.26V701.12a11.21,11.21,0,0,0,12.76,11.17c128.86-19.51,235.14-107.66,280.48-226a11.33,11.33,0,0,0-10.53-15.41h-294A11.25,11.25,0,0,1,377,459.61ZM35.27,399.53V316.9a11.26,11.26,0,0,1,11.27-11.26H669.92a11.25,11.25,0,0,1,11.26,11.26v82.63a11.25,11.25,0,0,1-11.26,11.26H46.54a11.27,11.27,0,0,1-11.27-11.26Z",
|
||||
painterPaths[2]);
|
||||
|
||||
for (auto& i : painterPaths)
|
||||
{
|
||||
auto [contour, ratio] = PainterPathUtil::toNormalizedLines(i);
|
||||
contours.emplace_back(std::make_shared<Contour>(contour), ratio);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<ElementStyle>> style = {
|
||||
std::make_shared<ElementStyleFillDemo>(),
|
||||
std::make_shared<ElementStyleStrokeDemo>(0.02),
|
||||
std::make_shared<ElementStyleStrokeRadialGradientDemo>(0.2)
|
||||
};
|
||||
|
||||
std::vector<std::shared_ptr<Element>> element = {
|
||||
std::make_shared<Element>(Element{ contours[0].first, style[0], contours[0].second}),
|
||||
std::make_shared<Element>(Element{ contours[1].first, style[2], contours[1].second}),
|
||||
std::make_shared<Element>(Element{ contours[2].first, style[0], contours[2].second}),
|
||||
};
|
||||
Painting painting;
|
||||
painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,-0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
painting.addElement(*element[2], ElementTransform{ glm::vec2(0.50,-0.45), glm::vec2(0.6,0.7) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
painting.generateBuffers(this);*/
|
||||
|
||||
//auto index = vtManager->createVirtualTexture(painting);
|
||||
};
|
||||
void paintGL() override
|
||||
{
|
||||
glClearColor(219 / 255., 78 / 255., 32 / 255., 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
};
|
||||
void resizeGL(int w, int h) override {};
|
||||
};
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
#include "CppUnitTest.h"
|
||||
#include "MainWindow.h"
|
||||
//#include "MainWindow.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
||||
#include <util/SvgFileLoader.h>
|
||||
#include "Renderer/Painting/CubicBezier.h"
|
||||
#include <Renderer/Painting/StraightLine.h>
|
||||
#include <ElementPoolWidget.h>
|
||||
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
@ -43,24 +44,24 @@ namespace UnitTest
|
|||
TEST_CLASS(UnitTest)
|
||||
{
|
||||
public:
|
||||
TEST_METHOD(TestMethod1)
|
||||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
FramelessHelper::Core::initialize();
|
||||
//QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
char arg[] = "";
|
||||
char* argv[] = { arg };
|
||||
int argc = 1;
|
||||
QApplication a(argc, argv);
|
||||
FramelessHelper::Core::setApplicationOSThemeAware();
|
||||
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
|
||||
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
|
||||
FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
a.exec();
|
||||
}
|
||||
//TEST_METHOD(TestMethod1)
|
||||
//{
|
||||
// FRAMELESSHELPER_USE_NAMESPACE
|
||||
// FramelessHelper::Core::initialize();
|
||||
// //QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
// QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
// char arg[] = "";
|
||||
// char* argv[] = { arg };
|
||||
// int argc = 1;
|
||||
// QApplication a(argc, argv);
|
||||
// FramelessHelper::Core::setApplicationOSThemeAware();
|
||||
// FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
|
||||
// FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
|
||||
// FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
|
||||
// MainWindow w;
|
||||
// w.show();
|
||||
// a.exec();
|
||||
//}
|
||||
};
|
||||
|
||||
TEST_CLASS(SvgLoaderTest)
|
||||
|
@ -94,5 +95,28 @@ namespace UnitTest
|
|||
|
||||
}
|
||||
};
|
||||
TEST_CLASS(ElementPoolTest)
|
||||
{
|
||||
private:
|
||||
char* argv[1];
|
||||
int argc;
|
||||
public:
|
||||
ElementPoolTest() :argv{ (char*)"" }, argc(1) {}
|
||||
|
||||
TEST_METHOD_INITIALIZE(initialize)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
}
|
||||
TEST_METHOD(ElementPool) {
|
||||
QApplication a(argc, argv);
|
||||
qInstallMessageHandler(messageHandler);
|
||||
ElementPoolWidget wi;
|
||||
//wi.setElementList({"1", "2", "3"});
|
||||
wi.setFixedSize(QSize(600, 800));
|
||||
wi.show();
|
||||
a.exec();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -65,11 +65,11 @@
|
|||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;$(SolutionDIr)ArchitectureColoredPainting;$(SolutionDIr)ArchitectureColoredPainting\include;$(SolutionDIr)ArchitectureColoredPainting\src;$(SolutionDir)ArchitectureColoredPainting\src\Editor\RightBar;$(SolutionDir)ArchitectureColoredPainting\src\Editor\;$(SolutionDIr)ArchitectureColoredPainting\x64\Debug\uic;$(SolutionDir)FramelessHelper\include;$(SolutionDir)FramelessHelper\qmake\inc\core;$(SolutionDir)FramelessHelper\include\FramelessHelper\Core;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;$(SolutionDIr)ArchitectureColoredPainting;$(SolutionDIr)ArchitectureColoredPainting\include;$(SolutionDIr)ArchitectureColoredPainting\src;$(SolutionDir)ArchitectureColoredPainting\src\Editor\RightBar;$(SolutionDir)ArchitectureColoredPainting\src\Editor\;$(SolutionDIr)ArchitectureColoredPainting\x64\Debug\uic;$(SolutionDir)FramelessHelper\include;$(SolutionDir)FramelessHelper\qmake\inc\core;$(SolutionDir)FramelessHelper\include\FramelessHelper\Core;$(SolutionDir)qt-material-widgets\components;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>$(SolutionDIr)ArchitectureColoredPainting\x64\Debug\*.obj;$(SolutionDIr)FramelessHelper\qmake\FramelessHelperCore\debug\FramelessHelperCore.lib;$(SolutionDIr)FramelessHelper\qmake\FramelessHelperWidgets\debug\FramelessHelperWidgets.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>$(SolutionDIr)ArchitectureColoredPainting\x64\Debug\*.obj;$(SolutionDIr)FramelessHelper\qmake\FramelessHelperCore\debug\FramelessHelperCore.lib;$(SolutionDIr)FramelessHelper\qmake\FramelessHelperWidgets\debug\FramelessHelperWidgets.lib;$(SolutionDIr)qt-material-widgets\components\debug\components.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -111,6 +111,12 @@
|
|||
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
|
||||
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PaintingTest.cpp">
|
||||
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">input</DynamicSource>
|
||||
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).moc</QtMocFileName>
|
||||
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
|
||||
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UnitTest.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -125,6 +131,9 @@
|
|||
<ItemGroup>
|
||||
<QtMoc Include="ElementRendererTest.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="PaintingTest.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
||||
<Import Project="$(QtMsBuild)\qt.targets" />
|
||||
|
|
|
@ -37,10 +37,16 @@
|
|||
<QtMoc Include="ElementRendererTest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="PaintingTest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ElementRendererTest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PaintingTest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue