Compare commits

..

No commits in common. "3f1421a1bd0c73f4f2ab56cb9ae3c32be5443337" and "1031ba580855827a76a4fea5971aef07f27a19c9" have entirely different histories.

76 changed files with 1550 additions and 2035 deletions

View File

@ -104,12 +104,10 @@
</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" />
@ -121,10 +119,9 @@
<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" />
@ -152,11 +149,13 @@
<ClCompile Include="src\Renderer\Painting\StraightLine.cpp" />
<ClCompile Include="src\Renderer\VirtualTextureManager.cpp" />
<ClCompile Include="src\SvgParser.cpp" />
<QtUic Include="EditorWidget.ui" />
<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="src\Editor\EditorWidgetComponent\LayerCreateWidget.ui" />
<QtUic Include="EditorWidget.ui" />
</ItemGroup>
<ItemGroup>
<None Include="..\data.json" />
@ -191,10 +190,7 @@
<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" />
@ -205,9 +201,7 @@
<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" />
@ -220,6 +214,9 @@
<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" />

View File

@ -70,10 +70,13 @@
<QtUic Include="MainWindow.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="EditorWidget.ui">
<QtUic Include="NavigationBarWidget.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.ui">
<QtUic Include="FramelessWindow.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="EditorWidget.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
@ -114,6 +117,15 @@
<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>
@ -207,21 +219,6 @@
<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">
@ -236,6 +233,15 @@
<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>
@ -251,18 +257,6 @@
<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" />
@ -396,6 +390,9 @@
<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>
@ -453,12 +450,6 @@
<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">

View File

@ -7,53 +7,42 @@
<x>0</x>
<y>0</y>
<width>1139</width>
<height>862</height>
<height>685</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,20">
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,1,1,20">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="autoFillBackground">
<bool>false</bool>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</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">
<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" stretch="1,1,1,1,1,0">
<property name="spacing">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="createButton">
<property name="minimumSize">
<size>
<width>80</width>
<height>40</height>
<height>0</height>
</size>
</property>
<property name="maximumSize">
@ -72,7 +61,7 @@
<property name="minimumSize">
<size>
<width>80</width>
<height>40</height>
<height>0</height>
</size>
</property>
<property name="maximumSize">
@ -91,7 +80,7 @@
<property name="minimumSize">
<size>
<width>80</width>
<height>40</height>
<height>0</height>
</size>
</property>
<property name="maximumSize">
@ -110,7 +99,7 @@
<property name="minimumSize">
<size>
<width>80</width>
<height>40</height>
<height>0</height>
</size>
</property>
<property name="maximumSize">
@ -126,16 +115,10 @@
</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>40</height>
<height>0</height>
</size>
</property>
<property name="maximumSize">
@ -149,34 +132,28 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="minimumSize">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>800</height>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">

View File

@ -6,23 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>1473</width>
<height>1103</height>
<width>1124</width>
<height>695</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>
@ -37,98 +28,53 @@
</property>
<item>
<widget class="QWidget" name="MainWindow" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="30">
<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 class="QVBoxLayout" name="verticalLayout_2" stretch="1,30">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,12,5">
<widget class="QLabel" name="Title">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,18,5">
<item>
<widget class="QWidget" name="LeftBar" native="true"/>
</item>
<item>
<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>
<widget class="PreviewWindow" name="Preview"/>
</item>
<item>
<widget class="QWidget" name="RightBar" native="true">
<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>
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="1,2">
<item>
<widget class="QTabWidget" name="DisplayTab">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="InfoDisplayWidget" name="LayerDisplay">
<attribute name="title">
<string>图层信息</string>
<string>Layer</string>
</attribute>
</widget>
<widget class="ElementPoolWidget" name="ElementDisplay">
<widget class="QWidget" name="ElementDisplay">
<attribute name="title">
<string>图元池</string>
<string>Element</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>图层树</string>
<string notr="true">1</string>
</property>
</column>
</widget>
@ -161,12 +107,6 @@
<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/>

View File

@ -0,0 +1,94 @@
<?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>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindowClass</class>
<widget class="QWidget" name="MainWindowClass">
<widget class="QMainWindow" name="MainWindowClass">
<property name="geometry">
<rect>
<x>0</x>
@ -10,45 +10,102 @@
<height>722</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true">font: 10pt &quot;Segoe UI, Microsoft YaHei UI&quot;;</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
<widget class="QWidget" name="centralWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</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>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<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>
<layout class="QVBoxLayout" name="verticalLayout">
<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>
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="1">
<property name="spacing">
<number>0</number>
</property>
<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">
<number>0</number>
</property>
<property name="elideMode">
<enum>Qt::ElideNone</enum>
</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>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
@ -63,6 +120,8 @@
<header>Editor/EditorWidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<resources>
<include location="MainWindow.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1,2 +0,0 @@
17876391417123941155.jpg 0.json 0 0 1 1
11474523244911310074.jpg 1.json 0 0 1 1

View File

@ -0,0 +1,100 @@
<?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>

View File

