ADG Lua 

ADG Lua Git Source Tree

Root/adg-demo.lua.in

1--[[
2
3This file is part of adg-lua.
4Copyright (C) 2012-2013 Nicola Fontana <ntd at entidi.it>
5
6adg-lua is free software; you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as
8published by the Free Software Foundation; either version 2 of
9the License, or (at your option) any later version.
10
11adg-lua is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General
17Public License along with adg-lua; if not, write to the Free
18Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19Boston, MA 02110-1301, USA.
20
21]]
22
23
24-- Path where the ADG library is installed: used for accessing
25-- shared resources such as icons and GtkBuilder XML files.
26local adg_data_dir = '@ADGDATADIR@'
27
28-- This hack checks if ADGDATADIR has been expanded by
29-- configure and provides a fallback otherwise. It allows to
30-- directly run adg-demo.lua.in if ADG is installed in the
31-- /usr prefix (as it happens to be on my system ;).
32if adg_data_dir == '@ADGDATADIR' .. '@' then
33 adg_data_dir = '/usr/share/adg'
34end
35
36
37local lgi = require 'lgi'
38local GLib = lgi.require 'GLib'
39local Gtk = lgi.require 'Gtk'
40local Adg = lgi.require 'Adg'
41local Piston = require 'piston'
42
43
44-- Command line parsing
45
46if arg[1] == '--version' or arg[1] == '-V' then
47 print('adg-demo @VERSION@')
48 return 0
49elseif arg[1] == '--help' or arg[1] == '-h' then
50 print([[
51Usage:
52 ]] .. arg[0] .. [[ [OPTION...] - ADG demonstration program
53
54 -h, --help Show help options
55 -V, --version Display version information
56 -E, --show-extents Show the boundary boxes of every entity
57]])
58 return 0
59elseif arg[1] == '--show-extents' or arg[1] == '-E' then
60 Adg.switch_extents(true)
61elseif arg[1] then
62 error('Invalid argument (' .. arg[1] .. ')')
63 return 1
64end
65
66
67-- User interface initialization
68
69Adg.gtk_use_default_icons(adg_data_dir)
70
71
72-- Customize error handler
73
74error = function (message)
75 local dialog = Gtk.MessageDialog {
76message_type = Gtk.MessageType.ERROR,
77buttons = Gtk.ButtonsType.CLOSE,
78text = message,
79title = 'Error from adg-demo',
80 }
81 dialog:run()
82 dialog:destroy()
83end
84
85
86-- Part definition
87
88local piston = Piston.new {
89 A = 55,
90 B = 20.6,
91 C = 2,
92 DHOLE = 2,
93 LHOLE = 3,
94 D1 = 9.3,
95 D2 = 6.5,
96 D3 = 13.8,
97 D4 = 6.5,
98 D5 = 4.5,
99 D6 = 7.2,
100 D7 = 2,
101 RD34 = 1,
102 RD56 = 0.2,
103 LD2 = 7,
104 LD3 = 3.5,
105 LD5 = 5,
106 LD6 = 1,
107 LD7 = 0.5,
108 GROOVE = false,
109 ZGROOVE = 16,
110 DGROOVE = 8.3,
111 LGROOVE = 1,
112 CHAMFER = 0.3,
113
114 -- Metadata
115 TITLE = 'SAMPLE DRAWING',
116 DRAWING = 'PISTON',
117 AUTHOR = 'adg-demo',
118 DATE = os.date('%d/%m/%Y'),
119}
120
121
122-- GtkBuilder initialization
123
124local builder = Gtk.Builder()
125builder:add_from_file(adg_data_dir .. '/adg-demo.ui')
126local ui = builder.objects
127
128
129-- Canvas settings
130
131local canvas = piston.view.detailed
132canvas:set_paper('iso_a4', Gtk.PageOrientation.LANDSCAPE)
133canvas:autoscale()
134
135local area = ui.mainCanvas
136area:set_canvas(canvas)
137area.on_button_press_event = function (area, event)
138 if event.button == 1 then
139 -- Restore the original zoom
140 area:reset()
141 elseif event.button == 3 then
142 canvas:autoscale()
143 area:queue_draw()
144 end
145
146 return FALSE;
147end
148
149
150-- Help dialog
151
152ui.mainHelp.on_clicked = function ()
153 local dialog = ui.wndHelp
154 dialog.on_response = Gtk.Widget.hide
155 dialog:run()
156end
157
158
159-- About dialog
160
161ui.mainAbout.on_clicked = function ()
162 local dialog = ui.wndAbout
163 local icon_list = Gtk.Window.get_default_icon_list()
164
165 -- The last icon is supposed to be the largest one:
166 -- check adg_gtk_use_default_icons() implementation.
167 local last_icon = icon_list[#icon_list]
168 dialog:set_logo(last_icon)
169
170 dialog.on_response = Gtk.Widget.hide
171 dialog:run()
172end
173
174
175-- Edit dialog
176
177local function entry_info(widget)
178 if Gtk.ToggleButton:is_type_of(widget) then
179-- Boolean value
180return 'get_active', 'set_active', 'on_toggled'
181 elseif Gtk.Entry:is_type_of(widget) then
182-- String value
183return 'get_text', 'set_text', 'on_changed'
184 elseif Gtk.SpinButton:is_type_of(widget) then
185-- Number value
186return 'get_value', 'set_value', 'on_changed'
187 else
188-- Unhandled type
189return
190 end
191end
192
193local function update_title_block()
194 local title_block = canvas.title_block
195 for field in pairs(Adg.TitleBlock._property) do
196local value = piston.data[field:upper()]
197if value then title_block[field] = value end
198 end
199end
200
201ui.editGROOVE.on_toggled = function (self)
202 local toggled = self:get_active()
203 ui.editZGROOVE:set_sensitive(toggled)
204 ui.editZGROOVELabel:set_sensitive(toggled)
205 ui.editDGROOVE:set_sensitive(toggled)
206 ui.editDGROOVELabel:set_sensitive(toggled)
207 ui.editLGROOVE:set_sensitive(toggled)
208 ui.editLGROOVELabel:set_sensitive(toggled)
209end
210
211for field in pairs(piston.data) do
212 local widget = ui['edit' .. field]
213 if widget then
214-- Synchronize GtkSpinButton to GtkAdjustment, that is
215-- initialize the widget to its default value
216if Gtk.SpinButton:is_type_of(widget) then
217 local adj = widget:get_adjustment()
218 adj:value_changed()
219end
220
221-- Unlock the UI on every widget change
222local getter, _, notification = entry_info(widget)
223widget[notification] = function ()
224 ui.btnApply:set_sensitive(true)
225 ui.btnReset:set_sensitive(true)
226end
227piston.data[field] = widget[getter](widget)
228 end
229end
230
231update_title_block()
232
233ui.mainEdit.on_clicked = function ()
234 local dialog = ui.wndEdit
235 dialog:set_position(Gtk.WindowPosition.MOUSE);
236
237 local function lock_ui()
238ui.btnApply:set_sensitive(false)
239ui.btnReset:set_sensitive(false)
240 end
241
242 ui.btnApply.on_clicked = function ()
243-- Refresh the piston data using the widgets
244for field in pairs(piston.data) do
245 local widget = ui['edit' .. field]
246 local getter = entry_info(widget)
247 if getter then
248piston.data[field] = widget[getter](widget)
249 end
250end
251
252-- Regenerate all the models
253for _, model in pairs(piston.model) do
254 model:reset()
255 model:regenerate(piston)
256 model:changed()
257end
258update_title_block()
259
260-- Refresh the GTK+ interface
261area:queue_draw()
262
263lock_ui()
264 end
265
266 ui.btnReset.on_clicked = function ()
267-- Update the widgets using the piston data
268for field, value in pairs(piston.data) do
269 local widget = ui['edit' .. field]
270 local _, setter = entry_info(widget)
271 if setter then
272widget[setter](widget, value)
273 end
274end
275
276lock_ui()
277 end
278
279 dialog.on_response = Adg.gtk_window_hide_here
280 dialog:run()
281end
282
283
284-- Save as dialog
285
286ui.mainSaveAs.on_clicked = function ()
287 local dialog = ui.wndSaveAs
288
289 -- Set the default destination file and directory
290 local dir = nil
291 if GLib.UserDirectory then
292-- Issue: http://github.com/pavouk/lgi/issues/45
293local dir_type = GLib.UserDirectory.DOCUMENTS or
294 GLib.UserDirectory.DIRECTORY_DOCUMENTS
295dir = GLib.get_user_special_dir(dir_type)
296 end
297 dir = dir or GLib.get_home_dir()
298 dialog:set_current_folder(dir)
299 dialog:set_current_name('adg-demo')
300
301 -- Response handling
302 dialog.on_response = function (dialog, response)
303if response == Gtk.ResponseType.OK then
304 -- Retrieve the file suffix (format type)
305 local suffix
306 for _, radio in pairs(ui.saveAsPng:get_group()) do
307if radio:get_active() then
308 suffix = radio:get_tooltip_markup()
309 break
310end
311 end
312 local file = dialog:get_filename()
313 if not GLib.str_has_suffix(file, suffix) then
314file = file .. suffix
315 end
316 _, err = canvas:export(file)
317 if err then error(err) end
318end
319dialog:hide()
320 end
321
322 dialog:run()
323end
324
325
326-- Print dialog
327
328do
329local settings
330
331ui.mainPrint.on_clicked = function ()
332 local operation = Gtk.PrintOperation.new()
333
334 operation:set_use_full_page(operation, false)
335 operation:set_unit(Gtk.Unit.POINTS)
336
337 if settings then
338operation:set_print_settings(settings)
339 end
340
341 if Gtk.PrintOperation.set_embed_page_setup then
342operation:set_embed_page_setup(true)
343 end
344
345 local page_setup = canvas:get_page_setup()
346 if page_setup then
347 operation:set_default_page_setup(page_setup)
348 end
349
350 operation.on_begin_print = function ()
351operation:set_n_pages(1)
352 end
353
354 operation.on_draw_page = function (operation, context)
355local cr = context:get_cairo_context()
356
357local old_map = canvas:get_global_map()
358canvas:set_global_map(Adg.matrix_identity())
359canvas:render(cr)
360canvas:set_global_map(old_map)
361 end
362
363 local result, err = operation:run(Gtk.PrintOperationAction.PRINT_DIALOG, ui.wndMain)
364 if result == Gtk.PrintOperationResult.APPLY then
365 settings = operation:get_print_settings()
366 elseif err then
367error(err)
368 end
369end
370
371end
372
373
374-- Quit command
375
376ui.mainQuit.on_clicked = Gtk.main_quit
377
378
379-- Main window
380
381local window = ui.wndMain
382window.on_delete_event = Gtk.main_quit
383window:show_all()
384
385
386Gtk.main()

Archive Download this file

Branches

Tags