OSDN Git Service

カーソルストローク機能のGUIを作成
[qtgeoviewer/QtGeoViewer.git] / Src / QtGeoViewer / FormMain.cpp
1 #include "stdafx.h"
2 #include "FormMain.h"
3
4 #include <QFileInfo>
5 #include <fstream>
6 #include <sstream>
7
8 #include <cassert>
9 #include <QSettings>
10
11 #include "FormVertexBuilder.h"
12 #include "FullScreenPanel.h"
13
14 #include <Qt5Utility/QGui.h>
15
16 #include <QMessageBox>
17 #include <QFileDialog>
18 #include <QPrintDialog>
19 #include <QPrintPreviewDialog>
20
21 #include "BuildInfo.h"
22 #include "PathInfo.h"
23 #include "PostprocLibrary.h"
24 #include "SampleShapeBuilder.h"
25 #include "ShaderLibrary.h"
26 #include "QGVAboutDlg.h"
27
28 #include "FormCustomShader.h"
29 #include "FormPyScript.h"
30 #include "MatcapSelectDlg.h"
31 #include "EnvmapSelectDlg.h"
32 #include "FileDlgUtil.h"
33 #include "TreeUtil.h"
34
35
36
37 QColor ToQColor(const lib_graph::color4f& c)
38 {
39         int r = lm::clamp(0, (int)(c.r() * 255.0f), 255);
40         int g = lm::clamp(0, (int)(c.g() * 255.0f), 255);
41         int b = lm::clamp(0, (int)(c.b() * 255.0f), 255);
42         int a = lm::clamp(0, (int)(c.a() * 255.0f), 255);
43
44         return QColor(r, g, b, a);
45 }
46
47
48
49 FormMain::FormMain(QWidget *parent)
50         : QMainWindow(parent)
51         , m_MatcapDlg(NULL)
52         , m_EnvmapDlg(NULL)
53         , m_CustomShaderDlg(NULL)
54         , m_PyScriptDlg(NULL)
55 {
56         ui.setupUi(this);
57
58         m_EnableAllFeatures = false;
59         m_LastFocusedDockDlg = NULL;
60
61         setAcceptDrops(true);
62
63         setWindowTitle("QtGeoViewer");
64
65         InitializeGLView();
66         InitializeStatusBar();
67         InitializeMenu();
68         InitializeCoordinateCombobox();
69         Initialize2DViewSrcCombobox();
70         InitializeEventFilter();
71         InitContextMenu();
72
73         InitDataBinding();
74
75         SyncViewSettingsFromGUI();
76         SyncUVViewSettingsFromGUI();
77         SyncSceneSettingsFromGUI();
78         ApplyGeomStateFromGUI();
79         SyncShaderSettingsToGUI();
80
81         ui.toolBar_View->setVisible( ui.actionWindow_ToolBarView->isChecked() );
82
83         UpdateViewTypeFromMenu();
84
85         CenteringSplitter();
86
87         RebuildObjectList();
88
89         InitializeSubDlg();
90
91         InitializeAnimation();
92
93         InitializeFromConfigFiles();
94
95         HideFeatures();
96
97         ResetHoleRange();
98
99         this->show();
100
101         m_InitRect = rect();
102         m_InitRect.translate(pos());
103
104         LoadLastWinPos();
105
106         ProcArguments();
107 }
108
109 FormMain::~FormMain()
110 {
111 }
112
113
114 void FormMain::LoadLastWinPos(void)
115 {
116         QString file = PathInfo::GetPosConfigFilePath();
117         QSettings conf(file, QSettings::IniFormat);
118
119         QVariant v;
120         v = conf.value("main/WindowPos");
121         if (v.isValid())
122         {
123                 QRect r = v.toRect();
124                 int dl = r.left();
125                 int dt = r.top();
126                 int dw = r.width();
127                 int dh = r.height();
128
129                 resize(dw, dh);
130
131                 move(QPoint(dl, dt));
132         }
133
134         v = conf.value("main/WinState");
135         if (v.isValid())
136         {
137                 if (v.toBool())
138                         setWindowState(Qt::WindowMaximized);
139         }
140 }
141
142 void FormMain::SaveWinPos(void)
143 {
144         QString file = PathInfo::GetPosConfigFilePath();
145         QSettings conf(file, QSettings::IniFormat);
146
147         conf.setValue("main/WinState", isMaximized());
148
149         if (isMaximized() || isMinimized())
150         {
151                 setWindowState(Qt::WindowNoState);
152                 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
153         }
154
155         QRect r = rect();
156         r.translate(pos());
157
158         conf.setValue("main/WindowPos", r);
159 }
160
161 void FormMain::HideFeatures(void)
162 {
163         bool b = m_EnableAllFeatures;
164
165         ui.actionVertexBuilder->setVisible(b);
166         ui.menuPrintRoot->menuAction()->setVisible(b);
167         ui.actionShadowmap->setVisible(b);
168         ui.actionEnvmap->setVisible(b);
169         ui.actionShaderCustom->setVisible(b);
170         ui.actionWindowCustomShader->setVisible(b);
171         ui.actionPyScript->setVisible(b);
172         ui.actionConsole->setVisible(b);
173         ui.actionReleaseShader->setVisible(b);
174 }
175
176 void FormMain::InitializeEventFilter(void)
177 {
178         ui.editEnvMap->installEventFilter(this);
179         ui.editMatcap->installEventFilter(this);
180
181         ui.editCurrentTexName->installEventFilter(this);
182         ui.editCurrentMatNormalMap->installEventFilter(this);
183         ui.editMatCapEachMaterial->installEventFilter(this);
184 }
185
186 void FormMain::InitDataBinding(void)
187 {
188         InitializeVisiblStateMenu();
189         InitializeUVStateMenu();
190         InitializeSceneStateMenu();
191         InitializeGeomStateMenu();
192         InitializeCursorMenu();
193 }
194
195 void FormMain::InitializeVisiblStateMenu(void)
196 {
197         DataBinderMap& dbmap = m_Binder_ViewConfig;
198
199         View3DConfig& cfg_3d = m_View3d.m_Config;
200
201         dbmap.AddBinder(new MenuBinder(ui.actionDrawBBox            , &cfg_3d.m_DrawBBox            ));
202         dbmap.AddBinder(new MenuBinder(ui.actionFaceVBO             , &cfg_3d.m_EnableFaceVBO       ));
203         dbmap.AddBinder(new MenuBinder(ui.actionVidTopMost          , &cfg_3d.m_ShowVidTopMost      ));
204         dbmap.AddBinder(new MenuBinder(ui.actionDrawBBoxRange       , &cfg_3d.m_DrawBBoxRange       ));
205         dbmap.AddBinder(new MenuBinder(ui.actionWireDispList        , &cfg_3d.m_EnableWireDispList  ));
206         dbmap.AddBinder(new MenuBinder(ui.actionMultisample         , &cfg_3d.m_EnableMultisample   ));
207         dbmap.AddBinder(new MenuBinder(ui.actionCoverageTransparent , &cfg_3d.m_EnableCoverageTrans ));
208         dbmap.AddBinder(new MenuBinder(ui.actionSeparateSpecular    , &cfg_3d.m_SeparateSpecular    ));
209         dbmap.AddBinder(new MenuBinder(ui.actionShowSelVertCoord    , &cfg_3d.m_ShowSelVertCoord    ));
210         dbmap.AddBinder(new MenuBinder(ui.actionHighlightSelected   , &cfg_3d.m_HighlightSelected   ));
211         dbmap.AddBinder(new MenuBinder(ui.actionFixMaterialSilver   , &cfg_3d.m_UseFixMaterial      ));
212         dbmap.AddBinder(new MenuBinder(ui.actionShadowmapBuffer     , &cfg_3d.m_DrawShadowmapBuf    ));
213         dbmap.AddBinder(new MenuBinder(ui.actionEnableTexture3D     , &cfg_3d.m_EnableTexture       ));
214         dbmap.AddBinder(new MenuBinder(ui.actionEnableLighting      , &cfg_3d.m_EnableLighting      ));
215         dbmap.AddBinder(new MenuBinder(ui.actionEnableCulling       , &cfg_3d.m_EnableCullFace      ));
216         dbmap.AddBinder(new MenuBinder(ui.actionDrawWire            , &cfg_3d.m_DrawWire            ));
217         dbmap.AddBinder(new MenuBinder(ui.actionDrawVid             , &cfg_3d.m_DrawVid             ));
218         dbmap.AddBinder(new MenuBinder(ui.actionDrawVertNormal      , &cfg_3d.m_DrawVertNormal      ));
219         dbmap.AddBinder(new MenuBinder(ui.actionDrawVert            , &cfg_3d.m_DrawVert            ));
220         dbmap.AddBinder(new MenuBinder(ui.actionWireVBO             , &cfg_3d.m_EnableWireVBO       ));
221         dbmap.AddBinder(new MenuBinder(ui.actionIndexColorMode      , &cfg_3d.m_IndexMaterial       ));
222         dbmap.AddBinder(new MenuBinder(ui.actionFBMaterial          , &cfg_3d.m_FBMaterial          ));
223         dbmap.AddBinder(new MenuBinder(ui.actionDrawMiniAxis        , &cfg_3d.m_DrawMiniAxis        ));
224         dbmap.AddBinder(new MenuBinder(ui.actionDrawLookPos         , &cfg_3d.m_DrawLookPos         ));
225         dbmap.AddBinder(new MenuBinder(ui.actionDrawLightPos        , &cfg_3d.m_DrawLightPosition   ));
226         dbmap.AddBinder(new MenuBinder(ui.actionDrawGround          , &cfg_3d.m_DrawGround          ));
227         dbmap.AddBinder(new MenuBinder(ui.actionDrawFid             , &cfg_3d.m_DrawFid             ));
228         dbmap.AddBinder(new MenuBinder(ui.actionDrawFace            , &cfg_3d.m_DrawFace            ));
229         dbmap.AddBinder(new MenuBinder(ui.actionCameraRecords       , &cfg_3d.m_DrawCameraRecord    ));
230         dbmap.AddBinder(new MenuBinder(ui.actionDrawAxis            , &cfg_3d.m_DrawAxis            ));
231         dbmap.AddBinder(new MenuBinder(ui.actionDoubleSideShading   , &cfg_3d.m_DoubleSideShading   ));
232         dbmap.AddBinder(new MenuBinder(ui.actionDirectionalLight    , &cfg_3d.m_LightIsDirectional  ));
233         dbmap.AddBinder(new MenuBinder(ui.actionCullFrontOrBack     , &cfg_3d.m_CullAngle_F         ));
234         dbmap.AddBinder(new MenuBinder(ui.actionHighlightMaterial   , &cfg_3d.m_HighlightMaterial   ));
235         dbmap.AddBinder(new MenuBinder(ui.actionCloseVert           , &cfg_3d.m_ShowCloseVertInfo   ));
236         dbmap.AddBinder(new MenuBinder(ui.actionCameraRange         , &cfg_3d.m_DrawRenderRange     ));
237         dbmap.AddBinder(new MenuBinder(ui.actionRenderTime          , &cfg_3d.m_ShowRenderTime      ));
238         dbmap.AddBinder(new MenuBinder(ui.actionUseFixTexture       , &cfg_3d.m_UseFixTexture       ));
239         dbmap.AddBinder(new MenuBinder(ui.actionShowSelVertIdx      , &cfg_3d.m_ShowSelVertIdx      ));
240         dbmap.AddBinder(new MenuBinder(ui.actionShowMeshBound       , &cfg_3d.m_ShowMeshBound       ));
241         dbmap.AddBinder(new MenuBinder(ui.actionPickTransparent     , &cfg_3d.m_PickTransparent     ));
242         dbmap.AddBinder(new MenuBinder(ui.actionFlatShading         , &cfg_3d.m_EnableFlatShade     ));
243         dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineLenWhl  , &cfg_3d.m_DrawPolylineLenWhl  ));
244         dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineLen     , &cfg_3d.m_DrawPolylineLen     ));
245         dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineIdx     , &cfg_3d.m_DrawPolylineIdx     ));
246         dbmap.AddBinder(new MenuBinder(ui.actionDrawPolyline        , &cfg_3d.m_DrawPolyline        ));
247         dbmap.AddBinder(new MenuBinder(ui.actionDrawBone            , &cfg_3d.m_DrawBone            ));
248         dbmap.AddBinder(new MenuBinder(ui.actionShowMeasure         , &cfg_3d.m_DrawCameraMeasure   ));
249         dbmap.AddBinder(new MenuBinder(ui.actionFlipMouseMR         , &cfg_3d.m_FlipMouseMR         ));
250         dbmap.AddBinder(new MenuBinder(ui.actionSyncLightToCamera   , &cfg_3d.m_SyncLightTocamera   ));
251
252         for (GuiBinder& binder : dbmap.m_BinderMap)
253         {
254                 MenuBinder* mb = dynamic_cast<MenuBinder*>(&binder);
255                 if (mb != NULL)
256                 {
257                         QAction* a = mb->GetMenu();
258                         connect(
259                                 a,
260                                 SIGNAL(triggered(bool)),
261                                 this,
262                                 SLOT(actionVisibleStates_Triggered(bool)));
263                 }
264         }
265 }
266
267 void FormMain::InitializeUVStateMenu(void)
268 {
269         DataBinderMap& dbmap = m_Binder_UVConfig;
270
271         dbmap.AddBinder(new MenuBinder(ui.actionUVRepeat         , &m_View2d.m_RepeatTexture             ));
272         dbmap.AddBinder(new MenuBinder(ui.actionUseFixTexture2D  , &m_View2d.m_UseFixTexute              ));
273         dbmap.AddBinder(new MenuBinder(ui.actionShowVertex2d     , &m_View2d.m_DrawVerts                 ));
274         dbmap.AddBinder(new MenuBinder(ui.actionShowImage2d      , &m_View2d.m_EnableTexture             ));
275         dbmap.AddBinder(new MenuBinder(ui.actionTextureMipmap    , &m_Scene.m_TexConfig.m_EnableMipmap   ));
276         dbmap.AddBinder(new MenuBinder(ui.actionTextureCompress  , &m_Scene.m_TexConfig.m_EnableCompress ));
277         dbmap.AddBinder(new MenuBinder(ui.actionUVFlipY          , &m_Scene.m_TextureTransform.m_FlipY   ));
278
279         for (GuiBinder& binder : dbmap.m_BinderMap)
280         {
281                 MenuBinder* mb = dynamic_cast<MenuBinder*>(&binder);
282                 if (mb != NULL)
283                 {
284                         QAction* a = mb->GetMenu();
285                         connect(
286                                 a,
287                                 SIGNAL(triggered(bool)),
288                                 this,
289                                 SLOT(actionVisibleStatesUV_Triggered(bool)));
290                 }
291         }
292 }
293
294 void FormMain::InitializeSceneStateMenu(void)
295 {
296         DataBinderMap& dbmap = m_Binder_Scene;
297
298         dbmap.AddBinder(new CheckboxBinder( ui.checkEnvMap         , &m_Scene.m_EnvImg.m_VisibleEnvSphere       ));
299         dbmap.AddBinder(new CheckboxBinder( ui.checkEnvReflection  , &m_Scene.m_EnvImg.m_IsEnableReflection     ));
300         dbmap.AddBinder(new CheckboxBinder( ui.checkShadowEnabled  , &m_Scene.m_ShadowConfig.m_EnableShadow     ));
301         dbmap.AddBinder(new CheckboxBinder( ui.checkSoftShadow     , &m_Scene.m_ShadowConfig.m_EnableSoftShadow ));
302
303         for (GuiBinder& binder : dbmap.m_BinderMap)
304         {
305                 CheckboxBinder* mb = dynamic_cast<CheckboxBinder*>(&binder);
306                 if (mb != NULL)
307                 {
308                         QCheckBox* c = mb->GetCheckBox();
309                         connect(
310                                 c,
311                                 SIGNAL(toggled(bool)),
312                                 this,
313                                 SLOT(actionSceneStates_Toggled(bool)));
314                 }
315         }
316 }
317
318 void FormMain::InitializeCursorMenu(void)
319 {
320         DataBinderMap& dbmap = m_Binder_Cursor;
321
322         Cursor3D& cursor = m_Scene.m_Cursor3d;
323         dbmap.AddBinder(new MenuBinder( ui.actionShowCursor       , &cursor.ShowCursor     ));
324         dbmap.AddBinder(new MenuBinder( ui.actionCursorToDepth    , &cursor.CursorDepth    ));
325         dbmap.AddBinder(new MenuBinder( ui.actionCursorCoord      , &cursor.ShowCoord      ));
326         dbmap.AddBinder(new MenuBinder( ui.actionCheckBaryCoord   , &cursor.CheckBaryCoord ));
327         dbmap.AddBinder(new MenuBinder( ui.actionSelectCloseMat   , &cursor.SelCloseVert   ));
328         dbmap.AddBinder(new MenuBinder( ui.actionCursorAxis       , &cursor.ShowAxis       ));
329         dbmap.AddBinder(new MenuBinder( ui.actionMeasure          , &cursor.ShowMeasure    ));
330         dbmap.AddBinder(new MenuBinder( ui.actionMeasureLen       , &cursor.ShowMeasureLen ));
331         dbmap.AddBinder(new MenuBinder( ui.actionMeasureXYZ       , &cursor.ShowMeasureXYZ ));
332         dbmap.AddBinder(new MenuBinder( ui.actionRecordStroke     , &cursor.RecordStroke   ));
333         dbmap.AddBinder(new MenuBinder( ui.actionShowStrokeLength , &cursor.ShowStrokeLen  ));
334
335         for (GuiBinder& binder : dbmap.m_BinderMap)
336         {
337                 MenuBinder* mb = dynamic_cast<MenuBinder*>(&binder);
338                 if (mb != NULL)
339                 {
340                         QAction* a = mb->GetMenu();
341                         connect(
342                                 a,
343                                 SIGNAL(triggered(bool)),
344                                 this,
345                                 SLOT(actionCursorMenuStates_Toggled(bool)));
346                 }
347         }
348 }
349
350
351 void FormMain::InitializeGeomStateMenu(void)
352 {
353         AddGeomStateAction( ui.actionCentering  );
354         AddGeomStateAction( ui.actionAutoResize );
355 }
356
357 void FormMain::AddGeomStateAction(const QAction* action)
358 {
359         connect(
360                 action,
361                 SIGNAL(triggered(bool)),
362                 this,
363                 SLOT(actionGeomStates_Triggered(bool)));
364 }
365
366
367 void FormMain::InitializeGLView(void)
368 {
369         ui.GLWidgetMain->setMouseTracking(true);
370         ui.GLWidgetUV->setMouseTracking(true);
371
372         ui.GLWidgetMain->SetViewer(&m_View3d);
373         m_View3d.m_Widgets = &m_Widgets;
374         m_View3d.RegisterScene(&m_Scene);
375         m_View3d.InitializeView(ui.GLWidgetMain);
376
377         ui.GLWidgetUV->SetViewer(&m_View2d);
378         m_View2d.m_Widgets = &m_Widgets;
379         m_View2d.RegisterScene(&m_Scene);
380         m_View2d.InitializeView(ui.GLWidgetUV);
381
382         m_Widgets.AddWidget(ui.GLWidgetMain);
383         m_Widgets.AddWidget(ui.GLWidgetUV);
384
385         // OpenGL\82Ì\83\8a\83X\83g\82Ì\8b¤\97L\89»
386         SetContextShare();
387
388         m_ContextShare.BeginDrawTop();
389
390         m_Scene.Initialize();
391
392         m_ContextShare.EndDrawTop();
393
394         connect(
395                 &m_View3d,
396                 SIGNAL(SelectedObjectChanged(int, int)),
397                 SLOT(View3D_SelectedObjectChanged(int, int)));
398         connect(
399                 &m_View3d,
400                 SIGNAL(SelectedMatChanged(int)),
401                 SLOT(View3D_SelectedMatChanged(int)));
402         connect(
403                 &m_View3d,
404                 SIGNAL(CameraMoved(void)),
405                 SLOT(View3D_CameraMoved(void)));
406         connect(
407                 &m_View3d,
408                 SIGNAL(StatusTipChanged(QString)),
409                 SLOT(View3D_StatusTipChanged(QString)));
410         connect(
411                 &m_View3d,
412                 SIGNAL(SequenceStepped(int)),
413                 SLOT(View3D_SequenceStepped(int)));
414         connect(
415                 &m_View3d,
416                 SIGNAL(CursorMoved()),
417                 SLOT(View3D_CursorMoved()));
418 }
419
420 // OpenGL\82Ì\83\8a\83X\83g\82Ì\8b¤\97L\89»
421 void FormMain::SetContextShare(void)
422 {
423         ui.GLWidgetUV->makeCurrent();
424         m_ContextShare.AddContext( GetDC((HWND)ui.GLWidgetUV->winId()) , wglGetCurrentContext() );
425         ui.GLWidgetUV->doneCurrent();
426
427         ui.GLWidgetMain->makeCurrent();
428         m_ContextShare.AddContext( GetDC((HWND)ui.GLWidgetUV->winId()) , wglGetCurrentContext() );
429         ui.GLWidgetMain->doneCurrent();
430
431         m_ContextShare.MakeShare();
432 }
433
434 void FormMain::InitializeCoordinateCombobox(void)
435 {
436         ui.comboCoordinate->blockSignals(true);
437         ui.comboCoordinate->addItem("Yup RH"); // RUF
438         ui.comboCoordinate->addItem("Zup RH"); // FRU
439         ui.comboCoordinate->addItem("Xup RH"); // UFR
440         ui.comboCoordinate->addItem("Yup LH"); // RUB
441         ui.comboCoordinate->addItem("Zup LH"); // BRU
442         ui.comboCoordinate->addItem("Xup LH"); // UBR
443         ui.comboCoordinate->blockSignals(false);
444 }
445
446 void FormMain::Initialize2DViewSrcCombobox(void)
447 {
448         ui.combo2DViewSrcType->blockSignals(true);
449         ui.combo2DViewSrcType->addItem("Color");
450         ui.combo2DViewSrcType->addItem("Normal");
451         ui.combo2DViewSrcType->blockSignals(false);
452 }
453
454 void FormMain::InitializeStatusBar(void)
455 {
456         m_StatusBar0 = new QLabel(this);
457         m_StatusBar1 = new QLabel(this);
458         ui.statusBar->addWidget(m_StatusBar0, 1);
459         ui.statusBar->addWidget(m_StatusBar1, 0);
460
461         m_StatusBar0->setText("");
462
463         m_StatusBar1->setMinimumWidth(290);
464         m_StatusBar1->setText("");
465 }
466
467 void FormMain::InitializeFromConfigFiles(void)
468 {
469         if (!InitializeConfig(PathInfo::GetGuiConfigFilePath()))
470         {
471                 InitializeConfig(PathInfo::GetDefaultGuiConfigFilePath());
472         }
473
474         OpenCameraFile(PathInfo::GetCameraLogFilePath());
475
476         LoadWindowLayout(PathInfo::GetWindowLayoutConfigFilePath());
477
478         if (!QGui::LoadGUIState(this, PathInfo::GetLayoutConfigFilePath()))
479         {
480                 QGui::LoadGUIState(this, PathInfo::GetDefaultLayoutConfigFilePath());
481         }
482 }
483
484 void FormMain::LoadDefaultConfig(void)
485 {
486         InitializeConfig(PathInfo::GetDefaultGuiConfigFilePath());
487         QGui::LoadGUIState(this, PathInfo::GetDefaultLayoutConfigFilePath());
488 }
489
490 void FormMain::SaveConfig(void)
491 {
492         PathInfo::CreateConfiDirIfNotExist();
493
494         SaveConfigFile(PathInfo::GetGuiConfigFilePath());
495
496         m_View3d.m_CameraRecord.SaveCamera(PathInfo::GetCameraLogFilePath().toLocal8Bit().data());
497
498         QGui::SaveGUIState(this, PathInfo::GetLayoutConfigFilePath());
499
500         SaveWindowLayout(PathInfo::GetWindowLayoutConfigFilePath());
501 }
502
503 bool FormMain::InitializeConfig(QString path)
504 {
505         View3DConfig& config_3d = m_View3d.m_Config;
506
507         GuiConfig cfg;
508         cfg.m_Config3D = &config_3d;
509         cfg.m_Scene    = &m_Scene;
510
511         if (!cfg.LoadConfigT(path.toLocal8Bit().data()))
512                 return false;
513
514         ui.actionUVAutoFit->setChecked(cfg.m_AutFitUVView);
515
516         ui.comboCoordinate->setCurrentIndex(cfg.m_CoordType);
517
518         CreateRecentFilesMenu(cfg.m_RecentFiles);
519
520         m_Binder_ViewConfig.UpdateAllGUI(true);
521         m_Binder_UVConfig.UpdateAllGUI(true);
522         m_Binder_Scene.UpdateAllGUI(true);
523         m_Binder_Cursor.UpdateAllGUI(true);
524
525         ApplyGeomStateDataoToGUI();
526
527         SyncViewSettingsFromGUI();
528         SyncUVViewSettingsFromGUI();
529         SyncShaderSettingsToGUI();
530
531         m_EnableAllFeatures = cfg.m_EnableAllFeatures;
532
533         return true;
534 }
535
536 void FormMain::SaveConfigFile(QString path)
537 {
538         GuiConfig cfg;
539         cfg.m_Config3D = &m_View3d.m_Config;
540         cfg.m_Scene    = &m_Scene;
541
542         cfg.m_EnableAllFeatures = m_EnableAllFeatures;
543
544         cfg.m_AutFitUVView = ui.actionUVAutoFit ->isChecked();
545
546         cfg.m_CoordType = ui.comboCoordinate->currentIndex();
547
548         CreateRecentFilesFromMenu(cfg.m_RecentFiles);
549
550         cfg.SaveConfigT(path.toLocal8Bit().data());
551 }
552
553
554 void FormMain::InitializeSubDlg(void)
555 {
556         connect(
557                 &m_WireColorSelDlg,
558                 SIGNAL(currentColorChanged(const QColor &)),
559                 this,
560                 SLOT(WireOverlayColorChanged(const QColor &)));
561         connect(
562                 &m_DiffuseColorSelDlg,
563                 SIGNAL(currentColorChanged(const QColor &)),
564                 this,
565                 SLOT(FaceDiffuseColorChanged(const QColor &)));
566         connect(
567                 &m_BGColorSelDlg,
568                 SIGNAL(currentColorChanged(const QColor &)),
569                 this,
570                 SLOT(BGColorChanged(const QColor &)));
571         connect(
572                 &m_SelMatColorSelDlg,
573                 SIGNAL(currentColorChanged(const QColor &)),
574                 this,
575                 SLOT(SelMatColorChanged(const QColor &)));
576
577         m_SelMatColorWidget = NULL;
578
579         m_ViewConfigDlg.InitializeConfigDlg(&m_View3d.m_Config);
580         connect(
581                 &m_ViewConfigDlg,
582                 SIGNAL(ConfigChanged()),
583                 this,
584                 SLOT(ConfigChangedDlg_ConfigChanged()));
585
586         m_CrossSectionDlg.InitializeConfigDlg(&m_View3d);
587         connect(
588                 &m_CrossSectionDlg,
589                 SIGNAL(ConfigChanged()),
590                 this,
591                 SLOT(CrossSectionDlg_ConfigChanged()));
592 }
593
594 void FormMain::InitializeAnimation(void)
595 {
596         connect(
597                 &m_AnimationTimer,
598                 SIGNAL(timeout()),
599                 this,
600                 SLOT(OnAnimationTimerUpdated()));
601         m_AnimationTimer.setInterval(20);
602 }
603
604 void FormMain::InitializeMenu(void)
605 {
606         m_AGroup_Window = new QActionGroup(this);
607         m_AGroup_Window->setExclusive(true);
608         m_AGroup_Window->addAction( ui.actionWindow_3DView    );
609         m_AGroup_Window->addAction( ui.actionWindow_UVView    );
610         m_AGroup_Window->addAction( ui.actionWindows_DualView );
611
612         m_AGroup_Shader = new QActionGroup(this);
613         m_AGroup_Shader->setExclusive(true);
614         m_AGroup_Shader->addAction( ui.actionShaderDefault   );
615         m_AGroup_Shader->addAction( ui.actionShaderPhong     );
616         m_AGroup_Shader->addAction( ui.actionShaderCustom    );
617         m_AGroup_Shader->addAction( ui.actionNormalColor     );
618         m_AGroup_Shader->addAction( ui.actionDepthColor      );
619         m_AGroup_Shader->addAction( ui.actionShadowmap       );
620         m_AGroup_Shader->addAction( ui.actionEnvmap          );
621         m_AGroup_Shader->addAction( ui.actionIntegrateShader );
622         m_AGroup_Shader->addAction( ui.actionMatcapShader    );
623
624         m_AGroup_PProc = new QActionGroup(this);
625         m_AGroup_PProc->addAction( ui.actionPostProcNone            );
626         m_AGroup_PProc->addAction( ui.actionPostProcAntialias       );
627         m_AGroup_PProc->addAction( ui.actionPostProcBorder          );
628         m_AGroup_PProc->addAction( ui.actionPostProcDepthLayerColor );
629         m_AGroup_PProc->addAction( ui.actionPostProcDepthColor      );
630         m_AGroup_PProc->addAction( ui.actionPostProcDepthOfField    );
631 }
632
633 void FormMain::InitContextMenu(void)
634 {
635         QList<QAction*> actions;
636         actions
637                 << ui.actionSelObjectVisible
638                 << ui.actionSelObjectVertexOnlyMode
639                 << ui.actionSelObjectDelete
640                 << ui.actionSelObjectReload
641                 << ui.actionSelObjectFlipFace
642                 << ui.actionSelObjectFlipNormal
643                 << ui.actionSelObjectOpenDir
644                 << ui.actionActionSelObjectShowOnlyOnce
645                 << ui.actionSelObjectTriangulate
646                 << ui.actionTreeCollapseAll
647                 << ui.actionTreeExpandAll;
648
649         QTreeWidget* obj_tree = ui.treeObjects;
650
651         obj_tree->setContextMenuPolicy(Qt::ActionsContextMenu);
652         obj_tree->addActions(actions);
653 }
654
655 void FormMain::ProcArguments(void)
656 {
657         QStringList args = QApplication::arguments();
658         for (int i = 1; i < args.size(); ++i)
659         {
660                 QString s = args[i];
661                 OpenGeomFile(s);
662         }
663 }
664
665 void FormMain::closeEvent(QCloseEvent *e)
666 {
667         SaveWinPos();
668
669         SaveConfig();
670
671         e->accept();
672
673         m_ViewConfigDlg.close();
674         m_CrossSectionDlg.close();
675         m_FullscreenPanel.close();
676
677         if (m_CustomShaderDlg != NULL)
678                 m_CustomShaderDlg->close();
679         if (m_PyScriptDlg != NULL)
680                 m_PyScriptDlg->close();
681
682         if (m_MatcapDlg != NULL)
683                 m_MatcapDlg->close();
684         if (m_EnvmapDlg != NULL)
685                 m_EnvmapDlg->close();
686
687         m_ContextShare.BeginDrawTop();
688         m_Scene.FinalizeScene();
689         m_ContextShare.EndDrawTop();
690 }
691
692
693 bool FormMain::eventFilter(QObject * filterobj, QEvent * filterevt)
694 {
695         if (filterobj == ui.editEnvMap)
696         {
697                 if (filterevt->type() == QEvent::DragEnter)
698                         return AcceptDropFilterIfUrl(filterevt);
699
700                 if (filterevt->type() == QEvent::Drop)
701                         return OnDropFile_editEnvMap(filterevt);
702         }
703         else if (filterobj == ui.editMatcap)
704         {
705                 if (filterevt->type() == QEvent::DragEnter)
706                         return AcceptDropFilterIfUrl(filterevt);
707
708                 if (filterevt->type() == QEvent::Drop)
709                         return OnDropFile_editMatcap(filterevt);
710         }
711         else if (filterobj == ui.editMatCapEachMaterial)
712         {
713                 if (filterevt->type() == QEvent::DragEnter)
714                         return AcceptDropFilterIfUrl(filterevt);
715
716                 if (filterevt->type() == QEvent::Drop)
717                         return OnDropFile_editMatcapEachMat(filterevt);
718         }
719         else if (filterobj == ui.editCurrentTexName)
720         {
721                 if (filterevt->type() == QEvent::DragEnter)
722                         return AcceptDropFilterIfUrl(filterevt);
723
724                 if (filterevt->type() == QEvent::Drop)
725                         return OnDropFile_editCurrentTexName(filterevt);
726         }
727         else if (filterobj == ui.editCurrentMatNormalMap)
728         {
729                 if (filterevt->type() == QEvent::DragEnter)
730                         return AcceptDropFilterIfUrl(filterevt);
731
732                 if (filterevt->type() == QEvent::Drop)
733                         return OnDropFile_editCurrentMatNormalMap(filterevt);
734         }
735
736         return QMainWindow::eventFilter(filterobj, filterevt);
737 }
738
739 bool FormMain::OnDropFile_editEnvMap(QEvent * filterevt)
740 {
741         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
742         if (!path.isEmpty())
743                 LoadEnvMap(path);
744
745         return true;
746 }
747
748 bool FormMain::OnDropFile_editMatcap(QEvent * filterevt)
749 {
750         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
751         if (!path.isEmpty())
752                 LoadMatcapImage(path);
753
754         return true;
755 }
756
757 bool FormMain::OnDropFile_editMatcapEachMat(QEvent * filterevt)
758 {
759         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
760         if (!path.isEmpty())
761                 LoadMatcapImageForCurrentMat(path);
762
763         return true;
764 }
765
766 bool FormMain::OnDropFile_editCurrentTexName(QEvent * filterevt)
767 {
768         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
769         if (!path.isEmpty())
770                 LoadCurSelMatTexture(TextureType::Color, path);
771
772         return true;
773 }
774
775 bool FormMain::OnDropFile_editCurrentMatNormalMap(QEvent * filterevt)
776 {
777         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
778         if (!path.isEmpty())
779                 LoadCurSelMatTexture(TextureType::Normal, path);
780
781         return true;
782 }
783
784 bool FormMain::AcceptDropFilterIfUrl(QEvent * filterevt)
785 {
786         QDragEnterEvent* e = dynamic_cast<QDragEnterEvent*>(filterevt);
787         if (e == NULL)
788                 return false;
789
790         if (e->mimeData()->hasUrls())
791                 e->acceptProposedAction();
792
793         return true;
794 }
795
796 QString FormMain::GetFirstLoadableImagePathFromDragEvent(QEvent* filterevt)
797 {
798         QDropEvent* e = dynamic_cast<QDropEvent*>(filterevt);
799         if (e == NULL)
800                 return false;
801
802         if (!e->mimeData()->hasUrls())
803                 return false;
804
805         QList<QUrl> urls = e->mimeData()->urls();
806         for (int i = 0; i < urls.size(); ++i)
807         {
808                 QString path = urls[i].toLocalFile();
809                 if (IsSupportedTextureExt(path))
810                         return path;
811         }
812
813         return QString();
814 }
815
816
817 void FormMain::CenteringSplitter(void)
818 {
819         int w = ui.splitter->width();
820         QList<int> s;
821         s.append(w / 2);
822         s.append(w / 2);
823         ui.splitter->setSizes(s);
824 }
825
826 void FormMain::updateView_All(void)
827 {
828         updateView_3D();
829         updateView_2D();
830 }
831
832 void FormMain::updateView_2D(void)
833 {
834         ui.GLWidgetUV->update();
835 }
836
837 void FormMain::updateView_3D(void)
838 {
839         ui.GLWidgetMain->update();
840 }
841
842 void FormMain::on_actionOpen_triggered()
843 {
844         FileDlgFilterList exts;
845         exts.Add( "Wavefront"   , "obj" );
846         exts.Add( "STL"         , "stl" );
847         exts.Add( "PLY"         , "ply" );
848         exts.Add( "Metasequoia" , "mqo" );
849         exts.Add( "Pmd"         , "pmd" );
850         exts.Add( "Collada"     , "dae" );
851         exts.Add( "DirectX"     , "x"   );
852
853         QString filter = FileDlgUtil::ExtListToDlgFilter("Geometry", exts);
854         QString title = "Open file";
855         QString fileName = GetFilePathFromOpenDlg(title, filter);
856
857         if (fileName.isEmpty())
858                 return;
859
860         if (IsResetSceneOnBeforeLoadFile())
861                 ClearAllObjects();
862
863         if (OpenGeomFile(fileName))
864                 return;
865 }
866
867 void FormMain::on_actionExit_triggered()
868 {
869         close();
870 }
871
872 void FormMain::actionVisibleStates_Triggered(bool checked)
873 {
874         QAction* a = dynamic_cast<QAction*>(QObject::sender());
875         if (checked)
876         {
877                 if (a == ui.actionIndexColorMode)
878                 {
879                         ui.actionFixMaterialSilver->setChecked(false);
880                         ui.actionFBMaterial->setChecked(false);
881                 }
882                 else if (a == ui.actionFixMaterialSilver)
883                 {
884                         ui.actionIndexColorMode->setChecked(false);
885                         ui.actionFBMaterial->setChecked(false);
886                 }
887                 else if (a == ui.actionFBMaterial)
888                 {
889                         ui.actionFixMaterialSilver->setChecked(false);
890                         ui.actionIndexColorMode->setChecked(false);
891                 }
892         }
893
894         SyncViewSettingsFromGUI();
895         updateView_All();
896 }
897
898 void FormMain::SyncViewSettingsFromGUI(void)
899 {
900         m_Binder_ViewConfig.UpdateAllData();
901
902         QAction* menu = GetMenuFromShader(m_View3d.m_Config.m_ShaderMode);
903         if (menu != NULL)
904                 menu->setChecked(true);
905 }
906
907 QAction* FormMain::GetMenuFromShader(ShaderType type)
908 {
909         switch(m_View3d.m_Config.m_ShaderMode)
910         {
911         case ShaderType::Phong      : return ui.actionShaderPhong;
912         case ShaderType::Custom     : return ui.actionShaderCustom;
913         case ShaderType::NormalColor: return ui.actionNormalColor;
914         case ShaderType::DepthColor : return ui.actionDepthColor;
915         case ShaderType::Shadowmap  : return ui.actionShadowmap;
916         case ShaderType::Envmap     : return ui.actionEnvmap;
917         case ShaderType::Integrate  : return ui.actionIntegrateShader;
918         case ShaderType::Matcap     : return ui.actionMatcapShader;
919         case ShaderType::Default    : return ui.actionShaderDefault;
920
921         default:
922                 assert(false);
923                 return NULL;
924         };
925 }
926
927 bool FormMain::SaveWindowLayout(const QString& filepath)
928 {
929         WindowConfig config;
930
931         config.m_MainWinLeft   = geometry().x();
932         config.m_MainWinTop    = geometry().y();
933         config.m_MainWinWidth  = geometry().width();
934         config.m_MainWinHeight = geometry().height();
935         config.m_IsMaximized   = isMaximized();
936
937         return config.SaveConfig(filepath.toLocal8Bit().data());
938 }
939
940 bool FormMain::LoadWindowLayout(const QString& filepath)
941 {
942         WindowConfig config;
943         if (!config.LoadConfig(filepath.toLocal8Bit().data()))
944                 return false;
945
946         if (config.m_IsMaximized)
947                 showMaximized();
948
949         int l = config.m_MainWinLeft;
950         int t = config.m_MainWinTop;
951         int w = config.m_MainWinWidth;
952         int h = config.m_MainWinHeight;
953         setGeometry(l, t, w, h);
954
955         return true;
956 }
957
958 void FormMain::actionVisibleStatesUV_Triggered(bool)
959 {
960         SyncUVViewSettingsFromGUI();
961 }
962
963 void FormMain::SyncUVViewSettingsFromGUI(void)
964 {
965         m_Binder_UVConfig.UpdateAllData();
966         updateView_All();
967 }
968
969 void FormMain::actionSceneStates_Toggled(bool)
970 {
971         SyncSceneSettingsFromGUI();
972 }
973
974 void FormMain::SyncSceneSettingsFromGUI(void)
975 {
976         m_Binder_Scene.UpdateAllData();
977         updateView_All();
978 }
979
980 void FormMain::on_actionWindow_ToolBarView_triggered(bool checked)
981 {
982         ui.toolBar_View->setVisible( ui.actionWindow_ToolBarView->isChecked() );
983 }
984
985 void FormMain::on_actionToolBar_Options_toggled(bool checked)
986 {
987         ui.toolBar_Option->setVisible(checked);
988 }
989
990 void FormMain::on_actionToolBar_Operation_toggled(bool checked)
991 {
992         ui.toolBar_Operation->setVisible(checked);
993 }
994
995 void FormMain::on_actionCameraDist_triggered()
996 {
997         m_View3d.AdjustCameraDistAuto();
998 }
999
1000 void FormMain::on_actionCameraFront_triggered()
1001 {
1002         m_View3d.MoveCaemraTo(ViewPoint::Front);
1003 }
1004
1005 void FormMain::on_actionCameraBack_triggered()
1006 {
1007         m_View3d.MoveCaemraTo(ViewPoint::Back);
1008 }
1009
1010 void FormMain::on_actionCameraLeft_triggered()
1011 {
1012         m_View3d.MoveCaemraTo(ViewPoint::Left);
1013 }
1014
1015 void FormMain::on_actionCameraRight_triggered()
1016 {
1017         m_View3d.MoveCaemraTo(ViewPoint::Right);
1018 }
1019
1020 void FormMain::on_actionCameraTop_triggered()
1021 {
1022         m_View3d.MoveCaemraTo(ViewPoint::Top);
1023 }
1024
1025 void FormMain::on_actionCameraBottom_triggered()
1026 {
1027         m_View3d.MoveCaemraTo(ViewPoint::Bottom);
1028 }
1029
1030 void FormMain::on_actionCameraPers_triggered()
1031 {
1032         m_View3d.MoveCaemraTo(ViewPoint::Perse);
1033 }
1034
1035 void FormMain::on_actionCameraLookOrigin_triggered()
1036 {
1037         m_View3d.MoveLookPosToOrigin();
1038 }
1039
1040 void FormMain::on_actionCameraLookCenter_triggered()
1041 {
1042         m_View3d.MoveLookPosToCenter();
1043 }
1044
1045 void FormMain::on_actionWindow_3DView_triggered(bool checked)
1046 {
1047         UpdateViewTypeFromMenu();
1048 }
1049
1050 void FormMain::on_actionWindows_DualView_triggered(bool checked)
1051 {
1052         UpdateViewTypeFromMenu();
1053 }
1054
1055 void FormMain::on_actionWindow_UVView_triggered(bool checked)
1056 {
1057         UpdateViewTypeFromMenu();
1058 }
1059
1060 void FormMain::UpdateViewTypeFromMenu(void)
1061 {
1062         if (ui.actionWindows_DualView->isChecked())
1063         {
1064                 ui.frameView3D->setVisible(true);
1065                 ui.frameView2D->setVisible(true);
1066
1067                 // TODO: \89¼. \8bN\93®\8e\9e\82É\83r\83\85\81[\82ð1:1\82É\90Ý\92è\82Å\82«\82È\82¢\96â\91è\82Ì\89¼\91Î\89\9e.
1068                 static bool firsttime = true;
1069                 if (firsttime)
1070                 {
1071                         firsttime = false;
1072                         CenteringSplitter();
1073                 }
1074         }
1075         if (ui.actionWindow_3DView->isChecked())
1076         {
1077                 ui.frameView3D->setVisible(true);
1078                 ui.frameView2D->setVisible(false);
1079         }
1080         if (ui.actionWindow_UVView->isChecked())
1081         {
1082                 ui.frameView3D->setVisible(false);
1083                 ui.frameView2D->setVisible(true);
1084         }
1085 }
1086
1087 void FormMain::on_actionWindowMaterialList_triggered()
1088 {
1089         ShowAndActivateAndRaise(ui.dockMaterial);
1090         ui.listMaterial->setFocus();
1091 }
1092
1093 void FormMain::on_actionWindowObjectList_triggered()
1094 {
1095         ShowAndActivateAndRaise(ui.dockObject);
1096         ui.treeObjects->setFocus();
1097 }
1098
1099 void FormMain::on_actionWindowCameraList_triggered()
1100 {
1101         ShowAndActivateAndRaise(ui.dockCamera);
1102         ui.listCamera->setFocus();
1103 }
1104
1105 void FormMain::on_actionWindowScenePanel_triggered()
1106 {
1107         ShowAndActivateAndRaise(ui.dockScene);
1108 }
1109
1110 void FormMain::on_actionCursorPanel_triggered()
1111 {
1112         ShowAndActivateAndRaise(ui.dockCursor);
1113 }
1114
1115 void FormMain::on_listMaterial_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
1116 {
1117         m_Scene.m_Sels.SetSelMat(ui.listMaterial->currentRow());
1118         OnChangedSelectedMaterial();
1119         updateView_All();
1120 }
1121
1122 void FormMain::ShowAndActivateAndRaise(QDockWidget* widget)
1123 {
1124         widget->setVisible(true);
1125         widget->activateWindow();
1126         widget->raise();
1127 }
1128
1129 void FormMain::on_treeObjects_currentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem * previous)
1130 {
1131         RefreshObjectSelectState();
1132 }
1133
1134 void FormMain::RefreshObjectSelectState(void)
1135 {
1136         SetPrimayrSelectObjectToScene();
1137
1138         QListWidget* list_mat = ui.listMaterial;
1139         list_mat->clear();
1140
1141         const MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
1142         if (mbuf != NULL)
1143         {
1144                 const lib_geo::BaseMesh& mesh = mbuf->m_Mesh;
1145                 for (const lib_geo::BaseMaterial& mat : mesh.m_Materials)
1146                 {
1147                         const std::string& name = mat.m_Name;
1148
1149                         if (name.empty())
1150                                 list_mat->addItem("--");
1151                         else
1152                                 list_mat->addItem(QString::fromLocal8Bit(name.c_str()));
1153                 }
1154         }
1155
1156         const GeomObject* obj = m_Scene.GetPrimaryObject();
1157         if (mbuf != NULL)
1158         {
1159                 ui.actionSelObjectVisible->setChecked(mbuf->IsVisible());
1160         }
1161         else if (obj != NULL)
1162         {
1163                 ui.actionSelObjectVisible->setChecked(obj->m_Visible);
1164         }
1165         
1166         if (obj != NULL)
1167                 ui.actionSelObjectVertexOnlyMode->setChecked(obj->m_VertexOnlyMode);
1168
1169         if (list_mat->count() > 0 && list_mat->currentRow() < 0)
1170         {
1171                 list_mat->setCurrentRow(0);
1172                 m_Scene.m_Sels.SetSelMat(0);
1173                 OnChangedSelectedMaterial();
1174         }
1175
1176         updateView_All();
1177 }
1178
1179 void FormMain::OnChangedSelectedMaterial(void)
1180 {
1181         if (IsAutUVFit())
1182         {
1183                 m_View2d.FitView();
1184         }
1185
1186         ui.editCurrentTexName->clear();
1187
1188         GeomTextureSet* ts = m_Scene.GetSelectedTexture();
1189         if (ts == NULL)
1190         {
1191                 ui.editCurrentTexName->setText("");
1192                 ui.editMatCapEachMaterial->setText("");
1193         }
1194         else
1195         {
1196                 QString name_c, name_n;
1197
1198                 gl::GlTexture* tex_c = ts->GetTexColor();
1199                 if (tex_c != NULL)
1200                         name_c = QString::fromLocal8Bit(tex_c->GetName().c_str());
1201
1202                 gl::GlTexture* tex_n = ts->GetTexNormal();
1203                 if (tex_n != NULL)
1204                         name_n = QString::fromLocal8Bit(tex_n->GetName().c_str());
1205
1206                 ui.editCurrentTexName->setText(name_c);
1207                 ui.editCurrentMatNormalMap->setText(name_n);
1208
1209                 MatcapImage& matcap = ts->TexMatcap;
1210                 ui.editMatCapEachMaterial->setText(matcap.GetName());
1211         }
1212
1213         lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
1214         if (mat != NULL)
1215         {
1216                 SetWidgetColor(ui.colorAmbient  , ToQColor(mat->m_Ambient));
1217                 SetWidgetColor(ui.colorEmission , ToQColor(mat->m_Emission));
1218                 SetWidgetColor(ui.colorDiffuse  , ToQColor(mat->m_Diffuse));
1219                 SetWidgetColor(ui.colorSpecular , ToQColor(mat->m_Specular));
1220
1221                 int val_max = ui.sliderShininess->maximum();
1222                 int slider_pos = (int)(mat->m_Shininess * (float)val_max / 200.0f);
1223                 slider_pos = (lm::min)(val_max, slider_pos);
1224                 ui.sliderShininess->blockSignals(true);
1225                 ui.sliderShininess->setValue(slider_pos);
1226                 ui.sliderShininess->blockSignals(false);
1227                 ui.labelShininessVal->setText(QString::number(mat->m_Shininess, 'f', 2));
1228         }
1229
1230         updateView_All();
1231 }
1232
1233 void FormMain::keyPressEvent(QKeyEvent *e)
1234 {
1235         Modifier m(e);
1236         if (m.Flag_C() && e->key() == Qt::Key_Tab)
1237         {
1238                 FocusNextSubDlg();
1239         }
1240 }
1241
1242 void FormMain::FocusNextSubDlg(void)
1243 {
1244         std::vector<QDockWidget*> widgets;
1245
1246         if (ui.dockObject   ->isVisible()) widgets.push_back( ui.dockObject   );
1247         if (ui.dockCamera   ->isVisible()) widgets.push_back( ui.dockCamera   );
1248         if (ui.dockScene    ->isVisible()) widgets.push_back( ui.dockScene    );
1249         if (ui.dockMaterial ->isVisible()) widgets.push_back( ui.dockMaterial );
1250
1251         if (widgets.empty())
1252                 return;
1253
1254         QDockWidget* next_widget = NULL;
1255
1256         for (size_t i = 0; i < widgets.size(); ++i)
1257         {
1258                 if (widgets[i] == m_LastFocusedDockDlg)
1259                 {
1260                         next_widget = widgets[(i + 1) % widgets.size()];
1261                         break;
1262                 }
1263         }
1264
1265         if (next_widget == NULL)
1266                 next_widget = widgets.front();
1267
1268         m_LastFocusedDockDlg = next_widget;
1269
1270         next_widget->activateWindow();
1271         next_widget->raise();
1272         next_widget->setFocus();
1273 }
1274
1275 void FormMain::dragEnterEvent(QDragEnterEvent* e)
1276 {
1277         if (e->mimeData()->hasUrls())
1278                 e->acceptProposedAction();
1279 }
1280
1281 void FormMain::dropEvent(QDropEvent* e)
1282 {
1283         if (e->mimeData()->hasUrls())
1284         {
1285                 QList<QUrl> urls = e->mimeData()->urls();
1286
1287                 std::vector<QString> geom_files;
1288
1289                 for (int i = 0; i < urls.size(); ++i)
1290                 {
1291                         QString path = urls[i].toLocalFile();
1292                         if (FormatType::IsGeomFileExt(path))
1293                                 geom_files.push_back(path);
1294                 }
1295
1296                 if (!geom_files.empty())
1297                 {
1298                         if (IsResetSceneOnBeforeLoadFile())
1299                                 ClearAllObjects();
1300
1301                         for (size_t i = 0; i < geom_files.size(); ++i)
1302                         {
1303                                 if (OpenGeomFile(geom_files[i]))
1304                                         continue;
1305                         }
1306                 }
1307
1308                 for (int i = 0; i < urls.size(); ++i)
1309                 {
1310                         QString path = urls[i].toLocalFile();
1311
1312                         if (IsSupportedTextureExt(path))
1313                         {
1314                                 OpenFixTextureFile(path);
1315                                 continue;
1316                         }
1317
1318                         if (IsCameraFile(path))
1319                         {
1320                                 OpenCameraFile(path);
1321                                 continue;
1322                         }
1323                 }
1324         }
1325 }
1326
1327 bool FormMain::IsResetSceneOnBeforeLoadFile(void) const
1328 {
1329         if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
1330                 return true;
1331
1332         return false;
1333 }
1334
1335 //! \83I\83u\83W\83F\83N\83g\82Ì\83}\83e\83\8a\83A\83\8b\82É\90Ý\92è\82³\82ê\82½\82à\82Ì\82Æ\82Í\95Ê\82Ì\83e\83N\83X\83`\83\83\82ð\8ew\92è\82·\82é.
1336 void FormMain::OpenFixTextureFile(const QString& path)
1337 {
1338         std::string fname = path.toLocal8Bit().data();
1339
1340         m_ContextShare.BeginDrawTop();
1341         m_Scene.LoadDefaultMatTexture(fname);
1342         m_ContextShare.EndDrawTop();
1343
1344         updateView_All();
1345 }
1346
1347 bool FormMain::OpenGeomFile(const QString& path)
1348 {
1349         m_Scene.m_ObjSplit = ui.checkSplitOBJ->isChecked();
1350
1351         m_ContextShare.BeginDrawTop();
1352
1353         bool suc = true;
1354         try
1355         {
1356                 m_Scene.ImportFileAutoFmt(path);
1357         }
1358         catch(const FileLoadErrorException& ex)
1359         {
1360                 QString msg;
1361                 msg += "Failed Load ";
1362                 msg += path + "\n\n";
1363                 msg += QString::fromLocal8Bit(ex.what());
1364
1365                 QMessageBox::warning(this, "", msg);
1366                 suc = false;
1367         }
1368
1369         m_ContextShare.EndDrawTop();
1370
1371         RebuildObjectList();
1372
1373         ResetSequenceSliderRange();
1374
1375         updateView_All();
1376
1377         if (!suc)
1378                 return false;
1379
1380         AddRecentFile(path);
1381
1382         return true;
1383 }
1384
1385 void FormMain::ClearAllObjects(void)
1386 {
1387         m_ContextShare.BeginDrawTop();
1388
1389         m_Scene.ClearObjects();
1390
1391         m_ContextShare.EndDrawTop();
1392
1393         m_View3d.ClearRenderMap();
1394
1395         RebuildObjectList();
1396         RefreshObjectSelectState();
1397
1398         updateView_All();
1399 }
1400
1401 void FormMain::RebuildObjectList(void)
1402 {
1403         QTreeWidget* obj_tree = ui.treeObjects;
1404
1405         obj_tree->setCurrentItem(NULL);
1406         obj_tree->blockSignals(true);
1407
1408         obj_tree->clear();
1409
1410         obj_tree->setSelectionBehavior(QAbstractItemView::SelectRows);
1411         obj_tree->setSelectionMode(QAbstractItemView::SingleSelection);
1412         obj_tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
1413
1414         obj_tree->setColumnCount(4);
1415
1416         InitObjectListHeader();
1417
1418         for (const geom::GeomObject& obj : m_Scene.m_Objects)
1419         {
1420                 QTreeWidgetItem* n = CreateObjectTreeNode(obj);
1421                 PushbackTreeNode(ui.treeObjects, n);
1422                 n->setExpanded(true);
1423         }
1424
1425         SetPrimayrSelectObjectFromScene();
1426
1427         obj_tree->blockSignals(false);
1428
1429         if (obj_tree->currentItem() == NULL)
1430         {
1431                 if (!m_Scene.m_Objects.empty())
1432                 {
1433                         QTreeWidgetItem* ti = obj_tree->topLevelItem(0);
1434                         obj_tree->setCurrentItem(ti);
1435
1436                         if (IsAutUVFit())
1437                                 m_View2d.FitView();
1438                 }
1439         }
1440
1441         ResizeTreeColumns(obj_tree, 4);
1442 }
1443
1444
1445 bool FormMain::IsCameraFile(const QString& path) const
1446 {
1447         QFileInfo fInfo( path );
1448         QString ext = fInfo.suffix().toLower();
1449         return (ext == "camera");
1450 }
1451
1452 bool FormMain::OpenCameraFile(const QString& path)
1453 {
1454         std::string fname = path.toLocal8Bit().data();
1455
1456         if(!m_View3d.m_CameraRecord.LoadCamera(fname.c_str()))
1457                 return false;
1458
1459         ui.listCamera->blockSignals(true);
1460         ui.listCamera->clear();
1461         for (size_t i = 0; i < m_View3d.m_CameraRecord.m_Records.size(); ++i)
1462         {
1463                 ui.listCamera->addItem( QString::number(i) );
1464         }
1465         ui.listCamera->blockSignals(false);
1466
1467         return true;
1468 }
1469
1470
1471 void FormMain::actionGeomStates_Triggered(bool)
1472 {
1473         ApplyGeomStateFromGUI();
1474
1475         m_Scene.UpdateTransform();
1476
1477         updateView_All();
1478 }
1479
1480 void FormMain::ApplyGeomStateFromGUI(void)
1481 {
1482         m_Scene.m_Config.m_EnableAutoCentering = ui.actionCentering->isChecked();
1483         m_Scene.m_Config.m_EnableAutoReisze    = ui.actionAutoResize->isChecked();
1484 }
1485
1486 void FormMain::ApplyGeomStateDataoToGUI(void)
1487 {
1488         ui.actionAutoResize ->setChecked( m_Scene.m_Config.m_EnableAutoReisze    );
1489         ui.actionCentering  ->setChecked( m_Scene.m_Config.m_EnableAutoCentering );
1490
1491         ui.checkShowOnlySelect->setChecked(m_View3d.m_Config.m_ShowOnlySelect);
1492 }
1493
1494 void FormMain::on_actionGeomClear_triggered()
1495 {
1496         ClearAllObjects();
1497 }
1498
1499
1500 void FormMain::on_actionUVFitView_triggered()
1501 {
1502         m_View2d.FitView();
1503         updateView_All();
1504 }
1505
1506 void FormMain::on_actionSelObjectDelete_triggered()
1507 {
1508         DeleteSelectedObject();
1509 }
1510
1511 void FormMain::on_actionSelObjectReload_triggered()
1512 {
1513         GeomObject* obj = m_Scene.GetPrimaryObject();
1514         if (obj == NULL)
1515                 return;
1516
1517         if (!obj->IsFileObject())
1518         {
1519                 QMessageBox::information(this, "", "IsNotFileObject");
1520                 return;
1521         }
1522
1523         m_Scene.ReloadObject(obj);
1524
1525         RebuildObjectList();
1526
1527         updateView_All();
1528 }
1529
1530 void FormMain::on_actionSelObjectVisible_triggered()
1531 {
1532         FlipVisibleSelectedObject();
1533 }
1534
1535 void FormMain::on_actionSelObjectVertexOnlyMode_triggered()
1536 {
1537         GeomObject* obj = m_Scene.GetPrimaryObject();
1538         if (obj == NULL)
1539                 return;
1540
1541         obj->m_VertexOnlyMode = !obj->m_VertexOnlyMode;
1542
1543         ui.actionSelObjectVertexOnlyMode->setChecked(obj->m_VertexOnlyMode);
1544
1545         updateView_All();
1546 }
1547
1548 void FormMain::on_actionSelObjectFlipFace_triggered()
1549 {
1550         m_Scene.FlipCurselFace(false);
1551
1552         ui.GLWidgetMain->makeCurrent();
1553         std::vector<MeshBuf*> mv = m_Scene.GetCurSelMeshes();
1554         for (MeshBuf* m : mv)
1555         {
1556                 m_View3d.ReleaseRenderbuffer(m);
1557         }
1558         ui.GLWidgetMain->doneCurrent();
1559
1560         updateView_All();
1561 }
1562
1563 void FormMain::on_actionSelObjectFlipNormal_triggered()
1564 {
1565         m_Scene.FlipCurselFace(true);
1566
1567         ui.GLWidgetMain->makeCurrent();
1568         std::vector<MeshBuf*> mv = m_Scene.GetCurSelMeshes();
1569         for (MeshBuf* m : mv)
1570         {
1571                 m_View3d.ReleaseRenderbuffer(m);
1572         }
1573         ui.GLWidgetMain->doneCurrent();
1574
1575         updateView_All();
1576 }
1577
1578 void FormMain::on_actionSelObjectOpenDir_triggered()
1579 {
1580         GeomObject* obj = m_Scene.GetPrimaryObject();
1581         if (obj == NULL)
1582                 return;
1583
1584         if (!obj->IsFileObject())
1585                 return;
1586
1587         QString path = QString::fromLocal8Bit(obj->m_FilePath.c_str());
1588         QString p2 = QDir::toNativeSeparators(path);
1589         QGui::ShowExplorerFileSel(p2);
1590 }
1591
1592 void FormMain::on_actionShowOnlySelected_triggered()
1593 {
1594         ShowObjectOnlySelected();
1595 }
1596
1597 void FormMain::on_actionSelObjectTriangulate_triggered()
1598 {
1599         MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
1600         if (mbuf == NULL)
1601                 return;
1602
1603         mbuf->Triangulate();
1604
1605         m_View3d.ReleaseAllRenderBuffer();
1606
1607         RebuildObjectList();
1608         updateView_All();
1609 }
1610
1611 void FormMain::on_actionTreeCollapseAll_triggered()
1612 {
1613         TreeUtil::SetAllTopExpand(ui.treeObjects, false);
1614 }
1615
1616 void FormMain::on_actionTreeExpandAll_triggered()
1617 {
1618         TreeUtil::SetAllTopExpand(ui.treeObjects, true);
1619 }
1620
1621
1622 void FormMain::on_actionAddSample_triggered()
1623 {
1624         SampleShapeBuilder::CreateSphere(m_Scene);
1625         OnDoneAddGeom();
1626 }
1627
1628 void FormMain::on_actionAddGroundPlane_triggered()
1629 {
1630         SampleShapeBuilder::CreateGroundPlane(m_Scene);
1631         OnDoneAddGeom();
1632 }
1633
1634 void FormMain::OnDoneAddGeom(void)
1635 {
1636         QTreeWidget* obj_tree = ui.treeObjects;
1637
1638         const GeomObject& obj = m_Scene.m_Objects.back();
1639
1640         obj_tree->setCurrentItem(NULL);
1641         obj_tree->blockSignals(true);
1642
1643         QTreeWidgetItem* n = CreateObjectTreeNode(obj);
1644         PushbackTreeNode(obj_tree, n);
1645         n->setExpanded(true);
1646
1647         SetPrimayrSelectObjectFromScene();
1648
1649         obj_tree->blockSignals(false);
1650
1651         if (obj_tree->currentItem() == NULL)
1652         {
1653                 if (!m_Scene.m_Objects.empty())
1654                 {
1655                         QTreeWidgetItem * j = obj_tree->topLevelItem(0);
1656                         obj_tree->setCurrentItem(j);
1657
1658                         if (IsAutUVFit())
1659                                 m_View2d.FitView();
1660                 }
1661         }
1662
1663         ResizeTreeColumns(obj_tree, 4);
1664
1665         ResetSequenceSliderRange();
1666
1667         updateView_All();
1668 }
1669
1670
1671 void FormMain::on_actionShaderDefault_triggered(bool)
1672 {
1673         ChangeShaderMenuMain(ShaderType::Default);
1674 }
1675
1676 void FormMain::on_actionShaderPhong_triggered(bool)
1677 {
1678         ChangeShaderMenuMain(ShaderType::Phong);
1679 }
1680
1681 void FormMain::on_actionShaderCustom_triggered(bool)
1682 {
1683         ChangeShaderMenuMain(ShaderType::Custom);
1684 }
1685
1686 void FormMain::on_actionNormalColor_triggered(bool)
1687 {
1688         ChangeShaderMenuMain(ShaderType::NormalColor);
1689 }
1690
1691 void FormMain::on_actionDepthColor_triggered(bool)
1692 {
1693         ChangeShaderMenuMain(ShaderType::DepthColor);
1694 }
1695
1696 void FormMain::on_actionShadowmap_triggered(bool)
1697 {
1698         ChangeShaderMenuMain(ShaderType::Shadowmap);
1699 }
1700
1701 void FormMain::on_actionEnvmap_triggered(bool)
1702 {
1703         ChangeShaderMenuMain(ShaderType::Envmap);
1704 }
1705
1706 void FormMain::on_actionIntegrateShader_triggered(bool)
1707 {
1708         ChangeShaderMenuMain(ShaderType::Integrate);
1709 }
1710
1711 void FormMain::on_actionMatcapShader_triggered(bool)
1712 {
1713         ChangeShaderMenuMain(ShaderType::Matcap);
1714 }
1715
1716 void FormMain::SyncShaderSettingsToGUI(void)
1717 {
1718         ChangeShaderMenuMain(m_View3d.m_Config.m_ShaderMode);
1719 }
1720
1721 void FormMain::ChangeShaderMenuMain(ShaderType type)
1722 {
1723         m_View3d.m_Config.m_ShaderMode = type;
1724         updateView_All();
1725 }
1726
1727
1728 void FormMain::on_actionCreate_Check_triggered()
1729 {
1730         CreateSampleTextureMain(SampleTextureBuilder::TEX_CHECKER);
1731 }
1732
1733 void FormMain::on_actionCreate_Stripe_V_triggered()
1734 {
1735         CreateSampleTextureMain(SampleTextureBuilder::TEX_STRIPE_V);
1736 }
1737
1738 void FormMain::on_actionCreate_Stripe_H_triggered()
1739 {
1740         CreateSampleTextureMain(SampleTextureBuilder::TEX_STRIPE_H);
1741 }
1742
1743 void FormMain::CreateSampleTextureMain(SampleTextureBuilder::TextureType tex_type)
1744 {
1745         m_ContextShare.BeginDrawTop();
1746         m_Scene.CreateSampleTexture(tex_type);
1747         m_ContextShare.EndDrawTop();
1748
1749         updateView_All();
1750 }
1751
1752 bool FormMain::IsAutUVFit(void) const
1753 {
1754         return ui.actionUVAutoFit->isChecked();
1755 }
1756
1757
1758 void FormMain::on_pushDeleteSelectedObject_clicked()
1759 {
1760         DeleteSelectedObject();
1761 }
1762
1763 void FormMain::on_treeObjects_itemChanged(QTreeWidgetItem * item, int column)
1764 {
1765         QTreeWidget* obj_tree = ui.treeObjects;
1766
1767         if (column == 1)
1768         {
1769                 QTreeWidgetItem* t = item->parent();
1770                 bool checked = (item->checkState(1) == Qt::Checked);
1771                 if (t == NULL)
1772                 {
1773                         int sel_idx = obj_tree->indexOfTopLevelItem(item);
1774                         GeomObject& obj = m_Scene.m_Objects[sel_idx];
1775                         obj.m_Visible = checked;
1776                 }
1777                 else
1778                 {
1779                         int sel_idx = obj_tree->indexOfTopLevelItem(t);
1780                         int midx = t->indexOfChild(item);
1781
1782                         GeomObject& obj = m_Scene.m_Objects[sel_idx];
1783                         MeshBuf& mb = obj.m_MeshAry[midx];
1784                         mb.m_Visible = checked;
1785                 }
1786
1787                 updateView_All();
1788         }
1789 }
1790
1791
1792 void FormMain::DeleteSelectedObject()
1793 {
1794         QTreeWidget* obj_tree = ui.treeObjects;
1795         QTreeWidgetItem* ti = obj_tree->currentItem();
1796         if (ti == NULL)
1797                 return;
1798
1799         QTreeWidgetItem* pn = ti->parent();
1800
1801         int sel_idx;
1802         if (pn == NULL)
1803                 sel_idx = obj_tree->indexOfTopLevelItem(ti);
1804         else
1805                 sel_idx = obj_tree->indexOfTopLevelItem(pn);
1806
1807         if (sel_idx < 0)
1808                 return;
1809
1810         m_ContextShare.BeginDrawTop();
1811
1812         m_Scene.RemoveItem(sel_idx);
1813
1814         m_ContextShare.EndDrawTop();
1815
1816         m_View3d.ClearRenderMap();
1817
1818         obj_tree->setCurrentItem(NULL);
1819         obj_tree->takeTopLevelItem(sel_idx);
1820
1821         ResizeTreeColumns(obj_tree, 4);
1822
1823         ti = obj_tree->currentItem();
1824         sel_idx = obj_tree->indexOfTopLevelItem(ti);
1825         m_Scene.m_Sels.SelectObject(sel_idx);
1826
1827         m_Scene.UpdateTransform();
1828
1829         RefreshObjectSelectState();
1830
1831         ResetSequenceSliderRange();
1832
1833         updateView_All();
1834 }
1835
1836 void FormMain::FlipVisibleSelectedObject()
1837 {
1838         QTreeWidget* obj_tree = ui.treeObjects;
1839         QTreeWidgetItem * item = obj_tree->currentItem();
1840         if (item == NULL)
1841                 return;
1842
1843         item->setCheckState(1, FilpState(item->checkState(1)));
1844 }
1845
1846 Qt::CheckState FormMain::FilpState(Qt::CheckState state) const
1847 {
1848         if(state == Qt::Checked)
1849                 return Qt::Unchecked;
1850         else
1851                 return Qt::Checked;
1852 }
1853
1854 void FormMain::ShowObjectOnlySelected(void)
1855 {
1856         GeomObject* sel_obj = m_Scene.GetPrimaryObject();
1857         if (sel_obj == NULL)
1858                 return;
1859
1860         for (GeomObject& o : m_Scene.m_Objects)
1861         {
1862                 o.m_Visible = (sel_obj == &o);
1863         }
1864
1865         RebuildObjectList();
1866         updateView_All();
1867 }
1868
1869 void FormMain::ShowAllObject(void)
1870 {
1871         m_Scene.ShowAllObject();
1872
1873         RebuildObjectList();
1874         updateView_All();
1875 }
1876
1877 void FormMain::HideAllObject(void)
1878 {
1879         m_Scene.HideAllObject();
1880
1881         RebuildObjectList();
1882         updateView_All();
1883 }
1884
1885 void FormMain::on_actionUVResetView_triggered()
1886 {
1887         m_View2d.ResetView();
1888
1889         updateView_All();
1890 }
1891
1892
1893 //! \83\8f\83C\83\84\81[\83I\81[\83o\81[\83\8c\83C\95\\8e¦\8e\9e\82Ì\90F\90Ý\92è
1894 void FormMain::on_actionWireColor_triggered()
1895 {
1896         m_WireColorSelDlg.exec();
1897 }
1898
1899 //! \83f\83t\83H\83\8b\83g\83}\83e\83\8a\83A\83\8b\82Ì\90F\90Ý\92è
1900 void FormMain::on_actionFaceColor_triggered()
1901 {
1902         const lib_graph::color4f& c = m_Scene.m_DefaultMaterial.m_Diffuse;
1903
1904         m_DiffuseColorSelDlg.setOption(QColorDialog::ShowAlphaChannel);
1905         m_DiffuseColorSelDlg.setCurrentColor(ToQColor(c));
1906         m_DiffuseColorSelDlg.exec();
1907 }
1908
1909 //! \94w\8ci\90F\82Ì\90Ý\92è
1910 void FormMain::on_actionBackGroundColor_triggered()
1911 {
1912         const lib_graph::color4f& c = m_View3d.m_BGColor;
1913
1914         m_BGColorSelDlg.setCurrentColor(ToQColor(c));
1915         m_BGColorSelDlg.exec();
1916 }
1917
1918 void FormMain::WireOverlayColorChanged(const QColor & color)
1919 {
1920         lib_graph::color3b& c = m_View3d.m_Config.m_WireColor;
1921         c.set(color.red(), color.green(), color.blue());
1922
1923         m_View3d.ReleaseAllRenderBuffer();
1924
1925         updateView_All();
1926 }
1927
1928 void FormMain::CopyRGB(lib_graph::color4f& c, const QColor & color)
1929 {
1930         c.r() = (float)color.red()   / 255.0f;
1931         c.g() = (float)color.green() / 255.0f;
1932         c.b() = (float)color.blue()  / 255.0f;
1933 }
1934
1935 void FormMain::CopyRGBA(lib_graph::color4f& c, const QColor & color)
1936 {
1937         c.r() = (float)color.red()   / 255.0f;
1938         c.g() = (float)color.green() / 255.0f;
1939         c.b() = (float)color.blue()  / 255.0f;
1940         c.a() = (float)color.alpha() / 255.0f;
1941 }
1942
1943 void FormMain::FaceDiffuseColorChanged(const QColor & color)
1944 {
1945         lib_graph::color4f& c = m_Scene.m_DefaultMaterial.m_Diffuse;
1946         CopyRGB(c, color);
1947
1948         m_View3d.ReleaseAllRenderBuffer();
1949         updateView_All();
1950 }
1951
1952 void FormMain::BGColorChanged(const QColor & color)
1953 {
1954         lib_graph::color4f& c = m_View3d.m_BGColor;
1955         CopyRGB(c, color);
1956
1957         updateView_All();
1958 }
1959
1960 void FormMain::SetSelectedMaterialColor(QColor col)
1961 {
1962         lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
1963         if (mat == NULL)
1964                 return;
1965
1966         if (m_SelMatColorWidget == ui.colorAmbient  ) CopyRGBA(mat->m_Ambient  , col);
1967         if (m_SelMatColorWidget == ui.colorEmission ) CopyRGBA(mat->m_Emission , col);
1968         if (m_SelMatColorWidget == ui.colorDiffuse  ) CopyRGBA(mat->m_Diffuse  , col);
1969         if (m_SelMatColorWidget == ui.colorSpecular ) CopyRGBA(mat->m_Specular , col);
1970
1971         SetWidgetColor(m_SelMatColorWidget, col);
1972 }
1973
1974 void FormMain::SelMatColorChanged(const QColor & color)
1975 {
1976         SetSelectedMaterialColor(color);
1977         m_View3d.ResetPrimaryObjectLists();
1978         updateView_All();
1979 }
1980
1981
1982 void FormMain::on_actionWindowOptions_triggered()
1983 {
1984         m_ViewConfigDlg.showNormal();
1985         m_ViewConfigDlg.show();
1986         m_ViewConfigDlg.activateWindow();
1987 }
1988
1989 void FormMain::on_actionWindowCustomShader_triggered()
1990 {
1991         if (m_CustomShaderDlg == NULL)
1992         {
1993                 m_CustomShaderDlg = new FormCustomShader(this);
1994                 m_CustomShaderDlg->SetShaderLibrary(&m_View3d.m_ShaderLib);
1995                 m_CustomShaderDlg->SetParentWidget(ui.GLWidgetMain);
1996                 m_CustomShaderDlg->LoadOrSetDefaultCode();
1997                 connect(
1998                         m_CustomShaderDlg,
1999                         SIGNAL(ShaderBuild()),
2000                         this,
2001                         SLOT(CustomShaderDlg_ShaderBuild()));
2002         }
2003
2004         m_CustomShaderDlg->showNormal();
2005         m_CustomShaderDlg->show();
2006         m_CustomShaderDlg->activateWindow();
2007 }
2008
2009
2010 void FormMain::ConfigChangedDlg_ConfigChanged()
2011 {
2012         m_View3d.ReleaseAllRenderBuffer();
2013         updateView_All();
2014 }
2015
2016 void FormMain::CrossSectionDlg_ConfigChanged()
2017 {
2018         updateView_All();
2019 }
2020
2021
2022 void FormMain::OnPaintImage(QPrinter *printer)
2023 {
2024         QPainter painter(printer);
2025
2026         QRect rect = painter.viewport();
2027         QSize size = this->size();
2028         size.scale(rect.size(), Qt::KeepAspectRatio);//\8fc\89¡\94ä\88Û\8e\9d
2029
2030         painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
2031         painter.setWindow(this->rect());
2032
2033         this->render(&painter);
2034 }
2035
2036 void FormMain::on_actionPrint_triggered()
2037 {
2038         PrintImage(false);
2039 }
2040
2041 void FormMain::on_actionPrintPreview_triggered()
2042 {
2043         PrintImage(true);
2044 }
2045
2046 void FormMain::PrintImage(bool WithPreview)
2047 {
2048         //QPrinter printer(QPrinter::ScreenResolution);
2049         QPrinter printer(QPrinter::ScreenResolution);
2050
2051         if(WithPreview)
2052         {
2053                 QPrintPreviewDialog preview(&printer, this);
2054                 preview.setWindowFlags( Qt::Window );
2055                 connect(
2056                         &preview,
2057                         SIGNAL(paintRequested(QPrinter *)),
2058                         SLOT(OnPaintImage(QPrinter *)));
2059
2060                 preview.showMaximized();
2061                 preview.exec();
2062         }
2063         else
2064         {
2065                 QPrintDialog printDialog(&printer, this);
2066                 if(printDialog.exec() == QDialog::Accepted)
2067                         OnPaintImage(&printer);
2068         }
2069 }
2070
2071
2072 void FormMain::on_pushButtonAddCameraRecord_clicked()
2073 {
2074         m_View3d.RecordCamera();
2075
2076         ui.listCamera->addItem( QString::number(ui.listCamera->count()) );
2077
2078         updateView_3D();
2079 }
2080
2081 void FormMain::on_pushButtonDeleteCameraRecord_clicked()
2082 {
2083         int idx = ui.listCamera->currentRow();
2084         if(idx < 0)
2085                 return;
2086
2087         m_View3d.RemoveRecordedCamera(idx);
2088
2089         for (int i = idx+1; i < ui.listCamera->count(); ++i)
2090         {
2091                 ui.listCamera->item(i)->setText(QString::number(i - 1));
2092         }
2093
2094         ui.listCamera->takeItem(idx);
2095
2096         updateView_3D();
2097 }
2098
2099 void FormMain::on_pushCameraRecordClear_clicked()
2100 {
2101         m_View3d.ClearRecordedCamera();
2102
2103         ui.listCamera->clear();
2104
2105         updateView_3D();
2106 }
2107
2108 void FormMain::on_listCamera_itemDoubleClicked(QListWidgetItem *item)
2109 {
2110         int idx = ui.listCamera->currentRow();
2111         if (idx < 0)
2112                 return;
2113
2114         m_View3d.MoveToRecordedCamera(idx, ui.checkCameraAnimation->isChecked());
2115 }
2116
2117 void FormMain::on_actionSaveCamera_triggered()
2118 {
2119         QString title = "camera";
2120         QString filter = "Camera File(*.camera)";
2121         QString fileName = GetFilePathFromSaveDlg(title, filter);
2122         if (fileName.isEmpty())
2123                 return;
2124
2125         m_View3d.m_CameraRecord.SaveCamera(fileName.toLocal8Bit().data());
2126 }
2127
2128 void FormMain::on_actionProjectionOrtho_triggered()
2129 {
2130         ui.actionProjectionOrtho->setChecked(true);
2131         ui.actionProjectionPers->setChecked(false);
2132
2133         m_View3d.m_Camera.m_ProjMode = gl::Camera::PROJ_ORTHO;
2134
2135         updateView_All();
2136 }
2137
2138 void FormMain::on_actionProjectionPers_triggered()
2139 {
2140         ui.actionProjectionPers->setChecked(true);
2141         ui.actionProjectionOrtho->setChecked(false);
2142
2143         m_View3d.m_Camera.m_ProjMode = gl::Camera::PROJ_PERS;
2144
2145         updateView_All();
2146 }
2147
2148
2149 void FormMain::CustomShaderDlg_ShaderBuild()
2150 {
2151         updateView_All();
2152 }
2153
2154 void FormMain::OnAnimationTimerUpdated()
2155 {
2156         static const float rot_speed = 0.005f;
2157
2158         if (ui.actionRotateCamera->isChecked())
2159         {
2160                 m_View3d.m_Camera.m_Manip.Tumble(rot_speed, 0.0f);
2161                 UpdateCameraStatus();
2162         }
2163
2164         if (ui.actionRotateLight->isChecked())
2165                 m_View3d.m_ControlLight.m_Position.rotate_y(rot_speed);
2166
2167         if (ui.actionAnimation->isChecked())
2168         {
2169                 StepSequence(1);
2170                 if (IsLastSequence())
2171                         ui.actionAnimation->setChecked(false);
2172         }
2173
2174         updateView_3D();
2175 }
2176
2177 void FormMain::on_actionRotateCamera_toggled(bool checked)
2178 {
2179         UpdateAnimState();
2180 }
2181
2182 void FormMain::on_actionRotateLight_toggled(bool checked)
2183 {
2184         UpdateAnimState();
2185 }
2186
2187 void FormMain::on_actionAnimation_toggled(bool checked)
2188 {
2189         if (checked)
2190         {
2191                 if (IsLastSequence())
2192                 {
2193                         QSlider* s = ui.sliderSequence;
2194                         s->setValue(0);
2195                 }
2196         }
2197
2198         UpdateAnimState();
2199 }
2200
2201 void FormMain::UpdateAnimState(void)
2202 {
2203         if (IsEnableAnimation())
2204                 m_AnimationTimer.start();
2205         else
2206                 m_AnimationTimer.stop();
2207 }
2208
2209 bool FormMain::IsEnableAnimation(void)
2210 {
2211         if (ui.actionRotateCamera->isChecked())
2212                 return true;
2213         if (ui.actionRotateLight->isChecked())
2214                 return true;
2215         if (ui.actionAnimation->isChecked())
2216                 return true;
2217
2218         return false;
2219 }
2220
2221 void FormMain::on_actionCrossSectionDlg_triggered()
2222 {
2223         m_CrossSectionDlg.showNormal();
2224         m_CrossSectionDlg.show();
2225         m_CrossSectionDlg.activateWindow();
2226 }
2227
2228 void FormMain::on_actionSelectNext_triggered()
2229 {
2230         AddSelectObjectIdx(1);
2231 }
2232
2233 void FormMain::on_actionSelectPrev_triggered()
2234 {
2235         AddSelectObjectIdx(-1);
2236 }
2237
2238 void FormMain::AddSelectObjectIdx(int step)
2239 {
2240         QTreeWidget* obj_tree = ui.treeObjects;
2241
2242         int num_obj = obj_tree->topLevelItemCount();
2243         if (num_obj == 0)
2244                 return;
2245
2246         QTreeWidgetItem * i = obj_tree->currentItem();
2247         int idx = obj_tree->indexOfTopLevelItem(i);
2248         idx += step;
2249
2250         if (0 > idx)
2251                 idx = num_obj - 1;
2252         else if (idx >= num_obj)
2253                 idx = 0;
2254
2255         QTreeWidgetItem * j = obj_tree->topLevelItem(idx);
2256         obj_tree->setCurrentItem(j);
2257 }
2258
2259 void FormMain::on_actionSwitchVisible_triggered()
2260 {
2261         FlipVisibleSelectedObject();
2262 }
2263
2264 void FormMain::on_actionActionSelObjectShowOnlyOnce_triggered()
2265 {
2266         ShowObjectOnlySelected();
2267 }
2268
2269 void FormMain::on_actionHideAll_triggered()
2270 {
2271         HideAllObject();
2272 }
2273
2274 void FormMain::on_actionShowAll_triggered()
2275 {
2276         ShowAllObject();
2277 }
2278
2279 void FormMain::on_actionVertexBuilder_triggered()
2280 {
2281         FormVertexBuilder builder;
2282         builder.CreateVertex(m_Scene);
2283
2284         RebuildObjectList();
2285         updateView_All();
2286 }
2287
2288 void FormMain::on_actionFullScreen_triggered()
2289 {
2290         m_FullscreenPanel.ShowWidgetAsFullscreen(ui.splitter, ui.gridLayout_4);
2291 }
2292
2293 void FormMain::on_actionResetConfig_triggered()
2294 {
2295         QString msg = QString::fromLocal8Bit("\90Ý\92è\82ð\83\8a\83Z\83b\83g\82µ\82Ü\82·");
2296         if (QMessageBox::question(this, "", msg, QMessageBox::Ok|QMessageBox::Cancel) != QMessageBox::Ok)
2297                 return;
2298
2299         setGeometry(m_InitRect);
2300
2301         LoadDefaultConfig();
2302
2303         SyncViewSettingsFromGUI();
2304         SyncUVViewSettingsFromGUI();
2305         ApplyGeomStateFromGUI();
2306         SyncShaderSettingsToGUI();
2307 }
2308
2309 QString FormMain::GetFilePathFromOpenDlg(const QString& title, const QString& filter)
2310 {
2311         QString default_path = GetNextDefaultPathForFileDlg();
2312         QString s = QFileDialog::getOpenFileName(this, title, default_path, filter);
2313
2314         if (!s.isEmpty())
2315                 m_LastFileDialogDir = QFileInfo(s).absolutePath();
2316
2317         return s;
2318 }
2319
2320 QString FormMain::GetFilePathFromSaveDlg(const QString& title, const QString& filter)
2321 {
2322         QString default_path = GetNextDefaultPathForFileDlg();
2323         QString s = QFileDialog::getSaveFileName(this, title, default_path, filter);
2324
2325         if (!s.isEmpty())
2326                 m_LastFileDialogDir = QFileInfo(s).absolutePath();
2327
2328         return s;
2329 }
2330
2331 bool FormMain::IsSupportedTextureExt(const QString& path) const
2332 {
2333         QString ext = QFileInfo(path).suffix().toLower();
2334
2335         std::map<QString, bool> types;
2336         types[ "png"  ] = true;
2337         types[ "jpg"  ] = true;
2338         types[ "jepg" ] = true;
2339         types[ "bmp"  ] = true;
2340         types[ "tif"  ] = true;
2341         types[ "tiff" ] = true;
2342
2343         return types[ext];
2344 }
2345
2346 QString FormMain::GetSupportedImageFilePathFromDlg(const QString& title)
2347 {
2348         FileDlgFilterList exts;
2349         exts.Add( "Png" , "png"  );
2350         exts.Add( "Jpg" , "jpg"  );
2351         exts.Add( "Jpg" , "jpeg" );
2352         exts.Add( "Bmp" , "bmp"  );
2353         exts.Add( "Tif" , "tif"  );
2354         exts.Add( "Tif" , "tiff" );
2355
2356         QString filter = FileDlgUtil::ExtListToDlgFilter("Image", exts);
2357         return GetFilePathFromOpenDlg(title, filter);
2358 }
2359
2360
2361 QString FormMain::GetNextDefaultPathForFileDlg(void)
2362 {
2363         if (m_LastFileDialogDir.isEmpty())
2364                 return PathInfo::GetMyDocDirPath();
2365
2366         return m_LastFileDialogDir;
2367 }
2368
2369
2370 void FormMain::on_toolLoadEnvMap_clicked()
2371 {
2372         QString fileName = GetSupportedImageFilePathFromDlg("Open envmap");
2373         if (fileName.isEmpty())
2374                 return;
2375
2376         LoadEnvMap(fileName);
2377 }
2378
2379 void FormMain::LoadEnvMap(QString& path)
2380 {
2381         m_ContextShare.BeginDrawTop();
2382         m_Scene.m_EnvImg.LoadTexture(path.toLocal8Bit().data());
2383         m_ContextShare.EndDrawTop();
2384
2385         QString title = QFileInfo(path).fileName();
2386         ui.editEnvMap->setText(title);
2387
2388         updateView_All();
2389 }
2390
2391 void FormMain::on_buttonReleaseEnvImg_clicked()
2392 {
2393         m_ContextShare.BeginDrawTop();
2394         m_Scene.m_EnvImg.ClearEnv();
2395         m_ContextShare.EndDrawTop();
2396
2397         ui.editEnvMap->clear();
2398
2399         updateView_All();
2400 }
2401
2402 void FormMain::on_buttonPresetEnvMap_clicked()
2403 {
2404         if (m_EnvmapDlg == NULL)
2405         {
2406                 m_EnvmapDlg = new EnvmapSelectDlg(this);
2407                 connect(
2408                         m_EnvmapDlg,
2409                         SIGNAL(ListSelectChanged()),
2410                         this,
2411                         SLOT(EnvmapDlg_ListSelectChanged()));
2412         }
2413
2414         m_EnvmapDlg->show();
2415 }
2416
2417 void FormMain::EnvmapDlg_ListSelectChanged()
2418 {
2419         QString p = m_EnvmapDlg->GetSelectedItemPath();
2420         if (p.isEmpty())
2421                 return;
2422
2423         LoadEnvMap(p);
2424 }
2425
2426 void FormMain::on_toolLoadMatcap_clicked()
2427 {
2428         QString fileName = GetSupportedImageFilePathFromDlg("Open matcap");
2429         if (fileName.isEmpty())
2430                 return;
2431
2432         LoadMatcapImage(fileName);
2433 }
2434
2435 void FormMain::on_buttonReleaseMatcap_clicked()
2436 {
2437         m_ContextShare.BeginDrawTop();
2438         m_Scene.m_MatcapImg.ClearEnv();
2439         m_ContextShare.EndDrawTop();
2440
2441         ui.editMatcap->clear();
2442
2443         updateView_All();
2444 }
2445
2446 void FormMain::on_buttonLoadMatcapPreset_clicked()
2447 {
2448         if (m_MatcapDlg == NULL)
2449         {
2450                 m_MatcapDlg = new MatcapSelectDlg(this);
2451                 connect(
2452                         m_MatcapDlg,
2453                         SIGNAL(ListSelectChanged()),
2454                         this,
2455                         SLOT(MatcapDlg_ListSelectChanged()));
2456         }
2457
2458         m_MatcapDlg->show();
2459 }
2460
2461 void FormMain::MatcapDlg_ListSelectChanged()
2462 {
2463         QString p = m_MatcapDlg->GetSelectedItemPath();
2464         if (p.isEmpty())
2465                 return;
2466
2467         LoadMatcapImage(p);
2468 }
2469
2470 void FormMain::on_sliderEnvReflection_valueChanged(int value)
2471 {
2472         float r = GetSliderNormalizedPos(ui.sliderEnvReflection);
2473         m_Scene.m_EnvImg.m_EnvReflection = r;
2474
2475         updateView_All();
2476 }
2477
2478
2479 void FormMain::on_comboCoordinate_currentIndexChanged(int index)
2480 {
2481         SceneTransform& transform = m_Scene.m_WorldTransform;
2482
2483         int idx = ui.comboCoordinate->currentIndex();
2484         switch (idx)
2485         {
2486         case 0: transform.SetCoordType(geom::SceneTransform::COORD_RUF); break;
2487         case 1: transform.SetCoordType(geom::SceneTransform::COORD_FRU); break;
2488         case 2: transform.SetCoordType(geom::SceneTransform::COORD_UFR); break;
2489         case 3: transform.SetCoordType(geom::SceneTransform::COORD_RUB); break;
2490         case 4: transform.SetCoordType(geom::SceneTransform::COORD_BRU); break;
2491         case 5: transform.SetCoordType(geom::SceneTransform::COORD_UBR); break;
2492         default:
2493                 break;
2494         }
2495
2496         updateView_All();
2497 }
2498
2499 void FormMain::on_sliderShadowDarkness_valueChanged(int value)
2500 {
2501         int b = ui.sliderShadowDarkness->minimum();
2502         int t = ui.sliderShadowDarkness->maximum();
2503
2504         float r = (float)(value - b) / (float)(t - b);
2505         m_Scene.m_ShadowConfig.m_ShadowDarkness = r;
2506
2507         updateView_All();
2508 }
2509
2510 void FormMain::on_buttonClearAllGeoms_clicked()
2511 {
2512         ClearAllObjects();
2513 }
2514
2515 //! \83J\83\81\83\89\88Ê\92u\95\9c\8c³\8b@\94\\8eg\97p\8e\9e\82Ì\83A\83j\83\81\81[\83V\83\87\83\93\97L\96³
2516 void FormMain::on_checkCameraAnimation_toggled(bool checked)
2517 {
2518 }
2519
2520
2521 void FormMain::on_actionOpenAppdir_triggered()
2522 {
2523         PathInfo::OpenAppDir();
2524 }
2525
2526 void FormMain::on_actionOpenConfigDir_triggered()
2527 {
2528         PathInfo::OpenConfigDir();
2529 }
2530
2531 void FormMain::on_buttonDecGridAxis_clicked()
2532 {
2533         m_View3d.m_GridAxisScale /= 10.0f;
2534         updateView_3D();
2535 }
2536
2537 void FormMain::on_buttonIncGridAxis_clicked()
2538 {
2539         m_View3d.m_GridAxisScale *= 10.0f;
2540         updateView_3D();
2541 }
2542
2543 void FormMain::on_buttonResetGridAxis_clicked()
2544 {
2545         m_View3d.m_GridAxisScale = 1.0f;
2546         updateView_3D();
2547 }
2548
2549
2550 void FormMain::View3D_SelectedObjectChanged(int sel_obj, int sel_mesh)
2551 {
2552         QTreeWidgetItem* on = ui.treeObjects->topLevelItem(sel_obj);
2553
2554         if (sel_mesh == -1)
2555         {
2556                 ui.treeObjects->setCurrentItem(on);
2557         }
2558         else
2559         {
2560                 QTreeWidgetItem* mn = on->child(sel_mesh);
2561                 ui.treeObjects->setCurrentItem(mn);
2562         }
2563 }
2564
2565 void FormMain::View3D_SelectedMatChanged(int sel_idx)
2566 {
2567         ui.listMaterial->setCurrentRow(sel_idx);
2568 }
2569
2570 void FormMain::View3D_CameraMoved(void)
2571 {
2572         UpdateCameraStatus();
2573 }
2574
2575 void FormMain::View3D_StatusTipChanged(QString msg)
2576 {
2577         //ui.statusBar->showMessage(msg, 1500);
2578 }
2579
2580 void FormMain::View3D_SequenceStepped(int step)
2581 {
2582         StepSequence(step);
2583 }
2584
2585 void FormMain::View3D_CursorMoved()
2586 {
2587         Cursor3D& c = m_Scene.m_Cursor3d;
2588         QString x = QString::number(c.CursorPos.x, 'f', 4);
2589         QString y = QString::number(c.CursorPos.y, 'f', 4);
2590         QString z = QString::number(c.CursorPos.z, 'f', 4);
2591         QString s;
2592         if (x.at(0) != '-')
2593                 s += " ";
2594         s += x;
2595         if (y.at(0) != '-')
2596                 s += " ";
2597         s += " ";
2598         s += y;
2599         if (z.at(0) != '-')
2600                 s += " ";
2601         s += " ";
2602         s += z;
2603
2604         ui.editCursorPos->setText(s);
2605 }
2606
2607 void FormMain::StepSequence(int step)
2608 {
2609         QSlider* s = ui.sliderSequence;
2610         s->setValue(s->value() + step);
2611 }
2612
2613 bool FormMain::IsLastSequence(void)
2614 {
2615         QSlider* s = ui.sliderSequence;
2616         return s->value() == s->maximum();
2617 }
2618
2619 void FormMain::UpdateCameraStatus(void)
2620 {
2621         const Camera& camera = m_View3d.m_Camera;
2622         const lib_gl::CameraManipulator& manip = camera.m_Manip;
2623         const lm::vec3f& vp = manip.m_ViewPos;
2624
2625         float a, b;
2626         manip.GetViewAngles(a, b);
2627         a = a * 180.0f / M_PI;
2628         b = b * 180.0f / M_PI;
2629
2630         QString msg;
2631         msg += "(";
2632         msg += QString::number(vp.x, 'f', 2) + " ";
2633         msg += QString::number(vp.y, 'f', 2) + " ";
2634         msg += QString::number(vp.z, 'f', 2);
2635         msg += ")";
2636
2637         msg += "(";
2638         msg += QString::number(a, 'f', 2) + " ";
2639         msg += QString::number(b, 'f', 2);
2640         msg += ")";
2641
2642         msg += "(";
2643         msg += QString::number(camera.m_Projection.m_Near, 'f', 2) + " ";
2644         msg += QString::number(camera.m_Projection.m_Far, 'f', 2);
2645         msg += ")";
2646
2647         m_StatusBar1->setText(msg);
2648 }
2649
2650 void FormMain::on_actionCameraFPSMode_toggled(bool arg1)
2651 {
2652         m_View3d.m_FpsMode = arg1;
2653 }
2654
2655
2656 void FormMain::actionCursorMenuStates_Toggled(bool)
2657 {
2658         m_Binder_Cursor.UpdateAllData();
2659         updateView_3D();
2660 }
2661
2662 void FormMain::on_actionResetCursor_triggered()
2663 {
2664         m_Scene.m_Cursor3d.ResetCursorPos();
2665         m_Scene.m_Cursor3d.UpdateNormal(m_View3d.m_Camera.m_Manip.GetFront());
2666         updateView_3D();
2667 }
2668
2669 void FormMain::on_actionResetMeasure_triggered()
2670 {
2671         m_View3d.ResetCursorMeasure();
2672         updateView_3D();
2673 }
2674
2675
2676 void FormMain::on_actionPyScript_triggered()
2677 {
2678         if (m_PyScriptDlg == NULL)
2679         {
2680                 m_PyScriptDlg = new FormPyScript(this);
2681                 m_PyScriptDlg->m_Scene = &m_Scene;
2682                 m_PyScriptDlg->m_View3d = &m_View3d;
2683                 m_PyScriptDlg->m_View2d = &m_View2d;
2684         }
2685
2686         m_PyScriptDlg->showNormal();
2687         m_PyScriptDlg->show();
2688         m_PyScriptDlg->activateWindow();
2689 }
2690
2691 void FormMain::on_actionConsole_triggered()
2692 {
2693         ::AllocConsole();
2694         freopen( "CON", "r", stdin  );
2695         freopen( "CON", "w", stdout );
2696 }
2697
2698
2699 void FormMain::on_actionClearVertSelect_triggered()
2700 {
2701         m_Scene.ClearAllVertSelect();
2702         updateView_All();
2703 }
2704
2705
2706 void FormMain::on_action_About_triggered()
2707 {
2708         QGVAboutDlg dlg;
2709         dlg.exec();
2710 }
2711
2712 void FormMain::on_action_Association_triggered()
2713 {
2714         m_AssociationDlg.exec();
2715 }
2716
2717 void FormMain::on_actionLookDepth_triggered()
2718 {
2719         m_View3d.LookDepth();
2720 }
2721
2722 void FormMain::on_actionLook3DCursor_triggered()
2723 {
2724         m_View3d.Look3DCursor();
2725 }
2726
2727 void FormMain::on_sliderLightPower_valueChanged(int value)
2728 {
2729         float val = (float)ui.sliderLightPower->value();
2730         float val_max = (float)ui.sliderLightPower->maximum();
2731         float n = 2.0f * val / val_max;
2732         
2733         m_View3d.SetLightStrengthByStdRatio(n);
2734
2735         ui.labelLightPower->setText(QString("LightPower ") + QString::number(n, 'f', 2));
2736
2737         updateView_All();
2738 }
2739
2740 void FormMain::on_buttonResetLightPower_clicked()
2741 {
2742         ui.sliderLightPower->setValue(1000);
2743 }
2744
2745 void FormMain::on_checkHoleAroundCursor_clicked(bool checked)
2746 {
2747         if (checked)
2748                 ui.checkShowOnlyAroundCursor->setChecked(false);
2749
2750         if (checked)
2751                 m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::Hole;
2752         else
2753                 m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::None;
2754
2755         updateView_All();
2756 }
2757
2758 void FormMain::on_checkShowOnlyAroundCursor_toggled(bool checked)
2759 {
2760         if (checked)
2761                 ui.checkHoleAroundCursor->setChecked(false);
2762
2763         if (checked)
2764                 m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::ShowAround;
2765         else
2766                 m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::None;
2767
2768         updateView_All();
2769 }
2770
2771 void FormMain::on_sliderCursorHoleRange_valueChanged(int value)
2772 {
2773         float val = (float)ui.sliderCursorHoleRange->value();
2774         float maxval = (float)ui.sliderCursorHoleRange->maximum();
2775         float n = val / maxval;
2776
2777         m_Scene.m_Cursor3d.HoleRangeRatio = n;
2778         updateView_All();
2779 }
2780
2781 void FormMain::on_buttonResetCursorHoleRange_clicked()
2782 {
2783         ResetHoleRange();
2784 }
2785
2786 void FormMain::ResetHoleRange(void)
2787 {
2788         ui.sliderCursorHoleRange->setValue(500);
2789 }
2790
2791 void FormMain::on_actionSaveImageToMydoc_triggered()
2792 {
2793         QString path = PathInfo::GetMyDocDirPath();
2794         QString basename = path + "/" + "qgv_snap_";
2795
2796         QDateTime dt = QDateTime::currentDateTime();
2797
2798         QString dst;
2799         for(;;)
2800         {
2801                 QString tp = dt.toString("yyyyMMdd_hhmmss_zzz");
2802                 dst = basename + tp + ".png";
2803                 if (!QFile(dst).exists())
2804                         break;
2805         }
2806
2807         ui.GLWidgetMain->grabFrameBuffer().save(dst);
2808 }
2809
2810 void FormMain::on_actionPostProcNone_triggered()
2811 {
2812         ChangePostprocMode(PostProcType::None);
2813 }
2814
2815 void FormMain::on_actionPostProcAntialias_triggered()
2816 {
2817         ChangePostprocMode(PostProcType::Antialias);
2818 }
2819
2820 void FormMain::on_actionPostProcBorder_triggered()
2821 {
2822         ChangePostprocMode(PostProcType::Border);
2823 }
2824
2825 void FormMain::on_actionPostProcDepthLayerColor_triggered()
2826 {
2827         ChangePostprocMode(PostProcType::DepthLayerColor);
2828 }
2829
2830 void FormMain::on_actionPostProcDepthColor_triggered()
2831 {
2832         ChangePostprocMode(PostProcType::DepthColor);
2833 }
2834
2835 void FormMain::on_actionPostProcDepthOfField_triggered()
2836 {
2837         ChangePostprocMode(PostProcType::DepthOfField);
2838 }
2839
2840 void FormMain::ChangePostprocMode(PostProcType type)
2841 {
2842         m_View3d.m_Config.m_PPMode = type;
2843         updateView_3D();
2844 }
2845
2846 void FormMain::on_sliderDOFPint_valueChanged(int value)
2847 {
2848         float n = GetSliderNormalizedPos(ui.sliderDOFPint);
2849         m_View3d.m_PPContext.m_DOFPintPos = n;
2850
2851         updateView_3D();
2852 }
2853
2854 void FormMain::on_sliderDOFRange_valueChanged(int value)
2855 {
2856         float n = GetSliderNormalizedPos(ui.sliderDOFRange);
2857         m_View3d.m_PPContext.m_DOFRange = 10.0f * n;
2858
2859         updateView_3D();
2860 }
2861
2862 float FormMain::GetSliderNormalizedPos(const QSlider* slider) const
2863 {
2864         float t = (float)slider->maximum();
2865         float b = (float)slider->minimum();
2866         float v = (float)slider->value();
2867
2868         return (v - b) / (t - b);
2869 }
2870
2871 void FormMain::on_buttonResetDOFPint_clicked()
2872 {
2873         ui.sliderDOFPint->setValue(1000);
2874 }
2875
2876 void FormMain::on_buttonResetDOFRange_clicked()
2877 {
2878         ui.sliderDOFRange->setValue(1000);
2879 }
2880
2881 void FormMain::on_actionAddCrossSectionRecord_triggered()
2882 {
2883         m_Scene.AddCrossSectionRecord();
2884         updateView_All();
2885 }
2886
2887 void FormMain::on_actionClearCrossSectionRecord_triggered()
2888 {
2889         m_Scene.ClearCrossSectionRecord();
2890         updateView_All();
2891 }
2892
2893 void FormMain::LoadCurSelMatTexture(TextureType type)
2894 {
2895         QString path = GetSupportedImageFilePathFromDlg("Load Texture");
2896         if (path.isEmpty())
2897                 return;
2898
2899         LoadCurSelMatTexture(type, path);
2900 }
2901
2902 void FormMain::LoadCurSelMatTexture(TextureType type, QString filepath)
2903 {
2904         GeomTextureSet* ts = m_Scene.GetSelectedTexture();
2905         if (ts == NULL)
2906                 return;
2907
2908         MeshBuf* mbuf = ts->GetParent();
2909         std::string fp = filepath.toLocal8Bit().data();
2910
2911         QString name_qs = QFileInfo(filepath).fileName();
2912         std::string name = name_qs.toLocal8Bit().data();
2913
2914         m_ContextShare.BeginDrawTop();
2915
2916         mbuf->ReleaseTextureUnit(ts, type);
2917         gl::GlTexture* tex = mbuf->GetInitTexture(fp, name, m_Scene.m_TexConfig);
2918         ts->SetTextureUnit(type, tex);
2919
2920         if (type == TextureType::Normal)
2921                 m_View3d.ReleaseAllRenderBuffer();
2922
2923         m_ContextShare.EndDrawTop();
2924
2925         OnChangedSelectedMaterial();
2926         updateView_All();
2927 }
2928
2929 void FormMain::ReleaseCurSelTexture(TextureType type)
2930 {
2931         MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
2932         if (mbuf == NULL)
2933                 return;
2934
2935         int mat_idx = m_Scene.m_Sels.GetSelMat();
2936
2937         m_ContextShare.BeginDrawTop();
2938         mbuf->ReleaseTextureUnit(mat_idx, type);
2939         m_ContextShare.EndDrawTop();
2940
2941         OnChangedSelectedMaterial();
2942         updateView_All();
2943 }
2944
2945 void FormMain::LoadMatcapImageForCurrentMat(QString& path)
2946 {
2947         GeomTextureSet* ts = m_Scene.GetSelectedTexture();
2948
2949         QString title = QFileInfo(path).fileName();
2950
2951         m_ContextShare.BeginDrawTop();
2952         ts->TexMatcap.LoadTexture(path.toLocal8Bit().data());
2953         ts->TexMatcap.SetName(title);
2954         m_ContextShare.EndDrawTop();
2955
2956         OnChangedSelectedMaterial();
2957         updateView_All();
2958 }
2959
2960 void FormMain::LoadMatcapImage(QString& path)
2961 {
2962         MatcapImage& mc = m_Scene.m_MatcapImg;
2963
2964         QString title = QFileInfo(path).fileName();
2965
2966         ui.editMatcap->setText(mc.GetName());
2967
2968         m_ContextShare.BeginDrawTop();
2969         mc.LoadTexture(path.toLocal8Bit().data());
2970         mc.SetName(title);
2971         m_ContextShare.EndDrawTop();
2972
2973         updateView_All();
2974 }
2975
2976 void FormMain::on_buttonOpenMatCapEachMaterial_clicked()
2977 {
2978         QString path = GetSupportedImageFilePathFromDlg("Load Texture");
2979         if (path.isEmpty())
2980                 return;
2981
2982         LoadMatcapImage(path);
2983 }
2984
2985 void FormMain::on_buttonClearMatCapEachMaterial_clicked()
2986 {
2987         geom::GeomTextureSet* tex = m_Scene.GetSelectedTexture();
2988         if (tex == NULL)
2989                 return;
2990
2991         m_ContextShare.BeginDrawTop();
2992         tex->TexMatcap.ClearEnv();
2993         m_ContextShare.EndDrawTop();
2994
2995         ui.editMatCapEachMaterial->clear();
2996
2997         updateView_All();
2998 }
2999
3000 void FormMain::on_buttonOpenCurrentMatColorMap_clicked()
3001 {
3002         LoadCurSelMatTexture(TextureType::Color);
3003 }
3004
3005 void FormMain::on_buttonClearCurrentMatColorMap_clicked()
3006 {
3007         ReleaseCurSelTexture(TextureType::Color);
3008 }
3009
3010 void FormMain::on_buttonOpenCurrentMatNormalMap_clicked()
3011 {
3012         LoadCurSelMatTexture(TextureType::Normal);
3013 }
3014
3015 void FormMain::on_buttonClearCurrentMatNormalMap_clicked()
3016 {
3017         ReleaseCurSelTexture(TextureType::Normal);
3018 }
3019
3020 void FormMain::ChangeMatlemColor(QWidget* col_widget)
3021 {
3022         lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
3023         if (mat == NULL)
3024                 return;
3025
3026         lib_graph::color4f* col;
3027
3028         if (col_widget == ui.colorAmbient  ) col = &mat->m_Ambient  ;
3029         if (col_widget == ui.colorEmission ) col = &mat->m_Emission ;
3030         if (col_widget == ui.colorDiffuse  ) col = &mat->m_Diffuse  ;
3031         if (col_widget == ui.colorSpecular ) col = &mat->m_Specular ;
3032
3033         lib_graph::color4f src = *col;
3034
3035         QColor dc = ToQColor(*col);
3036
3037         m_SelMatColorWidget = col_widget;
3038
3039         m_SelMatColorSelDlg.setOption(QColorDialog::ShowAlphaChannel);
3040         m_SelMatColorSelDlg.setCurrentColor(dc);
3041         if (m_SelMatColorSelDlg.exec() == QDialog::Rejected)
3042         {
3043                 *col = src;
3044                 SetWidgetColor(col_widget, dc);
3045         }
3046 }
3047
3048 void FormMain::on_buttonDiffuse_clicked()
3049 {
3050         ChangeMatlemColor(ui.colorDiffuse);
3051 }
3052
3053 void FormMain::on_buttonAmbient_clicked()
3054 {
3055         ChangeMatlemColor(ui.colorAmbient);
3056 }
3057
3058 void FormMain::on_buttonEmission_clicked()
3059 {
3060         ChangeMatlemColor(ui.colorEmission);
3061 }
3062
3063 void FormMain::on_buttonSpecular_clicked()
3064 {
3065         ChangeMatlemColor(ui.colorSpecular);
3066 }
3067
3068 void FormMain::SetWidgetColor(QWidget* w, QColor col)
3069 {
3070         QString ss = QString("background-color: %1").arg(col.name());
3071         w->setStyleSheet(ss);
3072 }
3073
3074 void FormMain::on_sliderShininess_valueChanged(int value)
3075 {
3076         lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
3077         if (mat == NULL)
3078                 return;
3079
3080         float val = (float)ui.sliderShininess->value();
3081         float val_max = (float)ui.sliderShininess->maximum();
3082
3083         float real_val = 200.0f * val / val_max;
3084
3085         mat->m_Shininess = real_val;
3086
3087         ui.labelShininessVal->setText(QString::number(real_val, 'f', 2));
3088
3089         updateView_All();
3090 }
3091
3092 void FormMain::CreateRecentFilesMenu(const std::vector<QString>& path)
3093 {
3094         QMenu* recents = ui.menuOpenRecent;
3095         recents->actions().clear();
3096
3097         for (size_t i = 0; i < path.size(); ++i)
3098         {
3099                 AddRecentFile(path[path.size() - i - 1]);
3100         }
3101 }
3102
3103 void FormMain::CreateRecentFilesFromMenu(std::vector<QString>& path)
3104 {
3105         QMenu* recents = ui.menuOpenRecent;
3106         for (int i = 0; i < recents->actions().size(); ++i)
3107         {
3108                 QAction* a = recents->actions().at(i);
3109                 path.push_back(a->text());
3110         }
3111 }
3112
3113 void FormMain::AddRecentFile(const QString& path)
3114 {
3115         QString path_local = QDir::toNativeSeparators(path);
3116
3117         static const int max_files = 10;
3118
3119         QMenu* recents = ui.menuOpenRecent;
3120
3121         for (int i = 0; i < recents->actions().size(); ++i)
3122         {
3123                 QAction* a = recents->actions().at(i);
3124                 if (a->text() == path_local)
3125                 {
3126                         recents->removeAction(a);
3127                         break;
3128                 }
3129         }
3130
3131         QAction* new_path = new QAction(path_local, this);
3132         connect(
3133                 new_path,
3134                 SIGNAL(triggered()),
3135                 this,
3136                 SLOT(OnOpenRecent()));
3137
3138         if (recents->actions().empty())
3139                 recents->addAction(new_path);
3140         else
3141                 recents->insertAction(recents->actions().front(), new_path);
3142
3143         if (recents->actions().size() > max_files)
3144         {
3145                 QAction* a = recents->actions().back();
3146                 recents->removeAction(a);
3147         }
3148 }
3149
3150 void FormMain::OnOpenRecent()
3151 {
3152         QAction* a = dynamic_cast<QAction*>(QObject::sender());
3153         assert(a != NULL);
3154         if (a == NULL)
3155                 return;
3156
3157         QString path = a->text();
3158
3159         if (IsResetSceneOnBeforeLoadFile())
3160                 ClearAllObjects();
3161
3162         if (OpenGeomFile(path))
3163                 return;
3164 }
3165
3166 void FormMain::on_checkShowOnlySelect_toggled(bool checked)
3167 {
3168         m_View3d.m_Config.m_ShowOnlySelect = checked;
3169         updateView_All();
3170 }
3171
3172 void FormMain::ResizeTreeColumns(QTreeWidget* t, int num_col)
3173 {
3174         t->setVisible(false);
3175         t->resizeColumnToContents(0);
3176         t->resizeColumnToContents(1);
3177         t->resizeColumnToContents(2);
3178         t->resizeColumnToContents(3);
3179         t->setVisible(true);
3180 }
3181
3182 void FormMain::PushbackTreeNode(QTreeWidget* tree, QTreeWidgetItem *node)
3183 {
3184         int next_idx = tree->topLevelItemCount();
3185         tree->insertTopLevelItem(next_idx, node);
3186 }
3187
3188 QTreeWidgetItem* FormMain::CreateObjectTreeNode(const geom::GeomObject& obj) const
3189 {
3190         QTreeWidgetItem* n = new QTreeWidgetItem;
3191
3192         n->setText(0, QString::fromLocal8Bit(obj.m_Name.c_str()));
3193         n->setCheckState(1, obj.m_Visible ? Qt::Checked : Qt::Unchecked);
3194         n->setText(2, QString::number(obj.GetNumTotalVerts()));
3195         n->setText(3, QString::number(obj.GetNumTotalFaces()));
3196
3197         int idx = 0;
3198         for (const MeshBuf& mbuf : obj.m_MeshAry)
3199         {
3200                 n->addChild(CreateMeshBufNode(obj, mbuf, idx++));
3201         }
3202
3203         n->setExpanded(true);
3204
3205         return n;
3206 }
3207
3208 QTreeWidgetItem* FormMain::CreateMeshBufNode(const geom::GeomObject& obj, const MeshBuf& mbuf, int idx) const
3209 {
3210         QTreeWidgetItem* n = new QTreeWidgetItem;
3211
3212         QString name;
3213         if (mbuf.m_Name.empty())
3214                 name = QString::fromLocal8Bit(obj.m_Name.c_str()) + QString::number(idx);
3215         else
3216                 name = QString::fromLocal8Bit(mbuf.m_Name.c_str());
3217
3218         n->setText(0, name);
3219         n->setCheckState(1, mbuf.m_Visible ? Qt::Checked : Qt::Unchecked);
3220         n->setText(2, QString::number(mbuf.GetNumVerts()));
3221         n->setText(3, QString::number(mbuf.GetNumFaces()));
3222
3223         return n;
3224 }
3225
3226 void FormMain::InitObjectListHeader(void)
3227 {
3228         QStringList qs;
3229         qs << "Name" << "Visible" << "Verts" << "Faces";
3230         ui.treeObjects->setHeaderLabels(qs);
3231 }
3232
3233 void FormMain::SetPrimayrSelectObjectFromScene(void)
3234 {
3235         QTreeWidget* obj_tree = ui.treeObjects;
3236
3237         Selection3D& sels = m_Scene.m_Sels;
3238         if (!sels.IsObjectSelected())
3239                 return;
3240
3241         int sel_idx = sels.GetSelObjectIdx();
3242
3243         QTreeWidgetItem* on = obj_tree->topLevelItem(sel_idx);
3244         if (on == NULL)
3245                 return;
3246
3247         if (sels.IsMBufSelected())
3248         {
3249                 QTreeWidgetItem* mn = on->child(sels.GetMBufIdx());
3250                 obj_tree->setCurrentItem(mn);
3251         }
3252         else
3253         {
3254                 obj_tree->setCurrentItem(on);
3255         }
3256 }
3257
3258 void FormMain::SetPrimayrSelectObjectToScene(void)
3259 {
3260         Selection3D& sels = m_Scene.m_Sels;
3261
3262         QTreeWidget* tree = ui.treeObjects;
3263
3264         QTreeWidgetItem* sel_node = tree->currentItem();
3265         if (sel_node == NULL)
3266                 return;
3267
3268         QTreeWidgetItem* on = sel_node->parent();
3269         if (on == NULL)
3270         {
3271                 int obj_idx = tree->indexOfTopLevelItem(sel_node);
3272                 sels.SelectObject(obj_idx);
3273         }
3274         else
3275         {
3276                 int obj_idx = tree->indexOfTopLevelItem(on);
3277                 int mb_idx = on->indexOfChild(sel_node);
3278                 sels.SelectMBuf(obj_idx, mb_idx);
3279         }
3280 }
3281
3282 void FormMain::on_actionReleaseShader_triggered()
3283 {
3284         m_ContextShare.BeginDrawTop();
3285
3286         m_View3d.m_ShaderLib.ReleaseAllShaders();
3287
3288         m_ContextShare.EndDrawTop();
3289 }
3290
3291 void FormMain::on_combo2DViewSrcType_currentIndexChanged(int index)
3292 {
3293         switch (index)
3294         {
3295         case 0 : return m_View2d.ChangeTextureSource(View2DTexSrc::Color);
3296         case 1 : return m_View2d.ChangeTextureSource(View2DTexSrc::Normal);
3297         default:
3298                 assert(false);
3299                 break;
3300         }
3301 }
3302
3303 void FormMain::on_sliderSequence_valueChanged(int value)
3304 {
3305         UpdateSequence();
3306 }
3307
3308 void FormMain::ResetSequenceSliderRange(void)
3309 {
3310         int m = m_Scene.GetKeyframeMax();
3311         ui.sliderSequence->setMaximum(m);
3312         UpdateSequence();
3313 }
3314
3315 void FormMain::UpdateSequence(void)
3316 {
3317         int v = ui.sliderSequence->value();
3318         int m = ui.sliderSequence->maximum();
3319
3320         QString s = QString("%1 / %2").arg(v).arg(m);
3321         ui.labelSequencePos->setText(s);
3322
3323         m_Scene.SetFrame(v);
3324
3325         m_View3d.ReleaseAllRenderBuffer();
3326         updateView_All();
3327 }
3328
3329 void FormMain::on_actionNewStroke_triggered()
3330 {
3331
3332 }
3333
3334 void FormMain::on_actionClearStroke_triggered()
3335 {
3336 }