@ -13,7 +13,7 @@
<property name="windowTitle">
<string>RendererWidget</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1">
<property name="spacing">
<number>0</number>
</property>
@ -31,37 +31,25 @@
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QtMaterialFlatButton" name="openButton">
<widget class="QPushButton" name="openButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>30</height>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>文件</string>
<string>打开</string>
</property>
<property name="flat">
<bool>false</bool>
@ -83,6 +71,34 @@
</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">
@ -164,11 +180,6 @@
<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/>

View File

@ -1190,7 +1190,7 @@ void main()
//imageStore(gBaseColor, pixelLocation, vec4(uv,1,1));
//imageStore(gMetallicRoughness, pixelLocation, vec4(uv,1,1));
//return;
uv = uv*2-vec2(1);
uv = vec2(1)-uv*2;
//vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg;
vec3 debugBVH = vec3(0);

View File

@ -0,0 +1,261 @@
/*
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);
}

View File

@ -0,0 +1,81 @@
/*
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

View File

@ -1,54 +0,0 @@
#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);
}
}

View File

@ -1,29 +0,0 @@
#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);
};

View File

@ -1,124 +0,0 @@
<?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>

View File

@ -1,88 +0,0 @@
#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);
}

View File

@ -1,23 +0,0 @@
#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;
};

View File

@ -11,13 +11,7 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p
tabWidget = ui.DisplayTab;
this->filePath = filePath;
layerInfoDisplayWidget = dynamic_cast<InfoDisplayWidget *>(tabWidget->widget(0));
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);
elementInfoDisplayWidget = dynamic_cast<InfoDisplayWidget *>(tabWidget->widget(1));
connect(treeWidget, &LayerTreeWidget::displayLayerChange, this, &EditorWidgetItem::onLayerChange);
connect(layerInfoDisplayWidget, &InfoDisplayWidget::requireRefreshPreview, this,
&EditorWidgetItem::triggerRefreshPreview);
@ -39,12 +33,8 @@ 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();
@ -59,11 +49,6 @@ EditorWidgetItem::~EditorWidgetItem()
void EditorWidgetItem::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// 设置画刷的颜色为灰色,并填充整个窗口区域
painter.setBrush(Qt::gray);
painter.drawRect(this->rect());
}
void EditorWidgetItem::onLayerChange(LayerWrapper *layer)

View File

@ -1,7 +1,6 @@
#pragma once
#include "ElementManager.h"
#include "ElementPoolWidget.h"
#include "InfoDisplayWidget.h"
#include "LayerManager.h"
#include "LayerTreeWidget.h"
@ -24,8 +23,7 @@ class EditorWidgetItem : public QWidget
Ui::EditorWidgetItem ui;
LayerTreeWidget *treeWidget;
QTabWidget *tabWidget;
InfoDisplayWidget* layerInfoDisplayWidget;
ElementPoolWidget* elementInfoDisplayWidget;
InfoDisplayWidget *layerInfoDisplayWidget, *elementInfoDisplayWidget;
// QT DATA PART
LayerWrapper *displayLayer;
GraphicElement *displayElement;

View File

@ -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,19 +19,10 @@ 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)
@ -54,49 +45,4 @@ QJsonObject ElementManager::toJson() const
QJsonObject result;
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);
}

View File

@ -8,11 +8,10 @@ using std::vector;
class LayerManager;
class GraphicElement;
class Renderer::ElementRenderer;
class FolderLayerWrapper;
class ElementManager
{
public:
private:
vector<GraphicElement *> elements;
public:
@ -20,14 +19,9 @@ 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);
};

View File

@ -1,81 +0,0 @@
#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();
}

View File

@ -1,32 +0,0 @@
#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();
};

View File

@ -43,11 +43,10 @@ PixelPath GroupElement::getPaintObject() const
}
//TODO: apply styles and send back
PixelPath SimpleElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
PixelPath SimpleElement::getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo> styles) const {
PixelPath result;
Renderer::ElementStyleStrokeDemo demo(2);
auto [img, mov] = renderer->drawElement(painterPath, demo, 1.0);
//qDebug() << mov;
auto [img, mov] = renderer->drawElement(painterPath, demo, 1.0, false);
//qDebug() << img << " ------";
result.addImage(img, mov);
//result.addPath(painterPath);
@ -60,7 +59,7 @@ PixelPath SimpleElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>
return result;
}
PixelPath GroupElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
PixelPath GroupElement::getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo> styles) const {
return getPaintObject();
}

View File

@ -1,7 +1,6 @@
#pragma once
#include "LayerWrapper.h"
#include "LayerStyle.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QPainterPath>
@ -27,7 +26,7 @@ public:
// TODO: ¸ÄΪBitmapPath
virtual QJsonObject toJson() const;
virtual PixelPath getPaintObject() const = 0;
virtual PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const = 0;
virtual PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const = 0;
};
class SimpleElement : public GraphicElement
@ -40,10 +39,9 @@ private:
public:
SimpleElement(QJsonObject jsonSource);
SimpleElement(QString filePath);
~SimpleElement() = default;
PixelPath getPaintObject() const override;
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const override;
};
class GroupElement : public GraphicElement
@ -56,7 +54,7 @@ public:
GroupElement(FolderLayerWrapper* mSourceLayer);
~GroupElement() = default;
PixelPath getPaintObject() const override;
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const override;
void setSourceLayer(FolderLayerWrapper* sourceLayer);
};

View File

@ -11,10 +11,10 @@ LayerWrapper *LayerManager::getRoot() const
{
return root;
}
void LayerManager::paint(QPainter *painter, QSize size,LayerWrapper* selecetedLayer) const
void LayerManager::paint(QPainter *painter, QSize size) const
{
root->getCache();
root->paint(painter);
auto p = root->getCache().resizedPixel(size);
painter->drawPixmap(0, 0, p);
}
bool LayerManager::singleSelectedCheck() const
{

View File

@ -32,7 +32,7 @@ class LayerManager
LayerManager() = default;
LayerManager(QJsonObject source, ElementManager* elementManager);
QJsonObject toJson() const;
void paint(QPainter *painter, QSize size, LayerWrapper* selecetedLayer=nullptr) const;
void paint(QPainter *painter, QSize size) const;
bool rename(QString newName) const;
bool combine() const;
// bool seperate() const;

View File

@ -1,103 +1,6 @@
#include "LayerStyle.h"
#include <QHBoxLayout>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
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
std::vector<Renderer::BaseStyle> StrokeElementStyle::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));
}

View File

@ -1,56 +1,24 @@
#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"
/**
* StylegetInputWidget()
* StylegetInputWidget()
*
* LayerStyleElementStylestyle
*
*/
class LayerStyle
{
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;
public:
virtual void apply() = 0;
};
class StrokeElementLayerStyle : public Renderer::ElementStyle, public LayerStyle
struct EditorStrokeMaterialStyle
{
public:
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;
float applyWidth;
Renderer::StrokeType strokeType;
Renderer::StrokeEndType endType;
std::shared_ptr<Renderer::MaterialStroke> materialStroke;
};
class FillElementLayerStyle : public Renderer::ElementStyle, public LayerStyle
class StrokeElementStyle : Renderer::ElementStyle
{
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;
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override;
std::vector<EditorStrokeMaterialStyle> materialStyles;
};

