git-svn-id: svn://db.shs.com.ru/libs@626 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2019-11-22 15:20:52 +00:00
parent 5e2b563d57
commit 09248aae34
128 changed files with 16038 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
project(qglengine_widgets)
cmake_minimum_required(VERSION 2.6)
if (POLICY CMP0017)
cmake_policy(SET CMP0017 NEW)
endif()
find_qt(Qt5 Core Gui Widgets)
qt_sources(SRC)
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
file(GLOB PHS "*_p.h")
list(REMOVE_ITEM out_HDR "${PHS}")
qt_add_library(${PROJECT_NAME} SHARED out_CPP)
qt_target_link_libraries(${PROJECT_NAME} qad_utils qad_widgets qglengine_core)
list(APPEND QT_MULTILIB_LIST ${PROJECT_NAME})
set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE)
message(STATUS "Building ${PROJECT_NAME}")
if (LIBPROJECT)
sdk_install("qglengine" "${PROJECT_NAME}" "${out_HDR}" "${out_QM}")
else()
if (LIB)
if (WIN32)
qt_install(FILES ${out_HDR} DESTINATION ${MINGW_INCLUDE}/qglengine)
qt_install(TARGETS ${PROJECT_NAME} DESTINATION ${MINGW_LIB})
qt_install(TARGETS ${PROJECT_NAME} DESTINATION ${MINGW_BIN})
qt_install(TARGETS ${PROJECT_NAME} DESTINATION QtBin)
else()
qt_install(FILES ${H} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/qglengine)
qt_install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
else()
qt_install(TARGETS ${PROJECT_NAME} DESTINATION bin)
message(STATUS "Install ${PROJECT_NAME} to local \"bin\"")
endif()
endif()

View File

