chiark / gitweb /
Fix bug where fullscreen on mac caused problems with the progress panels being below...
[cura.git] / Cura / gui / simpleMode.py
1 from __future__ import absolute_import
2 import __init__
3
4 import wx, os, platform, types, webbrowser
5
6 from gui import configBase
7 from gui import preview3d
8 from gui import sliceProgessPanel
9 from gui import preferencesDialog
10 from gui import configWizard
11 from gui import firmwareInstall
12 from gui import dropTarget
13 from gui import printWindow
14 from gui import icon
15 from util import validators
16 from util import profile
17 from util import version
18 from util import sliceRun
19 from util import meshLoader
20
21 class simpleModeWindow(configBase.configWindowBase):
22         "Main user interface window for Quickprint mode"
23         def __init__(self):
24                 super(simpleModeWindow, self).__init__(title='Cura - Quickprint - ' + version.getVersion())
25                 
26                 wx.EVT_CLOSE(self, self.OnClose)
27                 #self.SetIcon(icon.getMainIcon())
28
29                 self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.supportedExtensions()))
30                 
31                 menubar = wx.MenuBar()
32                 fileMenu = wx.Menu()
33                 i = fileMenu.Append(-1, 'Load model file...')
34                 self.Bind(wx.EVT_MENU, self.OnLoadModel, i)
35                 fileMenu.AppendSeparator()
36                 i = fileMenu.Append(-1, 'Preferences...')
37                 self.Bind(wx.EVT_MENU, self.OnPreferences, i)
38                 fileMenu.AppendSeparator()
39                 i = fileMenu.Append(wx.ID_EXIT, 'Quit')
40                 self.Bind(wx.EVT_MENU, self.OnQuit, i)
41                 menubar.Append(fileMenu, '&File')
42                 
43                 toolsMenu = wx.Menu()
44                 i = toolsMenu.Append(-1, 'Switch to Normal mode...')
45                 self.Bind(wx.EVT_MENU, self.OnNormalSwitch, i)
46                 menubar.Append(toolsMenu, 'Normal mode')
47                 
48                 helpMenu = wx.Menu()
49                 i = helpMenu.Append(-1, 'Online documentation...')
50                 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://daid.github.com/Cura'), i)
51                 i = helpMenu.Append(-1, 'Report a problem...')
52                 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/issues'), i)
53                 menubar.Append(helpMenu, 'Help')
54                 self.SetMenuBar(menubar)
55                 
56                 if profile.getPreference('lastFile') != '':
57                         self.filelist = profile.getPreference('lastFile').split(';')
58                         self.SetTitle(self.filelist[-1] + ' - Cura - ' + version.getVersion())
59                 else:
60                         self.filelist = []
61                 self.progressPanelList = []
62
63                 #Preview window
64                 self.preview3d = preview3d.previewPanel(self)
65
66                 configPanel = wx.Panel(self)
67                 printTypePanel = wx.Panel(configPanel)
68                 self.printTypeNormal = wx.RadioButton(printTypePanel, -1, 'Normal quality print', style=wx.RB_GROUP)
69                 self.printTypeLow = wx.RadioButton(printTypePanel, -1, 'Fast low quality print')
70                 self.printTypeHigh = wx.RadioButton(printTypePanel, -1, 'High quality print')
71                 self.printTypeJoris = wx.RadioButton(printTypePanel, -1, 'Thin walled cup or vase')
72
73                 printMaterialPanel = wx.Panel(configPanel)
74                 self.printMaterialPLA = wx.RadioButton(printMaterialPanel, -1, 'PLA', style=wx.RB_GROUP)
75                 self.printMaterialABS = wx.RadioButton(printMaterialPanel, -1, 'ABS')
76                 self.printMaterialDiameter = wx.TextCtrl(printMaterialPanel, -1, profile.getProfileSetting('filament_diameter'))
77                 
78                 self.printSupport = wx.CheckBox(configPanel, -1, 'Print support structure')
79                 
80                 sizer = wx.GridBagSizer()
81                 configPanel.SetSizer(sizer)
82
83                 sb = wx.StaticBox(printTypePanel, label="Select a print type:")
84                 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
85                 boxsizer.Add(self.printTypeNormal)
86                 boxsizer.Add(self.printTypeLow)
87                 boxsizer.Add(self.printTypeHigh)
88                 boxsizer.Add(self.printTypeJoris)
89                 printTypePanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
90                 printTypePanel.GetSizer().Add(boxsizer, flag=wx.EXPAND)
91                 sizer.Add(printTypePanel, (0,0), flag=wx.EXPAND)
92
93                 sb = wx.StaticBox(printMaterialPanel, label="Material:")
94                 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
95                 boxsizer.Add(self.printMaterialPLA)
96                 boxsizer.Add(self.printMaterialABS)
97                 boxsizer.Add(wx.StaticText(printMaterialPanel, -1, 'Diameter:'))
98                 boxsizer.Add(self.printMaterialDiameter)
99                 printMaterialPanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
100                 printMaterialPanel.GetSizer().Add(boxsizer, flag=wx.EXPAND)
101                 sizer.Add(printMaterialPanel, (1,0), flag=wx.EXPAND)
102
103                 sb = wx.StaticBox(configPanel, label="Other:")
104                 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
105                 boxsizer.Add(self.printSupport)
106                 sizer.Add(boxsizer, (2,0), flag=wx.EXPAND)
107
108                 # load and slice buttons.
109                 loadButton = wx.Button(self, -1, 'Load Model')
110                 sliceButton = wx.Button(self, -1, 'Prepare print')
111                 printButton = wx.Button(self, -1, 'Print')
112                 self.Bind(wx.EVT_BUTTON, self.OnLoadModel, loadButton)
113                 self.Bind(wx.EVT_BUTTON, self.OnSlice, sliceButton)
114                 self.Bind(wx.EVT_BUTTON, self.OnPrint, printButton)
115                 #Also bind double clicking the 3D preview to load an STL file.
116                 self.preview3d.glCanvas.Bind(wx.EVT_LEFT_DCLICK, self.OnLoadModel, self.preview3d.glCanvas)
117
118                 #Main sizer, to position the preview window, buttons and tab control
119                 sizer = wx.GridBagSizer()
120                 self.SetSizer(sizer)
121                 sizer.Add(configPanel, (0,0), span=(1,1), flag=wx.EXPAND)
122                 sizer.Add(self.preview3d, (0,1), span=(1,3), flag=wx.EXPAND)
123                 sizer.AddGrowableCol(2)
124                 sizer.AddGrowableRow(0)
125                 sizer.Add(loadButton, (1,1), flag=wx.RIGHT|wx.BOTTOM|wx.TOP, border=5)
126                 sizer.Add(sliceButton, (1,2), flag=wx.RIGHT|wx.BOTTOM|wx.TOP, border=5)
127                 sizer.Add(printButton, (1,3), flag=wx.RIGHT|wx.BOTTOM|wx.TOP, border=5)
128                 self.sizer = sizer
129
130                 if len(self.filelist) > 0:
131                         self.preview3d.loadModelFiles(self.filelist)
132
133                 self.SetBackgroundColour(configPanel.GetBackgroundColour())
134
135                 self.updateProfileToControls()
136
137                 self.printTypeNormal.SetValue(True)
138                 self.printMaterialPLA.SetValue(True)
139
140                 self.Fit()
141                 self.preview3d.Fit()
142                 self.SetMinSize(self.GetSize())
143                 self.Centre()
144                 self.Show(True)
145         
146         def OnPreferences(self, e):
147                 prefDialog = preferencesDialog.preferencesDialog(self)
148                 prefDialog.Centre()
149                 prefDialog.Show(True)
150
151         def OnLoadModel(self, e):
152                 dlg=wx.FileDialog(self, "Open file to print", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
153                 dlg.SetWildcard(meshLoader.wildcardFilter())
154                 if dlg.ShowModal() == wx.ID_OK:
155                         self.filelist = [dlg.GetPath()]
156                         profile.putPreference('lastFile', ';'.join(self.filelist))
157                         self.preview3d.loadModelFiles(self.filelist, True)
158                         self.preview3d.setViewMode("Normal")
159                 dlg.Destroy()
160
161         def OnDropFiles(self, filenames):
162                 self.filelist = filenames
163                 profile.putPreference('lastFile', ';'.join(self.filelist))
164                 self.preview3d.loadModelFiles(self.filelist, True)
165                 self.preview3d.setViewMode("Normal")
166         
167         def OnSlice(self, e):
168                 if len(self.filelist) < 1:
169                         wx.MessageBox('You need to load a file before you can prepare it.', 'Print error', wx.OK | wx.ICON_INFORMATION)
170                         return
171                 #save the current profile so we can put it back latter
172                 oldProfile = profile.getGlobalProfileString()
173                 
174                 put = profile.putProfileSetting
175                 get = profile.getProfileSetting
176
177                 put('layer_height', '0.2')
178                 put('wall_thickness', '0.8')
179                 put('solid_layer_thickness', '0.6')
180                 put('fill_density', '20')
181                 put('skirt_line_count', '1')
182                 put('skirt_gap', '6.0')
183                 put('print_speed', '50')
184                 put('print_temperature', '220')
185                 put('support', 'None')
186                 #put('machine_center_x', '100')
187                 #put('machine_center_y', '100')
188                 put('retraction_enable', 'False')
189                 put('retraction_min_travel', '5.0')
190                 put('retraction_speed', '40.0')
191                 put('retraction_amount', '4.5')
192                 put('retraction_extra', '0.0')
193                 put('travel_speed', '150')
194                 put('max_z_speed', '3.0')
195                 put('bottom_layer_speed', '25')
196                 put('cool_min_layer_time', '10')
197                 put('fan_enabled', 'True')
198                 put('fan_layer', '1')
199                 put('fan_speed', '100')
200                 #put('model_scale', '1.0')
201                 #put('flip_x', 'False')
202                 #put('flip_y', 'False')
203                 #put('flip_z', 'False')
204                 #put('model_rotate_base', '0')
205                 #put('model_multiply_x', '1')
206                 #put('model_multiply_y', '1')
207                 put('extra_base_wall_thickness', '0.0')
208                 put('sequence', 'Loops > Perimeter > Infill')
209                 put('force_first_layer_sequence', 'True')
210                 put('infill_type', 'Line')
211                 put('solid_top', 'True')
212                 put('fill_overlap', '15')
213                 put('support_rate', '50')
214                 put('support_distance', '0.5')
215                 put('joris', 'False')
216                 put('cool_min_feedrate', '5')
217                 put('bridge_speed', '100')
218                 put('raft_margin', '5')
219                 put('raft_base_material_amount', '100')
220                 put('raft_interface_material_amount', '100')
221                 put('bottom_thickness', '0.0')
222
223                 if self.printSupport.GetValue():
224                         put('support', 'Exterior Only')
225
226                 nozzle_size = float(get('nozzle_size'))
227                 if self.printTypeNormal.GetValue():
228                         put('wall_thickness', nozzle_size * 2.0)
229                         put('layer_height', '0.2')
230                         put('fill_density', '20')
231                 elif self.printTypeLow.GetValue():
232                         put('wall_thickness', nozzle_size * 1.4)
233                         put('layer_height', '0.25')
234                         put('fill_density', '10')
235                         put('print_speed', '80')
236                         put('cool_min_layer_time', '3')
237                         put('bottom_layer_speed', '40')
238                 elif self.printTypeHigh.GetValue():
239                         put('wall_thickness', nozzle_size * 2.0)
240                         put('layer_height', '0.1')
241                         put('fill_density', '30')
242                         put('bottom_layer_speed', '15')
243                         put('bottom_thickness', '0.2')
244                 elif self.printTypeJoris.GetValue():
245                         put('wall_thickness', nozzle_size * 1.5)
246                         put('layer_height', '0.3')
247                         put('solid_layer_thickness', '0.9')
248                         put('fill_density', '0')
249                         put('joris', 'True')
250                         put('extra_base_wall_thickness', '15.0')
251                         put('sequence', 'Infill > Loops > Perimeter')
252                         put('force_first_layer_sequence', 'False')
253                         put('solid_top', 'False')
254                         put('support', 'None')
255                         put('cool_min_layer_time', '3')
256
257                 put('filament_diameter', self.printMaterialDiameter.GetValue())
258                 if self.printMaterialPLA.GetValue():
259                         put('filament_density', '1.00')
260                         put('enable_raft', 'False')
261                         put('skirt_line_count', '1')
262                 if self.printMaterialABS.GetValue():
263                         put('filament_density', '0.85')
264                         put('enable_raft', 'True')
265                         put('skirt_line_count', '0')
266                         put('fan_layer', '1')
267                         put('bottom_thickness', '0.0')
268                         put('print_temperature', '260')
269                 
270                 #Create a progress panel and add it to the window. The progress panel will start the Skein operation.
271                 spp = sliceProgessPanel.sliceProgessPanel(self, self, self.filelist)
272                 self.sizer.Add(spp, (len(self.progressPanelList)+2,0), span=(1,4), flag=wx.EXPAND)
273                 self.sizer.Layout()
274                 newSize = self.GetSize();
275                 newSize.IncBy(0, spp.GetSize().GetHeight())
276                 if newSize.GetWidth() < wx.GetDisplaySize()[0]:
277                         self.SetSize(newSize)
278                 self.progressPanelList.append(spp)
279                 
280                 #Restore the old profile.
281                 profile.loadGlobalProfileFromString(oldProfile)
282         
283         def OnPrint(self, e):
284                 if len(self.filelist) < 1:
285                         wx.MessageBox('You need to load a file and prepare it before you can print.', 'Print error', wx.OK | wx.ICON_INFORMATION)
286                         return
287                 if not os.path.exists(sliceRun.getExportFilename(self.filelist[0])):
288                         wx.MessageBox('You need to prepare the file before you can print.', 'Print error', wx.OK | wx.ICON_INFORMATION)
289                         return
290                 printWindow.printFile(sliceRun.getExportFilename(self.filelist[0]))
291
292         def OnNormalSwitch(self, e):
293                 from gui import mainWindow
294                 profile.putPreference('startMode', 'Normal')
295                 mainWindow.mainWindow()
296                 self.Close()
297
298         def removeSliceProgress(self, spp):
299                 self.progressPanelList.remove(spp)
300                 newSize = self.GetSize();
301                 newSize.IncBy(0, -spp.GetSize().GetHeight())
302                 if newSize.GetWidth() < wx.GetDisplaySize()[0]:
303                         self.SetSize(newSize)
304                 spp.Show(False)
305                 self.sizer.Detach(spp)
306                 for spp in self.progressPanelList:
307                         self.sizer.Detach(spp)
308                 i = 2
309                 for spp in self.progressPanelList:
310                         self.sizer.Add(spp, (i,0), span=(1,4), flag=wx.EXPAND)
311                         i += 1
312                 self.sizer.Layout()
313
314         def OnQuit(self, e):
315                 self.Close()
316         
317         def OnClose(self, e):
318                 self.Destroy()
319
320         def updateProfileToControls(self):
321                 super(simpleModeWindow, self).updateProfileToControls()
322                 self.preview3d.updateProfileToControls()
323