View File

@ -23,22 +23,16 @@ FolderLayerWrapper*LayerWrapper::getParent() const
return this == nullptr ? nullptr : this->parent;
}
PixelPath LayerWrapper::getCache(LayerWrapper* selectedLayer)
PixelPath LayerWrapper::getCache()
{
this->refresh(selectedLayer);
if (selectedLayer == this)
{
this->cache.highLight();
}
this->refresh();
return cache;
}
// TODO: undone
LayerWrapper::LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager)
LayerWrapper::LayerWrapper(QJsonObject json, FolderLayerWrapper*parent)
{
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(),
@ -49,7 +43,7 @@ LayerWrapper::LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementM
}
FolderLayerWrapper::FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent)
: LayerWrapper(json, parent, elementManager)
: LayerWrapper(json, parent)
{
qDebug() << json.value("name").toString() << " " << this;
QJsonArray childrenJson = json.value("children").toArray();
@ -79,7 +73,6 @@ 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;
@ -88,48 +81,32 @@ void LayerWrapper::SimpleProperty::apply(PixelPath&cache) const
//qDebug() << name << " " << cache.boundingRect().center();
//qDebug() << name << " " << cache.boundingRect();
trans.translate(centerX, centerY);
trans.translate(offset.x(), offset.y());
trans.rotate(rotation);
trans.scale(scale.x(), scale.y());
trans.rotate(rotation);
trans.translate(-centerX, -centerY);
trans.translate(offset.x(), offset.y());
cache = cache.trans(trans);
}
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)
void LayerWrapper::refresh()
{
property.apply(cache);
}
void FolderLayerWrapper::refresh(LayerWrapper* layer)
void FolderLayerWrapper::refresh()
{
cache.clear();
for (auto& child : children) {
cache.addPath(child.get()->getCache(layer));
cache.addPath(child.get()->getCache());
}
LayerWrapper::refresh();
}
void LeafLayerWrapper::refresh(LayerWrapper* layer)
void LeafLayerWrapper::refresh()
{
cache.clear();
if (wrappedElement != nullptr)
{
cache.addPath(wrappedElement->getPaintObject(&(this->styles)));
cache.addPath(wrappedElement->getPaintObject(this->styles));
}
LayerWrapper::refresh();
}
@ -142,22 +119,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);
}
}
@ -177,7 +154,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()) {
@ -189,18 +166,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();
}
@ -227,8 +204,8 @@ QJsonObject FolderLayerWrapper::toJson() const
childrenJson.push_back(child->toJson());
json.insert("children", childrenJson);
json.insert("is-folder", true);
if(this->getReferencedBy() != -1)
json.insert("referenced-by", this->getReferencedBy());
if(this->referencedBy != -1)
json.insert("referenced-by", this->referencedBy);
else
json.insert("referenced-by", QJsonValue());
return json;
@ -240,41 +217,4 @@ QJsonObject LeafLayerWrapper::toJson() const
json.insert("element", wrappedElement->index);
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();
}
}

View File