@@ -0,0 +1,227 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "material_editor.h"
#include "ui_material_editor.h"
#include "glmaterial.h"
MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::MaterialEditor();
ui->setupUi(this);
ui->checkGlass->hide();
ui->frameReflection->hide();
ui->label_13->hide();
mat = 0;
active = true;
}
void MaterialEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void MaterialEditor::materialChanged() {
if (!active || !mat) return;
mat->_changed = true;
mat->color_diffuse = ui->colorDiffuse ->color();
mat->color_specular = ui->colorSpecular->color();
mat->color_emission = ui->colorEmission->color();
mat->transparency = ui->spinTransparent->value();
mat->reflectivity = ui->spinReflect->value();
mat->iof = ui->spinIOF->value();
mat->dispersion = ui->spinDispersion->value();
mat->glass = ui->checkGlass->isChecked();
emit changed();
}
void MaterialEditor::setMaterial(Material * m) {
active = false;
mat = m;
setEnabled(m);
if (!mat) return;
ui->colorDiffuse ->setColor(mat->color_diffuse );
ui->colorSpecular->setColor(mat->color_specular);
ui->colorEmission->setColor(mat->color_emission);
ui->spinTransparent->setValue(mat->transparency);
ui->spinReflect->setValue(mat->reflectivity);
ui->spinIOF->setValue(mat->iof);
ui->spinDispersion->setValue(mat->dispersion);
ui->checkGlass->setChecked(mat->glass);
ui->mapDiffuse ->setMap(&(mat->map_diffuse ));
ui->mapNormal ->setMap(&(mat->map_normal ));
ui->mapSpecular ->setMap(&(mat->map_specular ));
ui->mapRoughness->setMap(&(mat->map_roughness));
ui->mapEmission ->setMap(&(mat->map_emission ));
ui->mapRelief ->setMap(&(mat->map_relief ));
/*ui->lineReflFront->setProperty("GLpath", mat->map_reflection.path(0)); ui->lineReflFront->setText(QFileInfo(mat->map_reflection.path(0)).fileName());
ui->lineReflBack->setProperty("GLpath", mat->map_reflection.path(1)); ui->lineReflBack->setText(QFileInfo(mat->map_reflection.path(1)).fileName());
ui->lineReflLeft->setProperty("GLpath", mat->map_reflection.path(2)); ui->lineReflLeft->setText(QFileInfo(mat->map_reflection.path(2)).fileName());
ui->lineReflRight->setProperty("GLpath", mat->map_reflection.path(3)); ui->lineReflRight->setText(QFileInfo(mat->map_reflection.path(3)).fileName());
ui->lineReflTop->setProperty("GLpath", mat->map_reflection.path(4)); ui->lineReflTop->setText(QFileInfo(mat->map_reflection.path(4)).fileName());
ui->lineReflBottom->setProperty("GLpath", mat->map_reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(mat->map_reflection.path(5)).fileName());
*/active = true;
}
/*
Material MaterialEditor::material() {
Material m;
mat->color_diffuse = ui->colorDiffuse ->color();
mat->color_specular = ui->colorSpecular->color();
mat->color_emission = ui->colorEmission->color();
mat->transparency = ui->spinTransparent->value();
mat->reflectivity = ui->spinReflect->value();
mat->iof = ui->spinIOF->value();
mat->dispersion = ui->spinDispersion->value();
mat->glass = ui->checkGlass->isChecked();
mat->map_diffuse = ui->mapDiffuse->map();
mat->map_normal = ui->mapNormal->map();
mat->map_specular = ui->mapSpecular->map();
mat->map_roughness = ui->mapRoughness->map();
mat->map_emission = ui->mapEmission->map();
mat->map_relief = ui->mapRelief->map();
mat->map_reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
mat->map_reflection.setPath(1, ui->lineReflBack->property("GLpath").toString());
mat->map_reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString());
mat->map_reflection.setPath(3, ui->lineReflRight->property("GLpath").toString());
mat->map_reflection.setPath(4, ui->lineReflTop->property("GLpath").toString());
mat->map_reflection.setPath(5, ui->lineReflBottom->property("GLpath").toString());
return m;
}
*/
void MaterialEditor::on_buttonReflFrontSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflFront->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineReflFront->setProperty("GLpath", str);
ui->lineReflFront->setText(QFileInfo(str).fileName());
materialChanged();
}
void MaterialEditor::on_buttonReflBackSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflBack->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineReflBack->setProperty("GLpath", str);
ui->lineReflBack->setText(QFileInfo(str).fileName());
materialChanged();
}
void MaterialEditor::on_buttonReflLeftSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflLeft->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineReflLeft->setProperty("GLpath", str);
ui->lineReflLeft->setText(QFileInfo(str).fileName());
materialChanged();
}
void MaterialEditor::on_buttonReflRightSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflRight->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineReflRight->setProperty("GLpath", str);
ui->lineReflRight->setText(QFileInfo(str).fileName());
materialChanged();
}
void MaterialEditor::on_buttonReflTopSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflTop->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineReflTop->setProperty("GLpath", str);
ui->lineReflTop->setText(QFileInfo(str).fileName());
materialChanged();
}
void MaterialEditor::on_buttonReflBottomSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflBottom->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineReflBottom->setProperty("GLpath", str);
ui->lineReflBottom->setText(QFileInfo(str).fileName());
materialChanged();
}
void MaterialEditor::on_buttonReflFrontClear_clicked() {
ui->lineReflFront->setText("");
ui->lineReflFront->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonReflBackClear_clicked() {
ui->lineReflBack->setText("");
ui->lineReflBack->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonReflLeftClear_clicked() {
ui->lineReflLeft->setText("");
ui->lineReflLeft->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonReflRightClear_clicked() {
ui->lineReflRight->setText("");
ui->lineReflRight->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonReflTopClear_clicked() {
ui->lineReflTop->setText("");
ui->lineReflTop->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonReflBottomClear_clicked() {
ui->lineReflBottom->setText("");
ui->lineReflBottom->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonLoadCubeDir_clicked() {
QString dir = QFileDialog::getExistingDirectory(this, "Select directory", ui->lineReflFront->property("GLpath").toString());
if (dir.isEmpty()) return;
/*CubeTexture cb(0);
cb.loadPathesFromDirectory(dir);
active = false;
ui->lineReflFront->setProperty("GLpath", cb.path(0)); ui->lineReflFront->setText(QFileInfo(cb.path(0)).fileName());
ui->lineReflBack->setProperty("GLpath", cb.path(1)); ui->lineReflBack->setText(QFileInfo(cb.path(1)).fileName());
ui->lineReflLeft->setProperty("GLpath", cb.path(2)); ui->lineReflLeft->setText(QFileInfo(cb.path(2)).fileName());
ui->lineReflRight->setProperty("GLpath", cb.path(3)); ui->lineReflRight->setText(QFileInfo(cb.path(3)).fileName());
ui->lineReflTop->setProperty("GLpath", cb.path(4)); ui->lineReflTop->setText(QFileInfo(cb.path(4)).fileName());
ui->lineReflBottom->setProperty("GLpath", cb.path(5)); ui->lineReflBottom->setText(QFileInfo(cb.path(5)).fileName());*/
active = true;
materialChanged();
}

View File

@@ -0,0 +1,65 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MATERIAL_EDITOR_H
#define MATERIAL_EDITOR_H
#include <QFileDialog>
#include "gltypes.h"
namespace Ui {
class MaterialEditor;
}
class MaterialEditor: public QWidget
{
Q_OBJECT
public:
explicit MaterialEditor(QWidget * parent = 0);
void setMaterial(Material * m);
protected:
void changeEvent(QEvent * e);
bool active;
Ui::MaterialEditor * ui;
Material * mat;
private slots:
void materialChanged();
void on_buttonReflFrontSelect_clicked();
void on_buttonReflFrontClear_clicked();
void on_buttonReflBackSelect_clicked();
void on_buttonReflBackClear_clicked();
void on_buttonReflLeftSelect_clicked();
void on_buttonReflLeftClear_clicked();
void on_buttonReflRightSelect_clicked();
void on_buttonReflRightClear_clicked();
void on_buttonReflTopSelect_clicked();
void on_buttonReflTopClear_clicked();
void on_buttonReflBottomSelect_clicked();
void on_buttonReflBottomClear_clicked();
void on_buttonLoadCubeDir_clicked();
signals:
void changed();
};
#endif // MATERIAL_EDITOR_H

View File

@@ -0,0 +1,975 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaterialEditor</class>
<widget class="QWidget" name="MaterialEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>435</width>
<height>817</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<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="QGroupBox" name="groupDiffuse">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Diffuse</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QWidget" name="widgetDiffuse" native="true">
<layout class="QGridLayout" name="gridLayout">
<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 row="0" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorDiffuse">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapDiffuse" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupNormal">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Normal</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="MaterialMapEditor" name="mapNormal" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupSpecular">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Specular</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QWidget" name="widgetSpecular" native="true">
<layout class="QGridLayout" name="gridLayout_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 row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorSpecular">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapSpecular" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupRoughness">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Roughness</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="MaterialMapEditor" name="mapRoughness" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupEmission">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Emisson</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QWidget" name="widgetEmission" native="true">
<layout class="QGridLayout" name="gridLayout_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 row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorEmission">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapEmission" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupRelief">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Relief</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="MaterialMapEditor" name="mapRelief" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<item row="0" column="1">
<widget class="QCheckBox" name="checkGlass">
<property name="text">
<string>Glass</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Transparency</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SpinSlider" name="spinTransparent">
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="pageStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Reflectivity</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SpinSlider" name="spinReflect">
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="pageStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>IOF</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="SpinSlider" name="spinIOF">
<property name="maximum">
<double>2.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="pageStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Dispersion</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="SpinSlider" name="spinDispersion">
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="pageStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Reflection map</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QFrame" name="frameReflection">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="1" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Front:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Back:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Left:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Right:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Top:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Bottom:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineReflLeft"/>
</item>
<item>
<widget class="QToolButton" name="buttonReflLeftClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonReflLeftSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineReflFront"/>
</item>
<item>
<widget class="QToolButton" name="buttonReflFrontClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonReflFrontSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineReflBack"/>
</item>
<item>
<widget class="QToolButton" name="buttonReflBackClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonReflBackSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineReflRight"/>
</item>
<item>
<widget class="QToolButton" name="buttonReflRightClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonReflRightSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineReflTop"/>
</item>
<item>
<widget class="QToolButton" name="buttonReflTopClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonReflTopSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineReflBottom"/>
</item>
<item>
<widget class="QToolButton" name="buttonReflBottomClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonReflBottomSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0" colspan="2">
<widget class="QPushButton" name="buttonLoadCubeDir">
<property name="text">
<string>load from directory</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SpinSlider</class>
<extends>QWidget</extends>
<header>spinslider.h</header>
</customwidget>
<customwidget>
<class>ColorButton</class>
<extends>QPushButton</extends>
<header>colorbutton.h</header>
</customwidget>
<customwidget>
<class>MaterialMapEditor</class>
<extends>QWidget</extends>
<header>material_map_editor.h</header>
<container>1</container>
<slots>
<signal>changed()</signal>
</slots>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>colorDiffuse</sender>
<signal>colorChanged(QColor)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>326</x>
<y>49</y>
</hint>
<hint type="destinationlabel">
<x>282</x>
<y>17</y>
</hint>
</hints>
</connection>
<connection>
<sender>colorSpecular</sender>
<signal>colorChanged(QColor)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>376</x>
<y>202</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
<y>45</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinTransparent</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>433</x>
<y>497</y>
</hint>
<hint type="destinationlabel">
<x>283</x>
<y>149</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinReflect</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>433</x>
<y>526</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
<y>174</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinIOF</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>433</x>
<y>555</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
<y>236</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkGlass</sender>
<signal>toggled(bool)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>433</x>
<y>468</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
<y>84</y>
</hint>
</hints>
</connection>
<connection>
<sender>colorEmission</sender>
<signal>colorChanged(QColor)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>421</x>
<y>351</y>
</hint>
<hint type="destinationlabel">
<x>326</x>
<y>63</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinDispersion</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>433</x>
<y>584</y>
</hint>
<hint type="destinationlabel">
<x>326</x>
<y>288</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapDiffuse</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>421</x>
<y>69</y>
</hint>
<hint type="destinationlabel">
<x>434</x>
<y>63</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapSpecular</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>421</x>
<y>218</y>
</hint>
<hint type="destinationlabel">
<x>434</x>
<y>143</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapEmission</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>421</x>
<y>367</y>
</hint>
<hint type="destinationlabel">
<x>434</x>
<y>216</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapNormal</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>421</x>
<y>129</y>
</hint>
<hint type="destinationlabel">
<x>434</x>
<y>260</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapRelief</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>421</x>
<y>427</y>
</hint>
<hint type="destinationlabel">
<x>434</x>
<y>304</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapRoughness</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>421</x>
<y>278</y>
</hint>
<hint type="destinationlabel">
<x>434</x>
<y>250</y>
</hint>
</hints>
</connection>
<connection>
<sender>groupDiffuse</sender>
<signal>toggled(bool)</signal>
<receiver>widgetDiffuse</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>40</x>
<y>10</y>
</hint>
<hint type="destinationlabel">
<x>47</x>
<y>56</y>
</hint>
</hints>
</connection>
<connection>
<sender>groupNormal</sender>
<signal>toggled(bool)</signal>
<receiver>mapNormal</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>54</x>
<y>103</y>
</hint>
<hint type="destinationlabel">
<x>55</x>
<y>123</y>
</hint>
</hints>
</connection>
<connection>
<sender>groupSpecular</sender>
<signal>toggled(bool)</signal>
<receiver>widgetSpecular</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>72</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>71</x>
<y>205</y>
</hint>
</hints>
</connection>
<connection>
<sender>groupRoughness</sender>
<signal>toggled(bool)</signal>
<receiver>mapRoughness</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>56</x>
<y>246</y>
</hint>
<hint type="destinationlabel">
<x>55</x>
<y>273</y>
</hint>
</hints>
</connection>
<connection>
<sender>groupEmission</sender>
<signal>toggled(bool)</signal>
<receiver>widgetEmission</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>67</x>
<y>314</y>
</hint>
<hint type="destinationlabel">
<x>71</x>
<y>353</y>
</hint>
</hints>
</connection>
<connection>
<sender>groupRelief</sender>
<signal>toggled(bool)</signal>
<receiver>mapRelief</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>42</x>
<y>397</y>
</hint>
<hint type="destinationlabel">
<x>44</x>
<y>422</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>materialChanged()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,107 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this programap-> If not, see <http://www.gnu.org/licenses/>.
*/
#include "material_map_editor.h"
#include "ui_material_map_editor.h"
#include "glmaterial.h"
MaterialMapEditor::MaterialMapEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::MaterialMapEditor();
ui->setupUi(this);
active = true;
}
void MaterialMapEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void MaterialMapEditor::resizeEvent(QResizeEvent * e) {
ui->iconedLabel->setFixedWidth(ui->iconedLabel->height());
ui->iconedLabel->setIconSize(ui->iconedLabel->size());
}
void MaterialMapEditor::updateIcon() {
ui->iconedLabel->setIcon(QIcon(ui->linePath->property("GLpath").toString()));
}
void MaterialMapEditor::mapChanged() {
if (!active || !map) return;
map->color_amount = ui->sliderAmount->value();
map->color_offset = ui->sliderOffset->value();
map->bitmap_scale.setX(ui->spinScaleX->value());
map->bitmap_scale.setY(ui->spinScaleY->value());
emit changed();
}
void MaterialMapEditor::setMap(Map * m) {
active = false;
map = m;
setEnabled(m);
if (!map) return;
ui->sliderAmount->setValue(map->color_amount);
ui->sliderOffset->setValue(map->color_offset);
ui->spinScaleX->setValue(map->bitmap_scale.x());
ui->spinScaleY->setValue(map->bitmap_scale.y());
ui->linePath->setProperty("GLpath", map->bitmap_path); ui->linePath->setText(QFileInfo(map->bitmap_path).fileName());
updateIcon();
active = true;
}
/*
Map MaterialMapEditor::map() {
Map m;
map->color_amount = ui->sliderAmount->value();
map->color_offset = ui->sliderOffset->value();
map->bitmap_scale.setX(ui->spinScaleX->value());
map->bitmap_scale.setY(ui->spinScaleY->value());
map->bitmap_path = ui->linePath->property("GLpath").toString();
return m;
}
*/
void MaterialMapEditor::on_buttonSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->linePath->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->linePath->setProperty("GLpath", str);
ui->linePath->setText(QFileInfo(str).fileName());
map->setBitmapPath(str);
updateIcon();
mapChanged();
}
void MaterialMapEditor::on_buttonClear_clicked() {
ui->linePath->setText("");
ui->linePath->setProperty("GLpath", "");
map->clearBitmap();
updateIcon();
mapChanged();
}

View File

@@ -0,0 +1,56 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MATERIAL_MAP_EDITOR_H
#define MATERIAL_MAP_EDITOR_H
#include <QFileDialog>
#include "gltypes.h"
namespace Ui {
class MaterialMapEditor;
}
class MaterialMapEditor: public QWidget
{
Q_OBJECT
public:
explicit MaterialMapEditor(QWidget * parent = 0);
void setMap(Map * m);
protected:
void changeEvent(QEvent * e);
void resizeEvent(QResizeEvent * e);
void updateIcon();
bool active;
Ui::MaterialMapEditor * ui;
Map * map;
private slots:
void mapChanged();
void on_buttonSelect_clicked();
void on_buttonClear_clicked();
signals:
void changed();
};
#endif // MATERIAL_MAP_EDITOR_H

View File

@@ -0,0 +1,321 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaterialMapEditor</class>
<widget class="QWidget" name="MaterialMapEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>587</width>
<height>138</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<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="IconedLabel" name="iconedLabel">
<property name="direction">
<enum>IconedLabel::RightToLeft</enum>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="linePath"/>
</item>
<item>
<widget class="QToolButton" name="buttonClear">
<property name="icon">
<iconset resource="../qad/utils/qad_utils.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonSelect">
<property name="icon">
<iconset resource="../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Amount:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SpinSlider" name="sliderAmount">
<property name="minimum">
<double>-1.000000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="pageStep">
<double>0.200000000000000</double>
</property>
<property name="spinMinimum">
<double>-99.000000000000000</double>
</property>
<property name="spinMaximum">
<double>99.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Offset:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SpinSlider" name="sliderOffset">
<property name="minimum">
<double>-1.000000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="pageStep">
<double>0.200000000000000</double>
</property>
<property name="spinMinimum">
<double>-99.000000000000000</double>
</property>
<property name="spinMaximum">
<double>99.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Scale X:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinScaleX">
<property name="maximum">
<double>9999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Scale Y:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinScaleY">
<property name="maximum">
<double>9999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SpinSlider</class>
<extends>QWidget</extends>
<header>spinslider.h</header>
</customwidget>
<customwidget>
<class>IconedLabel</class>
<extends>QFrame</extends>
<header>iconedlabel.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../qad/utils/qad_utils.qrc"/>
<include location="../qad/application/qad_application.qrc"/>
</resources>
<connections>
<connection>
<sender>linePath</sender>
<signal>textChanged(QString)</signal>
<receiver>MaterialMapEditor</receiver>
<slot>mapChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>471</x>
<y>22</y>
</hint>
<hint type="destinationlabel">
<x>99</x>
<y>73</y>
</hint>
</hints>
</connection>
<connection>
<sender>sliderAmount</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialMapEditor</receiver>
<slot>mapChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>440</x>
<y>38</y>
</hint>
<hint type="destinationlabel">
<x>512</x>
<y>37</y>
</hint>
</hints>
</connection>
<connection>
<sender>sliderOffset</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialMapEditor</receiver>
<slot>mapChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>497</x>
<y>66</y>
</hint>
<hint type="destinationlabel">
<x>511</x>
<y>65</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinScaleX</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialMapEditor</receiver>
<slot>mapChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>377</x>
<y>104</y>
</hint>
<hint type="destinationlabel">
<x>332</x>
<y>164</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinScaleY</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialMapEditor</receiver>
<slot>mapChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>519</x>
<y>110</y>
</hint>
<hint type="destinationlabel">
<x>493</x>
<y>164</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>mapChanged()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,177 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "materials_editor.h"
#include "ui_materials_editor.h"
#include "material_editor.h"
#include "qglview.h"
#include "glmaterial.h"
#include <qad_types.h>
#include <ecombobox.h>
#include <QInputDialog>
MaterialsEditor::MaterialsEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::MaterialsEditor();
ui->setupUi(this);
ui->widgetMaterial->setMaterial(0);
view = 0;
}
void MaterialsEditor::assignQGLView(QGLView * v) {
view = v;
connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
connect(view, SIGNAL(materialsChanged()), this, SLOT(materialsChanged()));
connect(view, SIGNAL(materialThumbnailCreated(Material*)), this, SLOT(materialThumbnailCreated(Material*)));
materialsChanged();
}
bool MaterialsEditor::event(QEvent * e) {
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) {
QSize sz = preferredIconSize(1.5, this);
ui->comboMaterial->setIconSize(sz * 3);
ui->buttonRename->setIconSize(sz);
ui->buttonAdd ->setIconSize(sz);
ui->buttonDelete->setIconSize(sz);
ui->buttonAssign->setIconSize(sz);
}
return QWidget::event(e);
}
void MaterialsEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
Material * MaterialsEditor::currentMaterial() {
if (!view) return 0;
int ind = ui->comboMaterial->currentIndex();
QVector<Material*> mats = view->scene()->getMaterials();
if (ind < 0 || ind >= mats.size()) return 0;
return mats[ind];
}
void MaterialsEditor::selectMaterial(Material * m) {
if (!m) {
ui->comboMaterial->setCurrentIndex(-1);
return;
}
for (int i = 0; i < ui->comboMaterial->count(); ++i) {
if ((Material*)(ui->comboMaterial->itemData(i, Qt::UserRole + 1).value<quintptr>()) == m) {
ui->comboMaterial->setCurrentIndex(i);
break;
}
}
}
int MaterialsEditor::indexByMaterial(Material * m) {
if (!m) return -1;
for (int i = 0; i < ui->comboMaterial->count(); ++i) {
if ((Material*)(ui->comboMaterial->itemData(i, Qt::UserRole + 1).value<quintptr>()) == m)
return i;
}
return -1;
}
void MaterialsEditor::selectionChanged() {
if (!view) return;
//qDebug() << "selectionChanged";
ObjectBase * o = view->selectedObject();
if (o) selectMaterial(o->material());
}
void MaterialsEditor::materialsChanged() {
Material * cm = currentMaterial();
ui->comboMaterial->clear();
if (!view) return;
QVector<Material*> mats = view->scene()->getMaterials();
for (int i = 0; i < mats.size(); ++i) {
Material * m = mats[i];
ui->comboMaterial->addItem(QString("[%1] " + m->name).arg(i + 1), QVariant(m->name));
ui->comboMaterial->setItemData(i, QVariant(quintptr(m)), Qt::UserRole + 1);
ui->comboMaterial->setItemIcon(i, QIcon(QPixmap::fromImage(view->materialThumbnail(m))));
if (cm == m) ui->comboMaterial->setCurrentIndex(i);
}
}
void MaterialsEditor::materialThumbnailCreated(Material * m) {
//qDebug() << "materialThumbnailCreated" << m;
int i = indexByMaterial(m);
if (i < 0 || !view) return;
//qDebug() << "materialThumbnailCreated set to" << i;
ui->comboMaterial->setItemIcon(i, QIcon(QPixmap::fromImage(view->materialThumbnail(m))));
}
void MaterialsEditor::on_comboMaterial_currentIndexChanged(int index) {
ui->widgetMaterial->setMaterial(currentMaterial());
}
void MaterialsEditor::on_buttonRename_clicked() {
Material * m = currentMaterial();
if (!m) return;
QString nn = QInputDialog::getText(this, "Materials editor", "Input new name:", QLineEdit::Normal, m->name);
if (nn.isEmpty()) return;
m->name = nn;
int ind = ui->comboMaterial->currentIndex();
ui->comboMaterial->setItemText(ind, QString("[%1] " + nn).arg(ind + 1));
ui->comboMaterial->setItemData(ind, nn);
}
void MaterialsEditor::on_buttonAdd_clicked() {
if (!view) return;
Material * m = view->scene()->newMaterial();
materialsChanged();
selectMaterial(m);
}
void MaterialsEditor::on_buttonDelete_clicked() {
if (!view) return;
Material * m = currentMaterial();
if (!m) return;
view->scene()->removeMaterial(m);
materialsChanged();
}
void MaterialsEditor::on_buttonAssign_clicked() {
if (!view) return;
Material * m = currentMaterial();
QList<ObjectBase*> ol = view->selectedObjects();
foreach (ObjectBase * o, ol)
o->setMaterial(m, true);
}

View File

@@ -0,0 +1,64 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MATERIALS_EDITOR_H
#define MATERIALS_EDITOR_H
#include <QFileDialog>
#include "gltypes.h"
namespace Ui {
class MaterialsEditor;
}
class MaterialsEditor: public QWidget
{
Q_OBJECT
public:
explicit MaterialsEditor(QWidget * parent = 0);
void assignQGLView(QGLView * v);
protected:
bool event(QEvent * e);
void changeEvent(QEvent * e);
Material * currentMaterial();
void selectMaterial(Material * m);
int indexByMaterial(Material * m);
Ui::MaterialsEditor * ui;
QGLView * view;
Material * mat;
private slots:
void selectionChanged();
void materialsChanged();
void materialThumbnailCreated(Material * m);
void on_comboMaterial_currentIndexChanged(int index);
void on_buttonRename_clicked();
void on_buttonAdd_clicked();
void on_buttonDelete_clicked();
void on_buttonAssign_clicked();
signals:
void changed();
};
#endif // MATERIALS_EDITOR_H

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaterialsEditor</class>
<widget class="QWidget" name="MaterialsEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>542</width>
<height>492</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="EComboBox" name="comboMaterial">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonRename">
<property name="toolTip">
<string>Rename ...</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/edit-rename.png</normaloff>:/icons/edit-rename.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonAdd">
<property name="toolTip">
<string>Add</string>
</property>
<property name="icon">
<iconset resource="widgets.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonDelete">
<property name="toolTip">
<string>Delete</string>
</property>
<property name="icon">
<iconset resource="widgets.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="buttonAssign">
<property name="toolTip">
<string>Assign</string>
</property>
<property name="icon">
<iconset resource="widgets.qrc">
<normaloff>:/icons/go-jump.png</normaloff>:/icons/go-jump.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>522</width>
<height>440</height>
</rect>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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="MaterialEditor" name="widgetMaterial" native="true"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>421</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>EComboBox</class>
<extends>QComboBox</extends>
<header>ecombobox.h</header>
</customwidget>
<customwidget>
<class>MaterialEditor</class>
<extends>QWidget</extends>
<header>material_editor.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="widgets.qrc"/>
<include location="../qglview.qrc"/>
</resources>
<connections/>
<slots>
<slot>materialChanged()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,177 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "object_editor.h"
#include "ui_object_editor.h"
#include "glcamera.h"
ObjectEditor::ObjectEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::ObjectEditor();
ui->setupUi(this);
active = true;
object = 0;
rmodes << ObjectBase::View << ObjectBase::Point << ObjectBase::Line << ObjectBase::Fill;
ui->groupLight->setEnabled(false);
ui->groupLight->setVisible(false);
ui->groupCamera->setEnabled(false);
ui->groupCamera->setVisible(false);
}
void ObjectEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void ObjectEditor::setObject(ObjectBase * o) {
object = o;
if (object == 0) {
ui->groupLight->setEnabled(false);
ui->groupLight->setVisible(false);
ui->groupCamera->setEnabled(false);
ui->groupCamera->setVisible(false);
return;
}
ui->buttonDiscardRawMatrix->setEnabled(o->isRawMatrix());
active = false;
ui->spinPosX->setValue(object->posX());
ui->spinPosY->setValue(object->posY());
ui->spinPosZ->setValue(object->posZ());
ui->spinRotationX->setValue(object->rotationX());
ui->spinRotationY->setValue(object->rotationY());
ui->spinRotationZ->setValue(object->rotationZ());
ui->spinScaleX->setValue(object->scaleX());
ui->spinScaleY->setValue(object->scaleY());
ui->spinScaleZ->setValue(object->scaleZ());
ui->spinLineWidth->setValue(object->lineWidth());
ui->checkVisible->setChecked(object->isVisible());
ui->checkAcceptLight->setChecked(object->isAcceptLight());
ui->checkAcceptFog->setChecked(object->isAcceptFog());
ui->checkCastShadows->setChecked(object->isCastShadows());
ui->checkReceiveShadows->setChecked(object->isReceiveShadows());
ui->comboRenderMode->setCurrentIndex(rmodes.indexOf(object->renderMode()));
ui->groupLight->setEnabled(object->type() == ObjectBase::glLight);
ui->groupLight->setVisible(object->type() == ObjectBase::glLight);
ui->buttonColor->setColor(object->color());
if (object->type() == ObjectBase::glLight) {
Light * l = globject_cast<Light * >(object);
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
ui->comboLightType->setCurrentIndex(l->light_type);
ui->spinLightIntensity->setValue(l->intensity);
ui->spinLightDecayConst->setValue(l->decay_const);
ui->spinLightDecayLinear->setValue(l->decay_linear);
ui->spinLightDecayQuadratic->setValue(l->decay_quadratic);
ui->spinLightAngleStart->setValue(l->angle_start);
ui->spinLightAngleEnd->setValue(l->angle_end);
ui->spinLightDirectionX->setValue(l->direction.x());
ui->spinLightDirectionY->setValue(l->direction.y());
ui->spinLightDirectionZ->setValue(l->direction.z());
}
ui->groupCamera->setEnabled(object->type() == ObjectBase::glCamera);
ui->groupCamera->setVisible(object->type() == ObjectBase::glCamera);
if (object->type() == ObjectBase::glCamera) {
Camera * c = globject_cast<Camera * >(object);
ui->checkCameraMirrorX->setChecked(c->isMirrorX());
ui->checkCameraMirrorY->setChecked(c->isMirrorY());
ui->spinCameraFOV->setValue(c->FOV());
ui->spinCameraDepthStart->setValue(c->depthStart());
ui->spinCameraDepthEnd->setValue(c->depthEnd());
}
active = true;
}
void ObjectEditor::objectChanged() {
if (!active || object == 0) return;
if (!object->isRawMatrix()) {
object->setPosX(ui->spinPosX->value());
object->setPosY(ui->spinPosY->value());
object->setPosZ(ui->spinPosZ->value());
object->setRotationX(ui->spinRotationX->value());
object->setRotationY(ui->spinRotationY->value());
object->setRotationZ(ui->spinRotationZ->value());
object->setScaleX(ui->spinScaleX->value());
object->setScaleY(ui->spinScaleY->value());
object->setScaleZ(ui->spinScaleZ->value());
}
/*object->setLineWidth(ui->spinLineWidth->value());
object->setVisible(ui->checkVisible->isChecked());
object->setAcceptLight(ui->checkAcceptLight->isChecked());
object->setAcceptFog(ui->checkAcceptFog->isChecked());
object->setCastShadows(ui->checkCastShadows->isChecked());
object->setReceiveShadows(ui->checkReceiveShadows->isChecked());
object->setRenderMode((ObjectBase::RenderMode)rmodes[ui->comboRenderMode->currentIndex()]);*/
object->setColor(ui->buttonColor->color());
if (object->type() == ObjectBase::glLight) {
Light * l = globject_cast<Light * >(object);
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
l->light_type = (Light::Type)ui->comboLightType->currentIndex();
l->intensity = ui->spinLightIntensity->value();
l->decay_const = ui->spinLightDecayConst->value();
l->decay_linear = ui->spinLightDecayLinear->value();
l->decay_quadratic = ui->spinLightDecayQuadratic->value();
l->angle_start = ui->spinLightAngleStart->value();
l->angle_end = ui->spinLightAngleEnd->value();
l->direction = QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized();
l->apply();
}
if (object->type() == ObjectBase::glCamera) {
Camera * c = globject_cast<Camera * >(object);
c->setMirrorX(ui->checkCameraMirrorX->isChecked());
c->setMirrorY(ui->checkCameraMirrorY->isChecked());
c->setFOV(ui->spinCameraFOV->value());
c->setDepthStart(ui->spinCameraDepthStart->value());
c->setDepthEnd(ui->spinCameraDepthEnd->value());
}
emit changed();
}
void ObjectEditor::on_spinLightAngleStart_valueChanged(double v) {
if (ui->spinLightAngleEnd->value() < v)
ui->spinLightAngleEnd->setValue(v);
}
void ObjectEditor::on_spinLightAngleEnd_valueChanged(double v) {
if (ui->spinLightAngleStart->value() > v)
ui->spinLightAngleStart->setValue(v);
}
void ObjectEditor::on_buttonDiscardRawMatrix_clicked() {
if (!active || !object) return;
object->setPosX(ui->spinPosX->value());
object->setPosY(ui->spinPosY->value());
object->setPosZ(ui->spinPosZ->value());
object->setRotationX(ui->spinRotationX->value());
object->setRotationY(ui->spinRotationY->value());
object->setRotationZ(ui->spinRotationZ->value());
object->setScaleX(ui->spinScaleX->value());
object->setScaleY(ui->spinScaleY->value());
object->setScaleZ(ui->spinScaleZ->value());
ui->buttonDiscardRawMatrix->setEnabled(false);
}

View File

@@ -0,0 +1,57 @@
/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OBJECT_EDITOR_H
#define OBJECT_EDITOR_H
#include <QWidget>
#include "globject.h"
namespace Ui {
class ObjectEditor;
}
class ObjectEditor: public QWidget
{
Q_OBJECT
public:
explicit ObjectEditor(QWidget * parent = 0);
void setObject(ObjectBase * o);
ObjectBase * getObject() {return object;}
protected:
void changeEvent(QEvent * e);
Ui::ObjectEditor * ui;
bool active;
ObjectBase * object;
QList<GLenum> rmodes;
private slots:
void objectChanged();
void on_spinLightAngleStart_valueChanged(double v);
void on_spinLightAngleEnd_valueChanged(double v);
void on_buttonDiscardRawMatrix_clicked();
signals:
void changed();
};
#endif // OBJECT_EDITOR_H

View File

@@ -0,0 +1,1294 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ObjectEditor</class>
<widget class="QWidget" name="ObjectEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>352</width>
<height>891</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="horizontalSpacing">
<number>2</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="QPushButton" name="buttonDiscardRawMatrix">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Discard raw transform</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Position X</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="spinPosX">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Position Y</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="spinPosY">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Position Z</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="spinPosZ">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Rotation X</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="SpinSlider" name="spinRotationX">
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="suffix">
<string>°</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Rotation Y</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="SpinSlider" name="spinRotationY">
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="suffix">
<string>°</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Rotation Z</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="SpinSlider" name="spinRotationZ">
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="suffix">
<string>°</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Scale X</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QDoubleSpinBox" name="spinScaleX">
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Scale Y</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QDoubleSpinBox" name="spinScaleY">
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Scale Z</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QDoubleSpinBox" name="spinScaleZ">
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Render mode</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QComboBox" name="comboRenderMode">
<item>
<property name="text">
<string>View</string>
</property>
</item>
<item>
<property name="text">
<string>Point</string>
</property>
</item>
<item>
<property name="text">
<string>Line</string>
</property>
</item>
<item>
<property name="text">
<string>Fill</string>
</property>
</item>
</widget>
</item>
<item row="11" column="1">
<widget class="QCheckBox" name="checkVisible">
<property name="text">
<string>Visible</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QCheckBox" name="checkAcceptLight">
<property name="text">
<string>Accept light</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QCheckBox" name="checkAcceptFog">
<property name="text">
<string>Accept fog</string>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QCheckBox" name="checkCastShadows">
<property name="text">
<string>Cast shadows</string>
</property>
</widget>
</item>
<item row="15" column="1">
<widget class="QCheckBox" name="checkReceiveShadows">
<property name="text">
<string>Receive shadows</string>
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Line width</string>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QDoubleSpinBox" name="spinLineWidth">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="18" column="0" colspan="2">
<widget class="QGroupBox" name="groupLight">
<property name="title">
<string>Light</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="horizontalSpacing">
<number>2</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboLightType">
<item>
<property name="text">
<string>Omni</string>
</property>
</item>
<item>
<property name="text">
<string>Directional</string>
</property>
</item>
<item>
<property name="text">
<string>Cone</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Intensity</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SpinSlider" name="spinLightIntensity">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>128.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Decay const</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SpinSlider" name="spinLightDecayConst">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>64.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Decay linear</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="SpinSlider" name="spinLightDecayLinear">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>64.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Decay quadratic</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="SpinSlider" name="spinLightDecayQuadratic">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>64.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Angle Start</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="SpinSlider" name="spinLightAngleStart">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>180.000000000000000</double>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
<property name="pageStep">
<double>30.000000000000000</double>
</property>
<property name="suffix">
<string>°</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Angle End</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="SpinSlider" name="spinLightAngleEnd">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>180.000000000000000</double>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
<property name="pageStep">
<double>30.000000000000000</double>
</property>
<property name="suffix">
<string>°</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Direcion X</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="SpinSlider" name="spinLightDirectionX">
<property name="minimum">
<double>-1.000000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Direcion Y</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="SpinSlider" name="spinLightDirectionY">
<property name="minimum">
<double>-1.000000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Direcion Z</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="SpinSlider" name="spinLightDirectionZ">
<property name="minimum">
<double>-1.000000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="19" column="0" colspan="2">
<widget class="QGroupBox" name="groupCamera">
<property name="title">
<string>Camera</string>
</property>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_46">
<property name="text">
<string>Depth</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QDoubleSpinBox" name="spinCameraDepthStart">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_47">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string> - </string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinCameraDepthEnd">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
<property name="value">
<double>1000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>FOV</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SpinSlider" name="spinCameraFOV">
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>179.000000000000000</double>
</property>
<property name="value">
<double>60.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
<property name="pageStep">
<double>30.000000000000000</double>
</property>
<property name="suffix">
<string>°</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="checkCameraMirrorY">
<property name="text">
<string>Mirror Y</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkCameraMirrorX">
<property name="text">
<string>Mirror X</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item row="17" column="1">
<widget class="ColorButton" name="buttonColor"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SpinSlider</class>
<extends>QWidget</extends>
<header>spinslider.h</header>
</customwidget>
<customwidget>
<class>ColorButton</class>
<extends>QPushButton</extends>
<header>colorbutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>spinPosX</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>43</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>5</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinPosY</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>75</y>
</hint>
<hint type="destinationlabel">
<x>320</x>
<y>36</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinPosZ</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>97</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>61</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinRotationX</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>172</x>
<y>121</y>
</hint>
<hint type="destinationlabel">
<x>82</x>
<y>73</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinRotationY</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>145</y>
</hint>
<hint type="destinationlabel">
<x>320</x>
<y>96</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinRotationZ</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>169</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>125</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinScaleX</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>191</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>150</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinScaleY</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>213</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>175</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinScaleZ</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>235</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>200</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkVisible</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>185</x>
<y>268</y>
</hint>
<hint type="destinationlabel">
<x>76</x>
<y>242</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkAcceptLight</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>179</x>
<y>295</y>
</hint>
<hint type="destinationlabel">
<x>61</x>
<y>261</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkAcceptFog</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>210</x>
<y>314</y>
</hint>
<hint type="destinationlabel">
<x>79</x>
<y>288</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkCastShadows</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>283</x>
<y>333</y>
</hint>
<hint type="destinationlabel">
<x>55</x>
<y>310</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkReceiveShadows</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>287</x>
<y>352</y>
</hint>
<hint type="destinationlabel">
<x>78</x>
<y>334</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLineWidth</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>303</x>
<y>366</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>359</y>
</hint>
</hints>
</connection>
<connection>
<sender>comboRenderMode</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>257</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>228</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonColor</sender>
<signal>colorChanged(QColor)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>422</y>
</hint>
<hint type="destinationlabel">
<x>320</x>
<y>393</y>
</hint>
</hints>
</connection>
<connection>
<sender>comboLightType</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>442</y>
</hint>
<hint type="destinationlabel">
<x>320</x>
<y>429</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightIntensity</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>464</y>
</hint>
<hint type="destinationlabel">
<x>318</x>
<y>463</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightDecayConst</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>486</y>
</hint>
<hint type="destinationlabel">
<x>320</x>
<y>489</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightDecayLinear</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>508</y>
</hint>
<hint type="destinationlabel">
<x>318</x>
<y>517</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightDecayQuadratic</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>530</y>
</hint>
<hint type="destinationlabel">
<x>325</x>
<y>543</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightAngleStart</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>552</y>
</hint>
<hint type="destinationlabel">
<x>321</x>
<y>569</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightAngleEnd</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>574</y>
</hint>
<hint type="destinationlabel">
<x>320</x>
<y>595</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightDirectionX</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>596</y>
</hint>
<hint type="destinationlabel">
<x>332</x>
<y>607</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightDirectionY</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>618</y>
</hint>
<hint type="destinationlabel">
<x>330</x>
<y>633</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLightDirectionZ</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>640</y>
</hint>
<hint type="destinationlabel">
<x>326</x>
<y>659</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinCameraDepthStart</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>85</x>
<y>691</y>
</hint>
<hint type="destinationlabel">
<x>171</x>
<y>652</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinCameraDepthEnd</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>259</x>
<y>693</y>
</hint>
<hint type="destinationlabel">
<x>277</x>
<y>652</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinCameraFOV</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>145</x>
<y>719</y>
</hint>
<hint type="destinationlabel">
<x>324</x>
<y>696</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkCameraMirrorX</sender>
<signal>clicked(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>129</x>
<y>753</y>
</hint>
<hint type="destinationlabel">
<x>323</x>
<y>758</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkCameraMirrorY</sender>
<signal>clicked(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>objectChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>194</x>
<y>782</y>
</hint>
<hint type="destinationlabel">
<x>328</x>
<y>785</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>objectChanged()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,408 @@
#include "propertyeditor.h"
QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & index) const {
QWidget * w = 0;
int type = 0;
QVariant value = index.data(Qt::UserRole);
if (index.data(Qt::UserRole + 2).toString() == "__flags") return 0;
if (index.data(Qt::UserRole + 1).toString() == "__flag") {
qulonglong key = index.data(Qt::UserRole).toULongLong();
value = index.parent().data(Qt::UserRole);
//QMetaProperty prop = index.parent().data(Qt::UserRole + 1).value<QMetaProperty>();
w = new QCheckBox(parent); type = 14; ((QCheckBox*)w)->setChecked(((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0));
((QCheckBox*)w)->setText("0x" + QString::number(key, 16).toUpper());
connect((QCheckBox*)w, SIGNAL(clicked(bool)), this, SLOT(changedFlag()));
//qDebug() << prop.enumerator().name();
} else {
if (value.canConvert<PropertyValuePair>()) {
PropertyValuePair prop = value.value<PropertyValuePair>();
if (prop.first.isEnumType()) {
w = new QComboBox(parent); type = 13; ((QComboBox*)w)->setCurrentIndex(value.toInt());
w->setProperty("__prop", QVariant::fromValue<QMetaProperty>(prop.first));
QMetaEnum menum = prop.first.enumerator();
for (int i = 0; i < menum.keyCount(); ++i) {
((QComboBox*)w)->addItem(QString(menum.key(i)) + " (0x" + QString::number(menum.value(i), 16).toUpper() + ")", menum.value(i));
if (menum.value(i) == prop.second.toInt())
((QComboBox*)w)->setCurrentIndex(i);
}
connect((QComboBox*)w, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
}
} else {
switch (value.type()) {
case QVariant::Int: w = new QSpinBox(parent); type = 2; ((QSpinBox*)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break;
case QVariant::UInt: w = new QSpinBox(parent); type = 3; ((QSpinBox*)w)->setRange(0, 0xFFFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break;
case QVariant::LongLong: w = new QSpinBox(parent); type = 4; ((QSpinBox*)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break;
case QVariant::ULongLong: w = new QSpinBox(parent); type = 5; ((QSpinBox*)w)->setRange(0, 0xFFFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break;
case QVariant::Double: w = new QDoubleSpinBox(parent); type = 6; ((QDoubleSpinBox*)w)->setRange(-999999999, 999999999); ((QDoubleSpinBox*)w)->setDecimals(3); connect((QDoubleSpinBox*)w, SIGNAL(valueChanged(double)), this, SLOT(changed())); break;
case QVariant::Bool: w = new QCheckBox(parent); type = 7; ((QCheckBox*)w)->setChecked(value.toBool()); connect((QCheckBox*)w, SIGNAL(toggled(bool)), this, SLOT(changed())); break;
case QVariant::Color: w = new ColorButton(parent); type = 8; ((ColorButton*)w)->setUseAlphaChannel(true); ((ColorButton*)w)->setColor(value.value<QColor>()); connect((ColorButton*)w, SIGNAL(colorChanged(QColor)), this, SLOT(changed())); break;
case QVariant::Point: w = new QPointEdit(parent); type = 9; ((QPointEdit*)w)->setDecimals(0); ((QPointEdit*)w)->setValue(QPointF(value.toPoint())); connect((QPointEdit*)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed())); break;
case QVariant::PointF: w = new QPointEdit(parent); type = 10; ((QPointEdit*)w)->setDecimals(3); ((QPointEdit*)w)->setValue(value.toPointF()); connect((QPointEdit*)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed())); break;
case QVariant::Rect: w = new QRectEdit(parent); type = 11; ((QRectEdit*)w)->setDecimals(0); ((QRectEdit*)w)->setValue(QRectF(value.toRect())); connect((QRectEdit*)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed())); break;
case QVariant::RectF: w = new QRectEdit(parent); type = 12; ((QRectEdit*)w)->setDecimals(3); ((QRectEdit*)w)->setValue(value.toRectF()); connect((QRectEdit*)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed())); break;
case QVariant::String: default: w = new CLineEdit(parent); type = 1; ((CLineEdit*)w)->setDefaultText(value.toString()); connect((CLineEdit*)w, SIGNAL(textChanged(QString)), this, SLOT(changed())); break;
}
}
}
if (w == 0) return 0;
/*QPalette pal = w->palette();
pal.setColor(QPalette::Window, Qt::white);
w->setPalette(pal);*/
w->setAutoFillBackground(true);
w->setProperty("__type", type);
return w;
}
void Delegate::setWidgetProperty(QWidget * w, const QVariant & value) const {
if (w == 0) return;
switch (w->property("__type").toInt()) {
case 1: ((CLineEdit*)w)->setText(value.toString()); break;
case 2: case 3: case 4: case 5: ((QSpinBox*)w)->setValue(value.toInt()); break;
case 6: ((QDoubleSpinBox*)w)->setValue(value.toDouble()); break;
case 7: ((QCheckBox*)w)->setChecked(value.toBool()); break;
case 8: ((ColorButton*)w)->setColor(value.value<QColor>()); break;
case 9: ((QPointEdit*)w)->setValue(value.value<QPoint>()); break;
case 10: ((QPointEdit*)w)->setValue(value.value<QPointF>()); break;
case 11: ((QRectEdit*)w)->setValue(value.value<QRect>()); break;
case 12: ((QRectEdit*)w)->setValue(value.value<QRectF>()); break;
}
}
const QVariant Delegate::widgetProperty(QWidget * w) const {
if (w == 0) return QVariant();
switch (w->property("__type").toInt()) {
case 1: return QVariant::fromValue<QString>(((CLineEdit*)w)->text()); break;
case 2: return QVariant::fromValue<int>(((QSpinBox*)w)->value()); break;
case 3: return QVariant::fromValue<uint>(((QSpinBox*)w)->value()); break;
case 4: return QVariant::fromValue<qlonglong>(((QSpinBox*)w)->value()); break;
case 5: return QVariant::fromValue<qulonglong>(((QSpinBox*)w)->value()); break;
case 6: return QVariant::fromValue<double>(((QDoubleSpinBox*)w)->value()); break;
case 7: return QVariant::fromValue<bool>(((QCheckBox*)w)->isChecked()); break;
case 8: return QVariant::fromValue<QColor>(((ColorButton*)w)->color()); break;
case 9: return QVariant::fromValue<QPoint>(((QPointEdit*)w)->value().toPoint()); break;
case 10: return QVariant::fromValue<QPointF>(((QPointEdit*)w)->value()); break;
case 11: return QVariant::fromValue<QRect>(((QRectEdit*)w)->value().toRect()); break;
case 12: return QVariant::fromValue<QRectF>(((QRectEdit*)w)->value()); break;
case 13: return QVariant::fromValue<PropertyValuePair>(PropertyValuePair(w->property("__prop").value<QMetaProperty>(), ((QComboBox*)w)->itemData(((QComboBox*)w)->currentIndex()))); break;
default: return QVariant(); break;
}
return QVariant();
}
void Delegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
if (index.data(Qt::UserRole + 1).toString() != "__flag")
model->setData(index, widgetProperty(editor), Qt::UserRole);
}
void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
QStyledItemDelegate::paint(painter, option, index);
QVariant value = index.data(Qt::UserRole);
QStyle * style = QApplication::style();
QStyleOption * so = 0;
QStyleOptionComplex * soc = 0;
QString text;
QRect rect;
QPalette::ColorRole role = (option.state.testFlag(QStyle::State_Selected) && option.state.testFlag(QStyle::State_Active) ? QPalette::HighlightedText : QPalette::WindowText);
if (index.data(Qt::UserRole + 2).toString() == "__flags") {
text = "0x" + QString::number(value.toInt(), 16).toUpper();
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
return;
}
if (index.data(Qt::UserRole + 1) == "__flag") {
qulonglong key = index.data(Qt::UserRole).toULongLong();
value = index.parent().data(Qt::UserRole);
so = new QStyleOptionButton();
so->rect = option.rect;
so->palette = option.palette;
so->fontMetrics = option.fontMetrics;
((QStyleOptionButton*)so)->state = (((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0) ? QStyle::State_On : QStyle::State_Off) | option.state;
((QStyleOptionButton*)so)->text = "0x" + QString::number(key, 16).toUpper();
if (option.state.testFlag(QStyle::State_Selected))
so->palette.setColor(QPalette::WindowText, so->palette.color(QPalette::HighlightedText));
style->drawControl(QStyle::CE_CheckBox, so, painter);
} else {
if (value.canConvert<PropertyValuePair>()) {
PropertyValuePair prop = value.value<PropertyValuePair>();
if (prop.first.isEnumType()) {
QMetaEnum menum = prop.first.enumerator();
for (int i = 0; i < menum.keyCount(); ++i) {
if (menum.value(i) == prop.second.toInt()) {
text = QString(menum.key(i)) + " (0x" + QString::number(menum.value(i), 16).toUpper() + ")";
break;
}
}
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
}
} else {
switch (value.type()) {
case QVariant::Int:
text.setNum(value.toInt());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::UInt:
text.setNum(value.toUInt());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::LongLong:
text.setNum(value.toLongLong());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::ULongLong:
text.setNum(value.toULongLong());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::Double:
text.setNum(value.toDouble(), 'f', 3);
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::Bool:
so = new QStyleOptionButton();
so->rect = option.rect;
so->state = option.state;
so->palette = option.palette;
so->fontMetrics = option.fontMetrics;
((QStyleOptionButton*)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off) | option.state;
style->drawControl(QStyle::CE_CheckBox, so, painter);
break;
case QVariant::Color:
rect = option.rect;//style->subElementRect(QStyle::QStyle::SE_FrameContents, so);
rect.setRect(rect.x() + 3, rect.y() + 3, rect.width() - 6, rect.height() - 6);
painter->fillRect(rect, ab);
painter->fillRect(rect, value.value<QColor>());
break;
case QVariant::Point:
text = pointString(value.toPoint());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::PointF:
text = pointString(value.toPointF());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::Rect:
text = rectString(value.toRect());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::RectF:
text = rectString(value.toRectF());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
break;
case QVariant::String: default:
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, value.toString()),
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, value.toString(), role);
break;
}
}
}
/*so = new QStyleOptionFrame();
so->rect = option.rect;
so->state = option.state;
so->palette = option.palette;
so->fontMetrics = option.fontMetrics;
((QStyleOptionFrame*)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off);
style->drawPrimitive(QStyle::PE_PanelLineEdit, so, painter);
style->drawPrimitive(QStyle::PE_FrameLineEdit, so, painter);
break;*/
if (so != 0) delete so;
if (soc != 0) delete soc;
}
void Delegate::changedFlag() {
QAbstractItemModel * model = const_cast<QAbstractItemModel * >(cmi.model());
model->setData(cmi, qobject_cast<QCheckBox * >(sender())->isChecked(), Qt::UserRole + 3);
QModelIndex p = cmi.parent(), mi;
int row = 0;
qulonglong val = 0;
QList<QModelIndex> chldr;
mi = p.child(row, 1);
while (mi.isValid()) {
chldr << mi;
model->setData(mi, !mi.data(Qt::UserRole + 4).toBool(), Qt::UserRole + 4);
mi = p.child(++row, 1);
}
bool cc = cmi.data(Qt::UserRole + 3).toBool();
qulonglong cv = cmi.data(Qt::UserRole).toULongLong();
//qDebug() << "*****";
if (cc && cv == 0) {
val = 0;
//qDebug() << "null" << cv;
} else {
if (!cc && cv != 0) {
//qDebug() << "uncheck" << cv;
for (int i = 0; i < chldr.size(); ++i) {
if (chldr[i] == cmi) continue;
//qDebug() << (chldr[i].data(Qt::UserRole).toULongLong() & cv);
if (chldr[i].data(Qt::UserRole).toULongLong() & cv)
model->setData(chldr[i], false, Qt::UserRole + 3);
}
}
for (int i = 0; i < chldr.size(); ++i) {
//qDebug() << chldr[i].data(Qt::UserRole + 3).toBool();
if (chldr[i].data(Qt::UserRole + 3).toBool())
val |= chldr[i].data(Qt::UserRole).toULongLong();
}
}
for (int i = 0; i < chldr.size(); ++i) {
if (chldr[i] == cmi) continue;
cv = chldr[i].data(Qt::UserRole).toULongLong();
model->setData(chldr[i], ((val & cv) == cv && cv != 0) || (val == 0 && cv == 0), Qt::UserRole + 3);
}
//qDebug() << val;
model->setData(p, val, Qt::UserRole);
model->setData(p.sibling(p.row(), 1), val, Qt::UserRole);
}
PropertyEditor::PropertyEditor(QWidget * parent): QTreeWidget(parent) {
object = 0;
active_ = false;
configTree();
connect(this, SIGNAL(itemClicked(QTreeWidgetItem * , int)), this, SLOT(itemClicked(QTreeWidgetItem * , int)));
connect(this, SIGNAL(itemChanged(QTreeWidgetItem * , int)), this, SLOT(itemChanged(QTreeWidgetItem * , int)));
}
PropertyEditor::~PropertyEditor() {
}
void PropertyEditor::changeEvent(QEvent * e) {
QTreeWidget::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
configTree();
return;
}
}
void PropertyEditor::configTree() {
setColumnCount(2);
setRootIsDecorated(false);
setColumnWidth(0, 170);
setColumnWidth(1, 10);
header()->setStretchLastSection(true);
QStringList lbls;
lbls << tr("Property") << tr("Value");
setHeaderLabels(lbls);
setAlternatingRowColors(true);
setItemDelegateForColumn(1, new Delegate());
}
void PropertyEditor::itemClicked(QTreeWidgetItem * item, int column) {
if (column == 0)
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
else {
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
editItem(item, 1);
}
}
void PropertyEditor::itemChanged(QTreeWidgetItem * item, int column) {
if (!active_) return;
if (column != 1) return;
QVariant value = item->data(1, Qt::UserRole);
if (value.canConvert<PropertyValuePair>()) {
value = value.value<PropertyValuePair>().second;
}
object->setProperty(item->text(0).toLatin1(), value);
}
void PropertyEditor::rebuild() {
clear();
configTree();
if (object == 0) return;
active_ = false;
const QMetaObject * mo = object->metaObject();
QList<const QMetaObject * > mol;
while (mo != 0) {
mol.push_front(mo);
mo = mo->superClass();
}
int ps, pe;
QTreeWidgetItem * ti, * tli, * tfi;
QVariant value;
// QWidget * pw = 0;
int chue = 0;
QColor bc;
font_b = font();
font_b.setBold(true);
foreach (const QMetaObject * o, mol) {
ps = o->propertyOffset();
pe = o->propertyCount();// - ps;
//qDebug() << i->className() << ps << pe;
tli = new QTreeWidgetItem();
tli->setText(0, o->className());
tli->setFont(0, font_b);
setItemBackColor(tli, Qt::darkGray);
setItemForeColor(tli, Qt::white);
addTopLevelItem(tli);
setFirstItemColumnSpanned(tli, true);
tli->setExpanded(true);
for (int i = ps; i < pe; ++i) {
props << o->property(i);
value = o->property(i).read(object);
ti = new QTreeWidgetItem();
ti->setSizeHint(1, QSize(20, 20));
bc.setHsv(chue, 60, 245 + (i % 2) * 20 - 10);
setItemBackColor(ti, bc);
ti->setText(0, o->property(i).name());
if (props.back().isFlagType()) {
QMetaEnum menum = props.back().enumerator();
for (int j = 0; j < menum.keyCount(); ++j) {
tfi = new QTreeWidgetItem();
tfi->setText(0, menum.key(j));
tfi->setData(1, Qt::UserRole, menum.value(j));
tfi->setData(1, Qt::UserRole + 1, "__flag");
tfi->setData(1, Qt::UserRole + 2, value.toULongLong());
tfi->setData(1, Qt::UserRole + 3, (value.toULongLong() & menum.value(j)) > 0);
tfi->setSizeHint(1, QSize(20, 20));
bc.setHsv(chue, 60, 245 + ((i + j + 1) % 2) * 20 - 10);
setItemBackColor(tfi, bc);
ti->addChild(tfi);
}
ti->setData(0, Qt::UserRole, value);
ti->setData(1, Qt::UserRole, value);
ti->setData(1, Qt::UserRole + 2, "__flags");
ti->setData(0, Qt::UserRole + 1, QVariant::fromValue<QMetaProperty>(props.back()));
}
else if (props.back().isEnumType())
value.setValue<PropertyValuePair>(PropertyValuePair(props.back(), value));
//ti->setText(1, value.toString());
ti->setData(1, Qt::UserRole, value);
tli->addChild(ti);
//const_cast<QModelIndex & >(indexFromItem(ti, 1)).;
//if (pw != 0) setItemWidget(ti, 1, pw);
}
chue += 60;
chue %= 360;
}
active_ = true;
}
void PropertyEditor::refresh() {
}

View File

@@ -0,0 +1,77 @@
#ifndef PROPERTYEDITOR_H
#define PROPERTYEDITOR_H
#include <QTreeWidget>
#include <QHeaderView>
#include <QMetaProperty>
#include <QEvent>
#include <QDebug>
#include <QStyledItemDelegate>
#include <qpiconfigwidget.h>
class Delegate: public QStyledItemDelegate {
Q_OBJECT
public:
Delegate(QObject * parent = 0): QStyledItemDelegate() {ab = QBrush(QImage(":/icons/alpha.png"));}
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {cmi = const_cast<QModelIndex & >(index); return widgetForProperty(parent, index);}
void setEditorData(QWidget * editor, const QModelIndex & index) const {setWidgetProperty(editor, index.data(Qt::UserRole));}
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const {editor->setGeometry(option.rect);}
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
private:
QWidget * widgetForProperty(QWidget * parent, const QModelIndex & index) const;
void setWidgetProperty(QWidget * w, const QVariant & value) const;
const QVariant widgetProperty(QWidget * w) const;
QString pointString(const QPoint & p) const {return QString::number(p.x()) + " x " + QString::number(p.y());}
QString pointString(const QPointF & p) const {return QString::number(p.x()) + " x " + QString::number(p.y());}
QString rectString(const QRect & r) const {return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " +
QString::number(r.width()) + " x " + QString::number(r.height());}
QString rectString(const QRectF & r) const {return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " +
QString::number(r.width()) + " x " + QString::number(r.height());}
QBrush ab;
mutable QModelIndex cmi;
private slots:
void changed() {setModelData((QWidget * )sender(), const_cast<QAbstractItemModel * >(cmi.model()), cmi);}
void changedFlag();
};
typedef QPair<QMetaProperty, QVariant> PropertyValuePair;
Q_DECLARE_METATYPE (PropertyValuePair)
Q_DECLARE_METATYPE (QMetaProperty)
class PropertyEditor: public QTreeWidget {
Q_OBJECT
public:
explicit PropertyEditor(QWidget * parent = 0);
virtual ~PropertyEditor();
void assignObject(QObject * o) {object = o; rebuild();}
protected:
void changeEvent(QEvent * e);
private:
void configTree();
void setItemBackColor(QTreeWidgetItem * i, const QColor & c) {i->setBackgroundColor(0, c); i->setBackgroundColor(1, c);}
void setItemForeColor(QTreeWidgetItem * i, const QColor & c) {i->setForeground(0, c); i->setForeground(1, c);}
void rebuild();
void refresh();
QObject * object;
QFont font_b;
QList<QMetaProperty> props;
bool active_;
private slots:
void itemClicked(QTreeWidgetItem * item, int column);
void itemChanged(QTreeWidgetItem * item, int column);
};
#endif // PROPERTYEDITOR_H