@ -28,13 +28,12 @@ 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 = "";
@ -47,15 +46,13 @@ class LayerWrapper
void apply(PixelPath&cache) const;
} property;
virtual void setParent(FolderLayerWrapper*newParent);
virtual void refresh(LayerWrapper* layer = nullptr);
virtual void refresh();
virtual QTreeWidgetItem* getQTreeItem();
// TODO: 将QPainterPath改为BitmapPath/QImage或者直接将其删除绘制时直接使用BitmapPath的paint方法
virtual PixelPath getCache(LayerWrapper* selectedLayer=nullptr);
QTransform getTransform();
virtual PixelPath getCache();
FolderLayerWrapper*getParent() const; // invoke by manager, then invoke parent's applyStyles
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager=nullptr);
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent);
LayerWrapper() = default;
virtual void paint(QPainter* painter);
// TODO : export Function
// virtual LayerWrapper *addChild() = 0; // Leaf Child Only
// virtual LayerWrapper *addParent() = 0; // Folder Parent Only
@ -77,7 +74,7 @@ class FolderLayerWrapper : public LayerWrapper
public:
~FolderLayerWrapper() = default;
void refresh(LayerWrapper* layer=nullptr) override;
void refresh() override;
FolderLayerWrapper() = default;
FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
void addChild(shared_ptr<LayerWrapper> child);
@ -87,24 +84,20 @@ 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;
vector<std::shared_ptr<LayerStyle>> styles;
const vector<Renderer::ElementStyleStrokeDemo> styles;
public:
~LeafLayerWrapper() = default;
void refresh(LayerWrapper* layer = nullptr) override;
void refresh() override;
LeafLayerWrapper() = default;
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
QJsonObject toJson() const override;
void paint(QPainter* painter) override;
};
Q_DECLARE_METATYPE(LayerWrapper *)

View File

@ -32,15 +32,10 @@ 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());
}
@ -51,7 +46,6 @@ 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());
}
@ -89,32 +83,5 @@ 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();
}

View File

@ -10,21 +10,17 @@ class PixelPath
private:
QRectF boundingRect;
QPixmap pixmap;
QPainterPath painterPath;
int w,h;
public:
PixelPath(int w=1080, int h= 1080);
PixelPath(QPainterPath painterPath,int w = 1080, int h = 1080);
PixelPath(int w=1920, int h= 1080);
PixelPath(QPainterPath painterPath,int w = 1920, 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();
};

View File

@ -2,8 +2,7 @@
PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent)
{
this->setFixedSize(QSize(1080, 1080));
this->renderer = Renderer::ElementRenderer::instance();
this->renderer = new Renderer::ElementRenderer(this);
QSurfaceFormat surfaceFormat;
surfaceFormat.setSamples(16);
setFormat(surfaceFormat);
@ -11,7 +10,6 @@ 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)
@ -38,6 +36,7 @@ void PreviewWindow::show()
void PreviewWindow::initializeGL()
{
this->renderer->initialize();
initializeOpenGLFunctions();
}
@ -48,7 +47,7 @@ void PreviewWindow::paintGL()
painter->begin(this);
painter->setRenderHint(QPainter::Antialiasing);
painter->setRenderHint(QPainter::HighQualityAntialiasing);
layerManager->paint(painter,this->size(),currentLayer);
layerManager->paint(painter,this->size());
painter->end();
}
@ -58,50 +57,4 @@ 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)
{
// 当鼠标释放时,不做任何操作
}

View File

@ -7,7 +7,6 @@
#include <QJsonObject>
#include <QJsonValue>
#include <QOpenGLFunctions>
#include <QMouseEvent>
#include <QOpenGLWidget>
#include "../Renderer/Preview/ElementRenderer.h"
@ -20,13 +19,7 @@ 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);
void initialize(LayerManager *layerManager, QSize windowSize = QSize(1920, 1080));
@ -35,11 +28,4 @@ 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();
};

View File

@ -1,26 +1,27 @@
#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 (this->layout()->count() > 0 && (item = this->layout()->takeAt(0)) != nullptr)
while ((item = this->layout()->takeAt(0)) != nullptr)
{
delete item->widget();
delete item;
@ -46,31 +47,26 @@ 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();
});
@ -82,165 +78,78 @@ void InfoDisplayWidget::generateLayerForm()
layout->addRow("scale-Y:", scaleY);
layout->setRowWrapPolicy(QFormLayout::DontWrapRows);
LeafLayerWrapper* leafP = dynamic_cast<LeafLayerWrapper*>(this->displayLayer);
if (leafP) {
bool styleEnabled = true;
if (styleEnabled) {
QListWidget* styleList = new QListWidget(this);
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("样式列表");
item->setFlags(Qt::NoItemFlags);
styleList->addItem(item);
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;
layout->setAlignment(Qt::AlignmentFlag::AlignRight);
//QtMaterialFlatButton* detailButton = new QtMaterialFlatButton(w);
//QtMaterialFlatButton* removeButton = new QtMaterialFlatButton(w);
QPushButton* deleteButton = new QPushButton(w);
QPushButton* detailButton = new QPushButton(w);
QPushButton* removeButton = new QPushButton(w);
detailButton->setText("...");
QLabel* name = new QLabel(w);
name->setText(styleNames[index]);
detailButton->setText("...");
detailButton->setFixedSize(QSize(20, 20));
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(removeButton, &QPushButton::clicked, this,
[this, styleIterator, styles]()
{
styles->erase(styleIterator);
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();
emit requireRefreshElementWidget();
}
});
QWidget* styleDisplayWidget = (*styleIterator)->getListDisplayWidget();
styleDisplayWidget->setParent(w);
styleDisplayWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
layout->addWidget(styleDisplayWidget);
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(removeButton);
layout->addWidget(deleteButton);
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();
}