View File

@@ -0,0 +1,405 @@
/*
Stanley Designer
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "scene_tree.h"
#include "ui_scene_tree.h"
#include "glcamera.h"
#include "qglview.h"
#include <QTreeWidget>
#include <QScrollBar>
#include <QAction>
#include <QEvent>
enum Column {
cName,
cVis,
cMaterial
};
enum ItemRole {
irObject = Qt::UserRole,
irType = Qt::UserRole + 1,
};
enum ObjectType {
otNode = 1,
otMesh = 2,
otLight = 4,
otCamera = 8,
};
SceneTree::SceneTree(QWidget * parent): QWidget(parent) {
ui = new Ui::SceneTree();
ui->setupUi(this);
ui->treeObjects->header()->setSectionResizeMode(cVis, QHeaderView::ResizeToContents);
ui->treeObjects->header()->setSectionsMovable(false);
ui->treeObjects->header()->swapSections(cName, cVis);
icon_empty = QIcon(":/icons/type-empty.png");
icon_geo = QIcon(":/icons/type-geo.png");
icon_camera = QIcon(":/icons/type-camera.png");
icon_light = QIcon(":/icons/type-light.png");
icon_vis[0] = QIcon(":/icons/layer-visible-off.png");
icon_vis[1] = QIcon(":/icons/layer-visible-on.png");
QAction * a = 0;
a = new QAction(QIcon(":/icons/type-camera.png"), "Focus");
connect(a, SIGNAL(triggered()), this, SLOT(focusObjects()));
ui->treeObjects->addAction(a);
a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove");
connect(a, SIGNAL(triggered()), this, SLOT(removeObjects()));
ui->treeObjects->addAction(a);
view = 0;
block_tree = false;
connect(ui->treeObjects->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(treeObjects_selectionCnahged()));
}
SceneTree::~SceneTree() {
delete ui;
}
void SceneTree::assignQGLView(QGLView * v) {
view = v;
connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
connect(view, SIGNAL(materialsChanged()), this, SLOT(materialsChanged()));
connect(view->scene(), SIGNAL(treeChanged()), this, SLOT(objectsTreeChanged()));
connect(view->scene(), SIGNAL(__objectDeleted(ObjectBase*)), this, SLOT(__objectDeleted(ObjectBase*)));
objectsTreeChanged();
}
void SceneTree::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
return;
}
}
void SceneTree::rememberExpanded(QTreeWidgetItem * ti) {
for (int i = 0; i < ti->childCount(); ++i) {
QTreeWidgetItem * ci = ti->child(i);
if (ci->isExpanded())
expanded_ << itemObject(ci);
rememberExpanded(ci);
}
}
void SceneTree::restoreExpanded(QTreeWidgetItem * ti) {
for (int i = 0; i < ti->childCount(); ++i) {
QTreeWidgetItem * ci = ti->child(i);
ci->setExpanded(expanded_.contains(itemObject(ci)));
restoreExpanded(ci);
}
}
void SceneTree::makeObjetTree(ObjectBase * o, QTreeWidgetItem * ti) {
for (int i = 0; i < o->childCount(); ++i) {
ObjectBase * co = o->child(i);
QTreeWidgetItem * ci = new QTreeWidgetItem(ti);
ci->setText(cName, co->name());
ci->setCheckState(cVis, co->isVisible() ? Qt::Checked : Qt::Unchecked);
ci->setIcon(cVis, icon_vis[co->isVisible(true)]);
if (co->material())
ci->setText(cMaterial, co->material()->name);
ci->setFlags(ci->flags() | Qt::ItemIsEditable);
ObjectType t = otNode;
switch (co->type()) {
case ObjectBase::glMesh:
if (co->mesh()) {
t = otMesh;
ci->setIcon(cName, icon_geo);
geo_items << ci;
} else {
ci->setIcon(cName, icon_empty);
}
break;
case ObjectBase::glLight:
t = otLight;
ci->setIcon(cName, icon_light);
break;
case ObjectBase::glCamera:
t = otCamera;
ci->setIcon(cName, icon_camera);
break;
default: break;
}
ci->setData(cName, irObject, quintptr(co));
ci->setData(cName, irType, int(t));
ci->setSelected(co->isSelected());
makeObjetTree(co, ci);
}
}
ObjectBase * SceneTree::itemObject(QTreeWidgetItem * item) const {
if (!item) return 0;
return (ObjectBase*)(item->data(cName, irObject).toULongLong());
}
int SceneTree::itemType(QTreeWidgetItem * item) const {
if (!item) return otNode;
return item->data(cName, irType).toInt();
}
void SceneTree::selectionChanged() {
if (block_tree) return;
block_tree = true;
QList<QTreeWidgetItem*> il = ui->treeObjects->findItems("", Qt::MatchContains | Qt::MatchRecursive);
const ObjectBase * fo = 0;
if (view->selectedObjects().size() == 1)
fo = view->selectedObject();
foreach (QTreeWidgetItem * i, il) {
ObjectBase * o = itemObject(i);
i->setSelected(o->isSelected());
if (fo && (fo == o)) {
ui->treeObjects->setCurrentItem(i);
}
}
block_tree = false;
checkButtons();
}
void SceneTree::materialsChanged() {
foreach (QTreeWidgetItem * i, geo_items) {
ObjectBase * o = itemObject(i);
if (!o) continue;
if (o->material())
i->setText(cMaterial, o->material()->name);
}
}
bool SceneTree::filterTree(QTreeWidgetItem * ti, const QString & filter, int types) {
bool ret = false;
for (int i = 0; i < ti->childCount(); ++i) {
QTreeWidgetItem * ci = ti->child(i);
QString cit = ci->text(cName);
int t = itemType(ci);
if (ci->childCount() > 0) {
if (!filterTree(ci, filter, types)) {
ci->setHidden(true);
continue;
}
ci->setHidden(false);
ret = true;
} else {
bool f = false;
if (filter.isEmpty()) {
f = true;
} else {
f = f || cit.contains(filter);
}
if ((types & t) != t)
f = false;
ci->setHidden(!f);
if (f) ret = true;
}
}
return ret;
}
void SceneTree::checkButtons() {
bool has_1 = false, has_m = false;
if (view) {
has_1 = !view->selectedObjects().isEmpty();
has_m = view->selectedObjects().size() > 1;
}
ui->buttonFocus ->setEnabled(has_1);
ui->buttonRemove->setEnabled(has_1);
ui->buttonClone ->setEnabled(has_1);
ui->buttonSelectParent->setEnabled(has_1);
ui->buttonGroup->setEnabled(has_m);
}
void SceneTree::treeObjects_selectionCnahged() {
if (block_tree || !view) return;
block_tree = true;
view->scene()->clearSelection();
QList<ObjectBase*> sol;
QList<QTreeWidgetItem*> til = ui->treeObjects->selectedItems();
foreach (QTreeWidgetItem * i, til)
sol << itemObject(i);
view->scene()->selectObjects(sol);
block_tree = false;
checkButtons();
}
void SceneTree::filter() {
int types = 0;
if (ui->buttonFilterNode ->isChecked()) types |= otNode ;
if (ui->buttonFilterMesh ->isChecked()) types |= otMesh ;
if (ui->buttonFilterLight ->isChecked()) types |= otLight ;
if (ui->buttonFilterCamera->isChecked()) types |= otCamera;
if (types == 0) types = 0xFF;
filterTree(ui->treeObjects->invisibleRootItem(), ui->lineFilter->text(), types);
ui->treeObjects->invisibleRootItem()->setHidden(false);
}
void SceneTree::__objectDeleted(ObjectBase * o) {
for (int i = 0; i < geo_items.size(); ++i)
if (itemObject(geo_items[i]) == o) {
geo_items.removeAt(i);
--i;
}
}
void SceneTree::on_treeObjects_itemChanged(QTreeWidgetItem * item, int column) {
if (block_tree) return;
if (column == cName) {
ObjectBase * o = itemObject(item);
if (o) o->setName(item->text(cName));
}
if (column == cVis) {
bool vis = item->checkState(cVis) == Qt::Checked;
QList<QTreeWidgetItem*> til = ui->treeObjects->selectedItems();
if (!til.contains(item)) {
til.clear();
til << item;
}
foreach (QTreeWidgetItem * ti, til) {
//itemObject(ti)->setVisible(vis);
itemObject(ti)->setVisible(vis);
}
}
}
void SceneTree::on_treeObjects_itemMoved(QTreeWidgetItem * item, QTreeWidgetItem * new_parent) {
ObjectBase * co = itemObject(item);
if (!co->hasParent()) return;
//co->parent()->removeChild(co);
if (new_parent == ui->treeObjects->invisibleRootItem()) {
view->scene()->rootObject()->addChild(co);
} else {
ObjectBase * po = itemObject(new_parent);
if (po)
po->addChild(co);
}
}
void SceneTree::on_buttonAddNode_clicked() {
if (!view) return;
ObjectBase * no = new ObjectBase();
view->scene()->addObject(no);
view->scene()->selectObject(no);
}
void SceneTree::on_buttonAddLight_clicked() {
if (!view) return;
ObjectBase * no = new Light();
view->scene()->addObject(no);
view->scene()->selectObject(no);
}
void SceneTree::on_buttonClone_clicked() {
if (!view) return;
QList<QTreeWidgetItem*> sil = ui->treeObjects->selectedItems();
QList<ObjectBase*> col;
foreach (QTreeWidgetItem * i, sil) {
ObjectBase * o = itemObject(i);
if (!o) continue;
ObjectBase * no = o->clone();
o->parent()->addChild(no);
col << no;
}
view->scene()->selectObjects(col);
}
void SceneTree::on_buttonSelectParent_clicked() {
if (!view) return;
QList<ObjectBase*> sol = view->scene()->selectedObjects(true);
QSet<ObjectBase*> nsl;
foreach (ObjectBase * o, sol) {
ObjectBase * po = o->parent();
if (po != view->scene()->rootObject())
o = po;
nsl << o;
}
view->scene()->selectObjects(nsl.toList());
}
void SceneTree::on_buttonGroup_clicked() {
if (!view) return;
QList<ObjectBase*> sol = view->scene()->selectedObjects(true);
ObjectBase * cp = sol[0]->parent();
ObjectBase * nr = new ObjectBase();
cp->addChild(nr);
foreach (ObjectBase * o, sol)
nr->addChild(o);
view->scene()->selectObject(nr);
}
void SceneTree::removeObjects() {
if (!view) return;
QList<QTreeWidgetItem*> sil = ui->treeObjects->selectedItems();
foreach (QTreeWidgetItem * i, sil) {
ObjectBase * o = itemObject(i);
if (o) delete o;
}
qDeleteAll(sil);
}
void SceneTree::focusObjects() {
if (!view) return;
if (!view->camera()) return;
Box3D bb;
QList<ObjectBase*> ol = view->selectedObjects();
foreach (ObjectBase * o, ol) {
o->calculateBoundingBox();
bb |= o->boundingBox();
}
view->focusOn(bb);
}
void SceneTree::objectsTreeChanged() {
int vpos = ui->treeObjects->verticalScrollBar()->value();
expanded_.clear();
geo_items.clear();
rememberExpanded(ui->treeObjects->invisibleRootItem());
block_tree = true;
ui->treeObjects->clear();
block_tree = false;
if (!view) return;
block_tree = true;
makeObjetTree(view->scene()->rootObject(), ui->treeObjects->invisibleRootItem());
restoreExpanded(ui->treeObjects->invisibleRootItem());
block_tree = false;
filter();
QApplication::processEvents();
ui->treeObjects->verticalScrollBar()->setValue(vpos);
}

View File

@@ -0,0 +1,85 @@
/*
Stanley Designer
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SCENE_TREE_H
#define SCENE_TREE_H
#include <QWidget>
#include <QIcon>
#include "glscene.h"
class QTreeWidgetItem;
namespace Ui {
class SceneTree;
}
class SceneTree: public QWidget
{
Q_OBJECT
public:
SceneTree(QWidget * parent = 0);
~SceneTree();
void assignQGLView(QGLView * v);
private:
void changeEvent(QEvent * e);
void rememberExpanded(QTreeWidgetItem * ti);
void restoreExpanded(QTreeWidgetItem * ti);
void makeObjetTree(ObjectBase * o, QTreeWidgetItem * ti);
ObjectBase * itemObject(QTreeWidgetItem * item) const;
int itemType(QTreeWidgetItem * item) const;
bool filterTree(QTreeWidgetItem * ti, const QString & filter, int types);
void checkButtons();
Ui::SceneTree * ui;
bool block_tree;
QIcon icon_empty, icon_geo, icon_camera, icon_light, icon_vis[2];
QSet<ObjectBase*> expanded_;
QList<QTreeWidgetItem*> geo_items;
QGLView * view;
private slots:
void treeObjects_selectionCnahged();
void on_treeObjects_itemChanged(QTreeWidgetItem * item, int column);
void on_treeObjects_itemMoved (QTreeWidgetItem * item, QTreeWidgetItem * new_parent);
void on_buttonAddNode_clicked();
void on_buttonAddLight_clicked();
void on_buttonClone_clicked();
void on_buttonUpdate_clicked() {objectsTreeChanged();}
void on_buttonSelectParent_clicked();
void on_buttonGroup_clicked();
void removeObjects();
void focusObjects();
void objectsTreeChanged();
void selectionChanged();
void materialsChanged();
void filter();
void __objectDeleted(ObjectBase * o);
public slots:
signals:
private:
};
#endif // SCENE_TREE_H

View File

@@ -0,0 +1,550 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SceneTree</class>
<widget class="QWidget" name="SceneTree">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>345</width>
<height>494</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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_7">
<item>
<widget class="QGroupBox" name="groupSelection">
<property name="title">
<string>Selection</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QToolButton" name="buttonFocus">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Focus on selected</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/type-camera.png</normaloff>:/icons/type-camera.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="buttonRemove">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Delete selected</string>
</property>
<property name="icon">
<iconset resource="widgets.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="buttonClone">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Clone selected</string>
</property>
<property name="icon">
<iconset resource="widgets.qrc">
<normaloff>:/icons/edit-copy.png</normaloff>:/icons/edit-copy.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonGroup">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Group selected</string>
</property>
<property name="text">
<string>G</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonSelectParent">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Select parent</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/go-top.png</normaloff>:/icons/go-top.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupAdd">
<property name="title">
<string>Add</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QToolButton" name="buttonAddNode">
<property name="toolTip">
<string>Add empty object</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/add-type-empty.png</normaloff>:/icons/add-type-empty.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonAddLight">
<property name="toolTip">
<string>Add light</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/add-type-light.png</normaloff>:/icons/add-type-light.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonAddCamera">
<property name="toolTip">
<string>Add camera</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/add-type-camera.png</normaloff>:/icons/add-type-camera.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QGroupBox" name="groupFilter">
<property name="title">
<string>Filter</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="CLineEdit" name="lineFilter"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Types:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widgetFilter" 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>
<widget class="QToolButton" name="buttonFilterNode">
<property name="toolTip">
<string>Nodes</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/type-empty.png</normaloff>:/icons/type-empty.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonFilterMesh">
<property name="toolTip">
<string>Meshes</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/type-geo.png</normaloff>:/icons/type-geo.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonFilterLight">
<property name="toolTip">
<string>Lights</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/type-light.png</normaloff>:/icons/type-light.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonFilterCamera">
<property name="toolTip">
<string>Cameras</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/type-camera.png</normaloff>:/icons/type-camera.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupTree">
<property name="title">
<string>Tree</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QToolButton" name="buttonExpand">
<property name="toolTip">
<string>Expand tree</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/expand.png</normaloff>:/icons/expand.png</iconset>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="buttonUpdate">
<property name="toolTip">
<string>Force update</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/view-refresh.png</normaloff>:/icons/view-refresh.png</iconset>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="buttonCollapse">
<property name="toolTip">
<string>Collapse tree</string>
</property>
<property name="icon">
<iconset resource="../qglview.qrc">
<normaloff>:/icons/collapse.png</normaloff>:/icons/collapse.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="InternalMoveTreeWidget" name="treeObjects">
<property name="contextMenuPolicy">
<enum>Qt::ActionsContextMenu</enum>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Vis</string>
</property>
</column>
<column>
<property name="text">
<string>Material</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CLineEdit</class>
<extends>QLineEdit</extends>
<header>clineedit.h</header>
</customwidget>
<customwidget>
<class>InternalMoveTreeWidget</class>
<extends>QTreeWidget</extends>
<header>treewidget_p.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="widgets.qrc"/>
<include location="../qglview.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonExpand</sender>
<signal>clicked()</signal>
<receiver>treeObjects</receiver>
<slot>expandAll()</slot>
<hints>
<hint type="sourcelabel">
<x>288</x>
<y>143</y>
</hint>
<hint type="destinationlabel">
<x>299</x>
<y>174</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonCollapse</sender>
<signal>clicked()</signal>
<receiver>treeObjects</receiver>
<slot>collapseAll()</slot>
<hints>
<hint type="sourcelabel">
<x>319</x>
<y>137</y>
</hint>
<hint type="destinationlabel">
<x>332</x>
<y>184</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonFocus</sender>
<signal>clicked()</signal>
<receiver>SceneTree</receiver>
<slot>focusObjects()</slot>
<hints>
<hint type="sourcelabel">
<x>26</x>
<y>37</y>
</hint>
<hint type="destinationlabel">
<x>17</x>
<y>27</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonRemove</sender>
<signal>clicked()</signal>
<receiver>SceneTree</receiver>
<slot>removeObjects()</slot>
<hints>
<hint type="sourcelabel">
<x>122</x>
<y>39</y>
</hint>
<hint type="destinationlabel">
<x>114</x>
<y>26</y>
</hint>
</hints>
</connection>
<connection>
<sender>lineFilter</sender>
<signal>textChanged(QString)</signal>
<receiver>SceneTree</receiver>
<slot>filter()</slot>
<hints>
<hint type="sourcelabel">
<x>239</x>
<y>100</y>
</hint>
<hint type="destinationlabel">
<x>355</x>
<y>37</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonFilterNode</sender>
<signal>toggled(bool)</signal>
<receiver>SceneTree</receiver>
<slot>filter()</slot>
<hints>
<hint type="sourcelabel">
<x>61</x>
<y>137</y>
</hint>
<hint type="destinationlabel">
<x>353</x>
<y>109</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonFilterMesh</sender>
<signal>toggled(bool)</signal>
<receiver>SceneTree</receiver>
<slot>filter()</slot>
<hints>
<hint type="sourcelabel">
<x>95</x>
<y>140</y>
</hint>
<hint type="destinationlabel">
<x>357</x>
<y>146</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonFilterLight</sender>
<signal>toggled(bool)</signal>
<receiver>SceneTree</receiver>
<slot>filter()</slot>
<hints>
<hint type="sourcelabel">
<x>135</x>
<y>135</y>
</hint>
<hint type="destinationlabel">
<x>353</x>
<y>173</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonFilterCamera</sender>
<signal>toggled(bool)</signal>
<receiver>SceneTree</receiver>
<slot>filter()</slot>
<hints>
<hint type="sourcelabel">
<x>161</x>
<y>135</y>
</hint>
<hint type="destinationlabel">
<x>351</x>
<y>226</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>removeObjects()</slot>
<slot>focusObjects()</slot>
<slot>filter()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,33 @@
#ifndef TREEWIDGET_H
#define TREEWIDGET_H
#include <QTreeWidget>
#include <QDropEvent>
#include <QDebug>
#include <QTimer>
class InternalMoveTreeWidget: public QTreeWidget
{
Q_OBJECT
public:
InternalMoveTreeWidget(QWidget * parent = 0): QTreeWidget(parent) {}
protected:
virtual void dropEvent(QDropEvent * e) {
QList<QTreeWidgetItem*> sil = selectedItems();
if (sil.isEmpty()) return;
QTreeWidget::dropEvent(e);
foreach (QTreeWidgetItem * ti, sil) {
QTreeWidgetItem * ti_p = ti->parent();
if (!ti_p) ti_p = invisibleRootItem();
int ti_ppos = ti_p->indexOfChild(ti);
emit itemMoved(ti, ti_p, ti_ppos);
}
}
signals:
void itemMoved(QTreeWidgetItem * item, QTreeWidgetItem * new_parent, int new_index);
};
#endif // TREEWIDGET_H

View File

@@ -0,0 +1,15 @@
<RCC>
<qresource prefix="/">
<file>../icons/go-jump.png</file>
<file>../icons/dialog-close.png</file>
<file>../icons/edit-clear.png</file>
<file>../icons/configure.png</file>
<file>../icons/document-save.png</file>
<file>../icons/edit-find.png</file>
<file>../icons/list-add.png</file>
<file>../icons/edit-delete.png</file>
<file>../icons/edit-copy.png</file>
<file>../icons/edit-paste.png</file>
<file>../icons/document-edit.png</file>
</qresource>
</RCC>