View File

@ -4,18 +4,19 @@
#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();
@ -23,6 +24,6 @@ class InfoDisplayWidget : public QWidget
signals:
void requireRefreshPreview();
void requireSelfRefresh();
void requireRefreshElementWidget();
};

View File

@ -1,8 +1,6 @@
#include "LayerTreeWidget.h"
#include <QInputDialog>
#include <QMenu>
#include "./EditorWidgetComponent/LayerCreateWidget.h"
LayerTreeWidget::LayerTreeWidget(QWidget *parent)
{
emit displayLayerChange(nullptr);
@ -13,14 +11,10 @@ LayerTreeWidget::LayerTreeWidget(QWidget *parent)
connect(this, &QTreeWidget::customContextMenuRequested, this, &LayerTreeWidget::popMenu);
connect(this, &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem *currentItem) {
this->selectedItem = currentItem;
if (this->selectedItem != nullptr) {
auto layer = this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>();
emit displayLayerChange(layer);
}
else {
emit displayLayerChange(nullptr);
}
emit requireRefreshPreview();
if(this->selectedItem !=nullptr)
emit displayLayerChange(this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper *>());
else
emit displayLayerChange(nullptr);
});
// connect(this, &QTreeWidget::itemDoubleClicked, this, &LayerTreeWidget::onItemDoubleClicked);
}
@ -41,64 +35,32 @@ void LayerTreeWidget::popMenu(const QPoint &pos)
QMenu menu;
QTreeWidgetItem *item = itemAt(pos);
this->selectedItem = item;
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]() {
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]() {
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();
}
}
});
}
}
}
// 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)
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();
});
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.exec(mapToGlobal(pos));
}

View File

@ -1,6 +1,5 @@
#pragma once
#include "LayerWrapper.h"
#include "ElementManager.h"
#include <QPoint>
#include <QTreeWidget>
class LayerTreeWidget : public QTreeWidget
@ -11,7 +10,6 @@ class LayerTreeWidget : public QTreeWidget
LayerWrapper *copiedItem;
public:
ElementManager* elementManager;
LayerWrapper* root;
LayerTreeWidget(QWidget *parent = nullptr);
void onRenameEvent();
@ -20,8 +18,7 @@ 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();
};

View File

@ -1,128 +0,0 @@
#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;
}

View File

@ -1,15 +0,0 @@
#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);
};

View File

@ -86,6 +86,7 @@ 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();

View File

@ -1,24 +0,0 @@
#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);
}

View File

@ -1,14 +0,0 @@
#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;
};

View File

@ -0,0 +1,75 @@
/*
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);
}

View File

@ -0,0 +1,52 @@
/*
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

View File

@ -2,7 +2,6 @@
#include "Renderer/RendererGLWidget.h"
#include "qslider.h"
#include <QPushButton>
#include <QScreen>
#include "NavigationBarWidget.h"
#include <FramelessHelper/Core/utils.h>
#include <FramelessHelper/Widgets/standardtitlebar.h>
@ -12,13 +11,111 @@
FRAMELESSHELPER_USE_NAMESPACE
CentralWidget::CentralWidget(QWidget* parent) : QWidget(parent)
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)
{
ui.setupUi(this);
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);
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);
}
CentralWidget::~CentralWidget()
@ -36,29 +133,38 @@ 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_central_widget);
setCentralWidget(m_window);
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());
move(QGuiApplication::primaryScreen()->availableGeometry().center() - rect().center());
//setCentralWidget(m_window);
//move(QGuiApplication::primaryScreen()->availableGeometry().center() - rect().center());
}
@ -72,5 +178,6 @@ void MainWindow::closeEvent(QCloseEvent* event)
if (result != QMessageBox::Yes)
event->ignore();*/
qDebug() << "closeEvent";
}

View File

@ -2,6 +2,7 @@
#include <QtWidgets/QMainWindow>
#include "ui_MainWindow.h"
#include "ui_FramelessWindow.h"
#include <FramelessHelper/Widgets/framelessmainwindow.h>
@ -9,7 +10,20 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
class StandardTitleBar;
FRAMELESSHELPER_END_NAMESPACE
class CentralWidget : public QWidget
class FramelessWindow : public QWidget
{
Q_OBJECT
public:
explicit FramelessWindow(QWidget* parent = nullptr);
~FramelessWindow();
Ui::FramelessWindow* ui;
};
class CentralWidget : public QMainWindow
{
Q_OBJECT
public:
@ -32,7 +46,10 @@ public:
private:
FRAMELESSHELPER_PREPEND_NAMESPACE(StandardTitleBar)* m_titleBar = nullptr;
Ui::MainWindowClass ui;
CentralWidget* m_central_widget = nullptr;
void closeEvent(QCloseEvent * event);
void closeEvent(QCloseEvent* event);
FramelessWindow* m_window;
CentralWidget* m_central_widget;
};

View File

@ -1,6 +1,5 @@
#include "NavigationBarWidget.h"
#include <qtmaterialraisedbutton.h>
#include <QVBoxLayout>
#include <QDebug>
NavigationBarWidget::NavigationBarWidget(QWidget *parent)

View File

@ -3,6 +3,7 @@
#include <QWidget>
#include <QButtonGroup>
#include <qtmaterialtabs.h>
#include "ui_NavigationBarWidget.h"
class NavigationBarWidget : public QWidget
{

View File

@ -1,23 +1,24 @@
#pragma once
#include <QOpenGLFunctions_4_5_Core>
#include <QString>
#include <vector>
#include <QVector>
#include <QVector2D>
#include <QVector3D>
#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
{
glm::vec3 Position;
glm::vec3 Normal;
glm::vec2 TexCoords;
QVector3D Position;
QVector3D Normal;
QVector2D TexCoords;
Vertex(const aiVector3D& position, const aiVector3D& Normal, const aiVector3D& TexCoords);
};
@ -37,8 +38,8 @@ namespace Renderer
class Mesh : public Drawable
{
public:
std::vector<Vertex> vertices;
std::vector<unsigned int> indices;
QVector<Vertex> vertices;
QVector<unsigned int> indices;
//QVector<Texture*> textures;
GLuint textureBasecolor = 0;
GLuint textureMetallicRoughness = 0;

View File

@ -45,50 +45,26 @@ void Model::drawShadow() {
void Renderer::Model::loadModel(QString path)
{
QFileInfo modelFile(path);
name = modelFile.baseName();
directory = modelFile.dir();
directory = path;
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(modelFile.absoluteFilePath().toUtf8(), aiProcess_Triangulate /*| aiProcess_FlipUVs*/);
const aiScene* scene = importer.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
{
qCritical() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
qDebug() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
return;
}
qDebug() << modelFile.absoluteFilePath() << "Loaded Successfully";
qDebug() << directory.absolutePath() << "Loaded Successfully";
qDebug() << "NumMeshes: " << scene->mNumMeshes;
qDebug() << "NumMaterials: " << scene->mNumMaterials;
qDebug() << "NumTextures: " << scene->mNumTextures;
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!";
}
directory.cdUp();
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();
aiMatrix4x4 transform;
aiMatrix4x4::Scaling(aiVector3D(1 / 0.008), transform);
processNode(scene->mRootNode, scene, transform * scene->mRootNode->mTransformation);
processNode(scene->mRootNode, scene);
AABB.push_back(QVector3D(minX, minY, minZ));
AABB.push_back(QVector3D(minX, minY, maxZ));
AABB.push_back(QVector3D(minX, maxY, minZ));
@ -117,77 +93,86 @@ 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);
std::vector<Vertex> vertices;
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
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))
{
if (mesh->mNormals && mesh->mTextureCoords[0])
qDebug() << str.C_Str() << "Replaced";
// 初始化网格
auto m_mesh = std::make_unique<PaintingMesh>(glFunc, paintingProgram, shadowProgram, modelQ);
// 遍历网格的每个顶点
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{
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);
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);
}
}
}
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())
{
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)
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{
//qDebug() << v.TexCoords.x << v.TexCoords.y;
v.TexCoords = (v.TexCoords - leftBottom) / (rightTop - leftBottom);
qDebug() << v.TexCoords.x << v.TexCoords.y;
aiFace face = mesh->mFaces[i];
// 将所有面的索引数据添加到索引数组中
for (unsigned int j = 0; j < face.mNumIndices; j++) {
m_mesh->indices.push_back(face.mIndices[j]);
}
}
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;
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;
}
else
{
auto mesh = std::make_unique<Mesh>(glFunc, shaderProgram, shadowProgram, modelQ);
mesh->vertices = vertices;
mesh->indices = indices;
// 初始化网格
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);
}
}
if (!(mesh->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR)))
// 将所有面的索引数据添加到索引数组中
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)))
qWarning() << "Basecolor Texture Loading Failed!";
if (!(mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS)))
if (!(m_mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS)))
qWarning() << "MetallicRoughness Texture Loading Failed!";
if (!(mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS)))
if (!(m_mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS)))
qWarning() << "Normal Texture Loading Failed!";
if (mesh->textureBasecolor && mesh->textureMetallicRoughness && mesh->textureNormal)
if (m_mesh->textureBasecolor && m_mesh->textureMetallicRoughness && m_mesh->textureNormal)
{
mesh->setupMesh();
return mesh;
m_mesh->setupMesh();
return m_mesh;
}
else
return nullptr;
@ -218,7 +203,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.mirrored());
texture.setData(data);
return texture.textureId();
}
@ -265,7 +250,7 @@ GLuint Renderer::Model::loadPainting(std::string path)
};
Painting painting;
if (path == "0.json")
if (path == "17876391417123941155.jpg")
{
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 });
@ -281,6 +266,7 @@ GLuint Renderer::Model::loadPainting(std::string path)
}
}
painting.generateBuffers(glFunc);
auto index = vtManager->createVirtualTexture(painting);

View File

@ -17,24 +17,20 @@ namespace Renderer
void loadModel(QString path);
Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, VirtualTextureManager* vtManager);
private:
QOpenGLContext* context = nullptr;
QOpenGLContext* context;
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; /// 模型所在路径
QString name; /// 模型文件名
/// 模型所在路径
QDir directory;
float minX, maxX, minY, maxY, minZ, maxZ;

View File

@ -23,7 +23,6 @@ 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;
};

View File

@ -18,11 +18,6 @@ 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()
@ -47,11 +42,6 @@ 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;

View File

@ -10,7 +10,6 @@ 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;
};
@ -20,7 +19,6 @@ 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;
@ -28,17 +26,16 @@ namespace Renderer
float roughness;
};
class MaterialStyleFill : public MaterialStyle
{
public:
class MaterialStyleFill : public MaterialStyle
{
public:
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 MaterialStyleType type() const override;
virtual std::vector<GLfloat> encoded() const override;
virtual bool operator==(const MaterialStyle&) const override;
//protected:
protected:
std::shared_ptr<MaterialFill> materialFill;
};
};
}

View File

@ -18,11 +18,6 @@ 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))),
@ -63,11 +58,6 @@ 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()
@ -97,11 +87,6 @@ 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;

View File

@ -11,7 +11,6 @@ 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;
};
@ -21,9 +20,7 @@ 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;
@ -35,7 +32,6 @@ 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;
@ -51,10 +47,9 @@ 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;

View File

@ -1,7 +1,7 @@
#pragma once
#include <QOpenGLFunctions_4_5_Core>
#include <QString>
#include <vector>
#include <QVector>
#include <QVector2D>
#include <QVector3D>
#include <QOpenGLShaderProgram>
@ -18,8 +18,8 @@ namespace Renderer
class PaintingMesh : public Drawable
{
public:
std::vector<Vertex> vertices;
std::vector<GLuint> indices;
QVector<Vertex> vertices;
QVector<GLuint> indices;
GLuint textureBasecolor;
GLuint textureMetallicRoughness;
QMatrix4x4 model;

View File

@ -12,6 +12,22 @@
#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;
@ -114,94 +130,42 @@ QRectF calcBoundingRect(const QPainterPath& path, const std::vector<BaseStyle>&
return QRectF(QPointF(leftTop.x, leftTop.y), QPointF(rightBottom.x, rightBottom.y));
}
Renderer::ElementRenderer::ElementRenderer()
std::pair<QImage, QPointF> Renderer::ElementRenderer::drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio, bool releaseContext)
{
surface.create();
thread = std::jthread([&](std::stop_token stop) {
std::stop_callback cb(stop, [&] {
draw.notify_all();
});
auto baseStyles = style.toBaseStyles();
QRectF bound = calcBoundingRect(path, baseStyles);
QPointF leftTop = bound.topLeft();
QSize size(ceil(bound.width() * pixelRatio), ceil(bound.height() * pixelRatio));
QOpenGLContext context;
context.create();
context.makeCurrent(&surface);
auto pathBuffer = generatePathBuffer(path);
auto styleBuffer = generateStyleBuffer(baseStyles);
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();
if (releaseContext) glWidget->makeCurrent();
initialized = true;
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);
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 fbo = QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D);
fbo.bind();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
fbo.release();
auto pathBuffer = generatePathBuffer(*path);
auto styleBuffer = generateStyleBuffer(baseStyles);
shader->bind();
shader->setUniformValue("pathSize", (GLint)pathBuffer.size());
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);
shader->release();
GLuint ssbo[2];
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();
gl->glClearColor(0, 0, 0, 0);
gl->glClear(GL_COLOR_BUFFER_BIT);
fbo.release();
shader->bind();
shader->setUniformValue("pathSize", (GLint)pathBuffer.size());
shader->setUniformValue("styleSize", (GLint)styleBuffer.size());
shader->setUniformValue("leftTop", leftTop);
shader->setUniformValue("pixelRatio", pixelRatio);
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);
gl->glDeleteBuffers(2, ssbo);
result = { image, leftTop };
drawFinished = true;
}
draw.notify_all();
}
context.doneCurrent();
});
while (!initialized)
std::this_thread::yield();
auto image = fbo.toImage(false);
glDeleteBuffers(2, ssbo);
if (releaseContext) glWidget->doneCurrent();
return { image, leftTop };
}
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;
}

View File

@ -3,40 +3,32 @@
#include <QOpenGLFunctions_4_5_Core>
#include <QOPenGLShaderProgram>
#include "../Painting/ElementStyle.h"
#include <QOffscreenSurface>
namespace Renderer
{
class ElementRenderer
class ElementRenderer : protected QOpenGLFunctions_4_5_Core
{
public:
static ElementRenderer* instance();
ElementRenderer(QOpenGLWidget* glWidget);
/**
* @brief initializeGL
*/
void initialize();
/**
* @brief QImage
* @param path
* @param style
* @param pixelRatio path
* @param releaseContext initializeGL, resizeGLpaintGLfalse
* @return QImage
* @return QPointF QPainterPath
*/
std::pair<QImage, QPointF> drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio);
std::pair<QImage, QPointF> drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio, bool releaseContext = true);
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();
};
}

View File

@ -73,14 +73,17 @@ void RendererGLWidget::stopTimer()
timerId = -1;
}
void RendererGLWidget::setModel(QString path)
void RendererGLWidget::setModel()
{
makeCurrent();
//model->loadModel("Models/Sponza/Sponza.gltf");
//model->loadModel("E:\\3D Objects\\Gate\\gltf\\Gate.gltf");
model->loadModel(path);
model->loadModel("Models/Sponza/Sponza.gltf");
//model = new Model("E:\\3D Objects\\gallery_gltf\\gallery_gltf.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper);
light.model = model;
qDebug() << model->AABB;
//paintingHelper->allocateBuffers();
//paintingCompProgramPtr->bind();
//paintingHelper->bindPaintingBuffers();
//paintingCompProgramPtr->release();
doneCurrent();
}

View File

@ -26,7 +26,7 @@ namespace Renderer
void startTimer();
void stopTimer();
public slots:
void setModel(QString path);
void setModel();
void setMainLightPitch(float pitch);
void setMainLightYaw(float yaw);
void setExposure(float exposure);

View File

@ -1,62 +1,29 @@
#include "RendererWidget.h"
#include "RendererGLWidget.h"
#include "../FluentMenu.h"
#include <QFileDialog>
Renderer::RendererWidget::RendererWidget(QWidget* parent)
using namespace 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, &Renderer::RendererGLWidget::setMainLightPitch);
ui.openGLWidget, &RendererGLWidget::setMainLightPitch);
QObject::connect(ui.horizontalSlider_2, &QSlider::valueChanged,
ui.openGLWidget, &Renderer::RendererGLWidget::setMainLightYaw);
ui.openGLWidget, &RendererGLWidget::setMainLightYaw);
QObject::connect(ui.exposureSlider, &QSlider::valueChanged, [&](int value) {
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.openGLWidget->setExposure(value/100.f);
});
ui.horizontalSlider->setValue(105);
ui.horizontalSlider_2->setValue(80);
ui.exposureSlider->setValue(60);
QObject::connect(ui.openButton, &QPushButton::clicked,
ui.openGLWidget, &RendererGLWidget::setModel);
}
Renderer::RendererWidget::~RendererWidget()
RendererWidget::~RendererWidget()
{}
void Renderer::RendererWidget::currentTabChanged(int index)
void RendererWidget::currentTabChanged(int index)
{
if (index == 1)
{
@ -66,5 +33,4 @@ void Renderer::RendererWidget::currentTabChanged(int index)
{
ui.openGLWidget->stopTimer();
}
}
}

View File

@ -1,14 +1,15 @@
#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:

View File

@ -18,7 +18,7 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain)
surface.create();
mainContext->doneCurrent();
thread = std::jthread([&](std::stop_token stop) {
thread = std::jthread([&] {
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 (!stop.stop_requested())
while (true)
{
if (needUpdate)
{
@ -85,7 +85,6 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain)
//qDebug() << duration;
pageLoadDuration += duration;
}
std::this_thread::yield();
}
});

View File

@ -0,0 +1,80 @@
/*
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);
}

View File

@ -0,0 +1,54 @@
/*
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

View File

@ -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();

View File

@ -12,20 +12,14 @@ namespace UnitTest
{
TEST_CLASS(ElementRendererStokeTypeTest)
{
private:
char* argv[1];
int argc;
public:
ElementRendererStokeTypeTest() :argv{ (char*)"" }, argc(1) {}
TEST_METHOD_INITIALIZE(initialize)
TEST_METHOD(TestBothSidesRound)
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
}
TEST_METHOD(TestBothSidesRound)
{
char* argv[] = { (char*)"" };
int argc = 1;
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
@ -47,6 +41,11 @@ 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
{
@ -68,6 +67,11 @@ 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
{
@ -89,6 +93,11 @@ 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
{
@ -112,13 +121,14 @@ 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
{
@ -135,6 +145,11 @@ 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
{
@ -156,6 +171,11 @@ 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
{

View File

@ -14,14 +14,15 @@ 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(*Renderer::ElementRenderer::instance()), style(style) {};
: QOpenGLWidget(parent), renderer(this), style(style) {};
void initializeGL() override
{
initializeOpenGLFunctions();
renderer.initialize();
};
void paintGL() override
{
@ -34,7 +35,7 @@ namespace UnitTest
transform.scale(10, 10);
path = transform.map(path);
float pixelRatio = devicePixelRatioF();
auto [img, pos] = renderer.drawElement(path, style, pixelRatio);
auto [img, pos] = renderer.drawElement(path, style, pixelRatio, false);
QPainter painter(this);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.setRenderHint(QPainter::HighQualityAntialiasing);

View File

@ -1,53 +0,0 @@
#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();
}
};
}

View File

@ -1,66 +0,0 @@
#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 {};
};
}

View File

@ -1,12 +1,11 @@
#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;
@ -44,24 +43,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)
@ -95,28 +94,5 @@ 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();
}
};
}

View File

@ -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;$(SolutionDir)qt-material-widgets\components;%(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;%(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;$(SolutionDIr)qt-material-widgets\components\debug\components.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;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -111,12 +111,6 @@
<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>
@ -131,9 +125,6 @@
<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" />

View File

@ -37,16 +37,10 @@
<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>