arcadia 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README ADDED
@@ -0,0 +1,122 @@
1
+ Arcadia Ruby Ide
2
+ version 0.1.0
3
+
4
+ by Antonio Galeone
5
+ on Feb 25, 2007
6
+
7
+ "Thank you for consider this project"
8
+
9
+ About
10
+ =====
11
+ Arcadia is a Integrated Development Environment (IDE) for Ruby language
12
+ written in Ruby using the classic tcl/tk GUI toolkit.
13
+
14
+ Some of Arcadia ruby ide project features include:
15
+ -Editor with source browsing and syntax highlighting
16
+ -Supporting RAD gui building
17
+ -Generation of widget-wrapper-independent ruby code
18
+ -Working on any platform where ruby and tcl-tk work.
19
+ -Highly extensibility architecture.
20
+
21
+ This release
22
+ ============
23
+ This is the first public version. A lot of things are to do
24
+ but i have decided to begin to release something. I use Arcadia
25
+ to develop Arcadia so there is something!
26
+
27
+ Short User guide
28
+ ================
29
+ I hope that you perceive Arcadia gui enough user frindly.
30
+ As you can see the application is splitted in vertial
31
+ and horizontal resizing frames. Clicking on vertical splitter
32
+ appear two button for left or right one shot frame close.
33
+ The horizontal splitter has two little button for the same reason
34
+ (perhaps i will conform them to the vertical style).
35
+ Every frame has a title and a button to expand or resizing it.
36
+ In this beta release there are very essential feature:
37
+
38
+ < Toolbar >
39
+ The toolbar button are in order:
40
+ -new, open, save
41
+ (relatively to editor extension)
42
+ -run current, run last
43
+ (for execute the raised file in the editor or the last file executed)
44
+ -debug current, debug last, stop debug
45
+ (for the debug extension that is in very unstable state)
46
+ -quit (to exit from arcadia)
47
+
48
+ < Editor >
49
+ Editor use the notebook metaphor. Same command are on the popup menu
50
+ that is raised on "Button-3" click event fundamentalally for closing the tab
51
+ under the mouse pointer.
52
+ These are same editor short-cut:
53
+ Ctrl-c => copy selected text
54
+ Ctrl-v => paste copied text
55
+ Ctrl-x => cut selected text
56
+ Ctrl-z => undo
57
+ Ctrl-f => copy the selected text on input combobox of find bar and moves focus
58
+ Ctrl-s => save
59
+ Ctrl-shift-i => indent the selected block
60
+ Ctrl-shift-u => unindent the selected block
61
+ Ctrl-shift-c => comment/uncomment the selected code block
62
+ F5 => execute the file
63
+ F3 => find/ find next
64
+
65
+ Double-Click on line number set or unset a debug breckpoint
66
+
67
+ < File history >
68
+ The last used files are organizing in tree so you can reopen them or there
69
+ directory by clicking on the tree node.
70
+
71
+ < Palette >
72
+ It containe the wrapper components for the tk gui building.
73
+ It is in very unstabled and incomplete state.
74
+ The first component is a TkTopLevel wrapper, when you click on it a new form is created and a
75
+ Object inspector appears.
76
+ The other component must be first selected and then created by clicking on container widget.
77
+ The so created widgets has a popup menu for deleting them or in the toplevel case to switch
78
+ to a code view.
79
+ On the palette there are also two button, one for deselect and other for copy from the selected
80
+ created widget. The copy action copy also the code into the clipboard, so you can copy the
81
+ code rapresenting the gui into the embedded editor or into external editor.
82
+
83
+ < Object Inspector >
84
+ It is for modify the widget property at runtime
85
+
86
+ < Debug >
87
+ It is created when a debug session init.
88
+ The debug button are: Step Next, Step Into, Step Over, Resume.
89
+ The debug frame show the local, instance and global variables for each
90
+ step. (you must have patience!)
91
+
92
+ <Configuration>
93
+ Same Arcadia properties are locally configurabled by editing the file arcadia.conf
94
+ under ~/.arcadia directory. The format of property definition are:
95
+ <OPERATING SYSTEM IDENTIFY:>PROPERTY_NAME=PROPERTY_VALUE
96
+
97
+
98
+ Requirement
99
+ ===========
100
+ I include into distribution also the BWidget lib (under tcl directory) so
101
+ are require realy only the standard tcl tk lib (tested on tcl tk 8.4).
102
+ I have tested arcadia with ruby 1.8.4 and 1.8.5 on FreeBsd6 and windows 2000 os. If you
103
+ will test arcadia on other operating system sends me a e-mail.
104
+
105
+ Developers information
106
+ =====================
107
+ Soon i will write samething about the arcadia software architecture (when it is more stable)
108
+ in order to allow extensions writing and collaborations.
109
+
110
+
111
+
112
+ License
113
+ =======
114
+ Arcadia is released under the Ruby License
115
+
116
+ Contacts
117
+ ========
118
+ For questions:
119
+ antonio-galeone@rubyforge.org
120
+ For bugs, support request, feature request https://rubyforge.org/projects/arcadia:
121
+
122
+
data/arcadia.rb ADDED
@@ -0,0 +1,748 @@
1
+ #
2
+ # arcadia.rb - Arcadia Ruby ide
3
+ # by Antonio Galeone <antonio-galeone@rubyforge.org>
4
+ #
5
+
6
+ Dir.chdir(File.dirname(__FILE__))
7
+ if FileTest.exist?('conf/arcadia.init.rb')
8
+ require 'conf/arcadia.init'
9
+ end
10
+ require "conf/arcadia.res"
11
+ require 'tkextlib/bwidget'
12
+ require "base/a-utils"
13
+ require "base/a-ext"
14
+ require "base/a-contracts"
15
+ require "observer"
16
+
17
+ class Arcadia < TkApplication
18
+ include Observable
19
+ attr_reader :layout
20
+ attr_reader :libs
21
+ #attr_reader :main_contract
22
+ def initialize
23
+ super(
24
+ ApplicationParams.new(
25
+ 'arcadia',
26
+ '0.1.0',
27
+ 'conf/arcadia.conf',
28
+ 'conf/arcadia.pers'
29
+ )
30
+ )
31
+ self.load_local_config(false)
32
+ ObjectSpace.define_finalizer($arcadia, self.class.method(:finalize).to_proc)
33
+ publish('action.on_exit', proc{do_exit})
34
+ _title = "Arcadia Ruby ide :: [Platform = "+RUBY_PLATFORM+'] [Ruby version = ' + RUBY_VERSION+']'
35
+ @root = TkRoot.new{
36
+ title _title
37
+ withdraw
38
+ protocol( "WM_DELETE_WINDOW", $arcadia['action.on_exit'])
39
+ }
40
+ @on_event = Hash.new
41
+ @main_menu = TkMenubar.new.pack('fill'=>'x')
42
+ @mf_root = Tk::BWidget::MainFrame.new(@root){
43
+ menu @main_menu
44
+ }.pack(
45
+ 'anchor'=> 'center',
46
+ 'fill'=> 'both',
47
+ 'expand'=> 1
48
+ )
49
+ @toolbar = @mf_root.add_toolbar
50
+ @mf_root.show_toolbar(1,true)
51
+ @splash = ArcadiaAboutSplash.new('... initialize')
52
+ @splash.set_progress(50)
53
+ @splash.deiconify
54
+ Tk.update
55
+ sleep(1)
56
+ @splash.next_step('..prepare')
57
+ prepare
58
+ @splash.last_step('..load finish')
59
+ geometry = (TkWinfo.screenwidth(@root)-4).to_s+'x'+
60
+ (TkWinfo.screenheight(@root)-20).to_s+'+0+0'
61
+ @root.deiconify
62
+ @root.raise
63
+ @root.focus(true)
64
+ @root.geometry(geometry)
65
+ Tk.update_idletasks
66
+ sleep(1)
67
+ @splash.destroy
68
+ if @first_run
69
+ EditorContract.instance.open_file(EditorContract::TEditorObj.new(self, 'file'=>'README'))
70
+ end
71
+ end
72
+
73
+ def Arcadia.finalize(id)
74
+ puts "\nArcadia #{id} dying at #{Time.new}"
75
+ end
76
+
77
+ def load_libs
78
+ @libs = ArcadiaLibs.new(self)
79
+ libs = self['conf']['libraries'].split(',')
80
+ libs.each{|lib|
81
+ if lib
82
+ @splash.next_step('... loading library '+lib)
83
+ begin
84
+ require self['conf']['libraries.'+lib+'.source']
85
+ @libs.add_lib(
86
+ ArcadiaLibs::ArcadiaLibParams.new(
87
+ self['conf']['libraries.'+lib+'.name'],
88
+ self['conf']['libraries.'+lib+'.source'],
89
+ self['conf']['libraries.'+lib+'.require'],
90
+ eval(self['conf']['libraries.'+lib+'.collection.class']))
91
+ )
92
+ rescue Exception
93
+ msg = "Loading lib "+'"'+lib+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
94
+ if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
95
+ 'title' => '(Arcadia) Libs', 'parent' => @root,
96
+ 'message' => msg) == 'cancel'
97
+ raise
98
+ exit
99
+ else
100
+ Tk.update
101
+ end
102
+ end
103
+ end
104
+ }
105
+ end
106
+
107
+ def load_toolbar_buttons
108
+ suf = 'toolbar_buttons'
109
+ @buttons = Hash.new
110
+ toolbar_buttons = self['conf'][suf].split(',')
111
+ toolbar_buttons.each{|groups|
112
+ if groups
113
+ suf1 = suf+'.'+groups
114
+ @splash.next_step('... loading '+suf1)
115
+ begin
116
+ buttons = self['conf'][suf1].split(',')
117
+ buttons.each{|button|
118
+ suf2 = suf1+'.'+button
119
+ name = self['conf'][suf2+'.name']
120
+ text = self['conf'][suf2+'.text']
121
+ image = self['conf'][suf2+'.image']
122
+ font = self['conf'][suf2+'.font']
123
+ background = self['conf'][suf2+'.background']
124
+ foreground = self['conf'][suf2+'.foreground']
125
+ hint = self['conf'][suf2+'.hint']
126
+ action = self['conf'][suf2+'.action']
127
+ actions = action.split('->') if action
128
+ if actions && actions.length>1
129
+ _command = proc{
130
+ action_obj = $arcadia[actions[0]]
131
+ 1.upto(actions.length-2) do |x|
132
+ action_obj = action_obj.send(actions[x])
133
+ end
134
+ action_obj.send(actions[actions.length-1])
135
+ }
136
+ elsif action
137
+ _command = proc{$arcadia[action].call}
138
+ end
139
+ @buttons[name] = Tk::BWidget::Button.new(@toolbar){
140
+ image TkPhotoImage.new('data' => eval(image)) if image
141
+ borderwidth 1
142
+ font font if font
143
+ background background if background
144
+ foreground foreground if foreground
145
+ command _command if action
146
+ relief 'flat'
147
+ helptext hint if hint
148
+ text text if text
149
+ pack('side' =>'left', :padx=>2, :pady=>2)
150
+ }
151
+ }
152
+ rescue Exception
153
+ msg = 'Loading '+groups+'" -> '+buttons.to_s+ '" (' + $!.class.to_s + ") : " + $!.to_s + " at : "+$@.to_s
154
+ if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
155
+ 'title' => '(Arcadia) Toolbar', 'parent' => @root,
156
+ 'message' => msg) == 'cancel'
157
+ raise
158
+ exit
159
+ else
160
+ Tk.update
161
+ end
162
+ end
163
+ end
164
+ Tk::BWidget::Separator.new(@toolbar, :orient=>'vertical').pack('side' =>'left', :padx=>2, :pady=>2, :fill=>'y',:anchor=> 'w')
165
+ }
166
+ end
167
+
168
+ def ext_active?(_name)
169
+ return (self['conf'][_name+'.active'] != nil && self['conf'][_name+'.active']=='yes')||
170
+ (self['conf'][_name+'.active'] == nil)
171
+ end
172
+
173
+ def load_exts_conf
174
+ @exts = Array.new
175
+ dirs = Array.new
176
+ files = Dir['ext/*'].concat(Dir[ENV["HOME"]+'/.arcadia/ext/*'])
177
+ files.each{|f|
178
+ dirs << f if File.stat(f).directory? && FileTest.exist?(f+'/'+File.basename(f)+'.conf')
179
+ }
180
+ dirs.each{|ext_dir|
181
+ conf_hash = self.config_file2hash(ext_dir+'/'+File.basename(ext_dir)+'.conf')
182
+ conf_hash2 = Hash.new
183
+ name = conf_hash['name']
184
+ conf_hash.each{|key, value|
185
+ var_plat = key.split(':')
186
+ if var_plat.length > 1
187
+ new_key = var_plat[0] + ':' + name + '.' + var_plat[1]
188
+ else
189
+ new_key = name+'.'+key
190
+ end
191
+ conf_hash2[new_key]= value
192
+ }
193
+ @exts << name
194
+ self['conf'].update(conf_hash2)
195
+ }
196
+ end
197
+
198
+ def load_exts
199
+
200
+ # create extensions
201
+ @exts.each{|extension|
202
+ if extension && ext_active?(extension)
203
+ @splash.next_step('... creating '+extension)
204
+ ext_create(extension)
205
+ end
206
+ }
207
+
208
+ # before_build extensions
209
+ @exts.each{|extension|
210
+ if extension && ext_active?(extension)
211
+ @splash.next_step('... before building '+extension)
212
+ ext_method(extension, :before_build)
213
+ MainContract.instance.extension_before_build(MainContract::TMainObj.new(self, 'obj'=>self[extension]))
214
+ end
215
+ }
216
+
217
+ # build extensions
218
+ @exts.each{|extension|
219
+ if extension && ext_active?(extension)
220
+ @splash.next_step('... building '+extension)
221
+ ext_method(extension, :build)
222
+ _tobj = MainContract::TMainObj.new(self)
223
+ _tobj.obj = self[extension]
224
+ MainContract.instance.extension_build(_tobj)
225
+ end
226
+ }
227
+
228
+ # after build extensions
229
+ @exts.each{|extension|
230
+ if extension && ext_active?(extension)
231
+ @splash.next_step('... after building '+extension)
232
+ ext_method(extension, :after_build)
233
+ _tobj = MainContract::TMainObj.new(self)
234
+ _tobj.obj = self[extension]
235
+ MainContract.instance.extension_after_build(_tobj)
236
+ end
237
+ }
238
+
239
+ end
240
+
241
+ def ext_create(_extension)
242
+ begin
243
+ source = self['conf'][_extension+'.require']
244
+ class_name = self['conf'][_extension+'.class']
245
+ if source.strip.length > 0
246
+ #p source
247
+ eval('require ' + "'" + source + "'")
248
+ end
249
+ if class_name.strip.length > 0
250
+ publish(_extension, eval(class_name).new(self, _extension))
251
+ end
252
+ rescue Exception
253
+ raise
254
+ msg = "Loading "+'"'+extension+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
255
+ ans = Tk.messageBox('icon' => 'error', 'type' => 'abortretryignore',
256
+ 'title' => '(Arcadia) Extensions', 'parent' => @root,
257
+ 'message' => msg)
258
+ if ans == 'abort'
259
+ raise
260
+ exit
261
+ elsif ans == 'retry'
262
+ retry
263
+ else
264
+ Tk.update
265
+ end
266
+ end
267
+ end
268
+
269
+ def ext_method(_extension, _method)
270
+ begin
271
+ self[_extension].send(_method)
272
+ rescue Exception
273
+ msg = _method.to_s+' "'+_extension.to_s+'"'+" ("+$!.class.to_s+") "+" : "+$! + "\n at : "+$@.to_s
274
+ ans = Tk.messageBox('icon' => 'warning', 'type' => 'abortretryignore',
275
+ 'title' => '(Arcadia) Extensions', 'parent' => @root,
276
+ 'message' => msg)
277
+ if ans == 'abort'
278
+ raise
279
+ exit
280
+ elsif ans == 'retry'
281
+ retry
282
+ else
283
+ Tk.update
284
+ end
285
+ end
286
+ end
287
+
288
+
289
+ def prepare
290
+ super
291
+ @splash.next_step('...initialize')
292
+ @layout = ArcadiaLayout.new(self, @mf_root.get_frame)
293
+
294
+ #@layout.add_cols(0,0,230,'_mosca_','_white_street_')
295
+ #@layout.add_rows(0,1,80,'_tokyo_','_red_street_')
296
+ #@layout.add_rows(1,1,450,'_los_angeles_','_rome_')
297
+
298
+ @layout.add_cols(0,0,230)
299
+ @layout.add_rows(0,0,190)
300
+ #@layout.add_rows(0,1,80)
301
+ #@layout.add_rows(1,1,450)
302
+ @layout.add_rows(0,1,500)
303
+
304
+
305
+ @layout.add_headers
306
+ @splash.next_step
307
+ self.load_libs
308
+ @splash.next_step
309
+ @splash.next_step('... load extensions')
310
+ self.load_exts_conf
311
+ self.load_local_config
312
+ self.load_exts
313
+ publish('buffers.code.in_memory',Hash.new)
314
+ publish('action.load_code_from_buffers', proc{TkBuffersChoise.new})
315
+ publish('output.action.run_last', proc{$arcadia['output'].run_last})
316
+ publish('main.action.open_file', proc{self['editor'].open_file(Tk.getOpenFile)})
317
+ @splash.next_step('... load obj controller')
318
+ @splash.next_step('... load editor')
319
+ publish('main.action.new_file',proc{$arcadia['editor'].open_buffer()})
320
+ publish('main.action.edit_cut',proc{$arcadia['editor'].raised.text.text_cut()})
321
+ publish('main.action.edit_copy',proc{$arcadia['editor'].raised.text.text_copy()})
322
+ publish('main.action.edit_paste',proc{$arcadia['editor'].raised.text.text_paste()})
323
+ @splash.next_step('... load actions')
324
+ publish('action.test.keys', proc{KetTest.new})
325
+ publish('action.get.font', proc{Tk::BWidget::SelectFont::Dialog.new.create})
326
+ @splash.next_step
327
+ publish('action.show_about', proc{ArcadiaAboutSplash.new.deiconify})
328
+ publish('main.menu', AMainMenu.new(@main_menu))
329
+ @splash.next_step
330
+ publish('objic.action.raise_active_obj',
331
+ proc{
332
+ InspectorContract.instance.raise_active_toplevel(InspectorContract::TInspectorObj.new(self))
333
+ # if $arcadia['objic'].active
334
+ # agobj = $arcadia['objic'].active.active_object
335
+ # while agobj.ag_parent
336
+ # agobj = agobj.ag_parent
337
+ # end
338
+ # agobj.obj.raise
339
+ # end
340
+ }
341
+ )
342
+ #@root.bind("Button-1", $arcadia['objic.action.raise_active_obj'] )
343
+ load_toolbar_buttons
344
+ end
345
+
346
+ def do_exit
347
+ q1 = (Tk.messageBox('icon' => 'question', 'type' => 'yesno',
348
+ 'title' => '(Arcadia) Exit', 'parent' => @root,
349
+ 'message' => "Do you want exit?")=='yes')
350
+ if q1 && can_exit?
351
+ do_finalize
352
+ @root.destroy
353
+ end
354
+ end
355
+
356
+ def can_exit?
357
+ _can_exit = true
358
+ @exts.each{|extension|
359
+ if ext_active?(extension) && !self[extension].can_exit_query
360
+ _can_exit = false
361
+ break
362
+ end
363
+ }
364
+ return _can_exit
365
+ end
366
+
367
+ def do_finalize
368
+ @exts.each{|extension|
369
+ self[extension].finalize if ext_active?(extension)
370
+ }
371
+ self.write_persist
372
+ end
373
+ end
374
+
375
+ class AMainMenu < TkMenubar
376
+
377
+ def initialize(menu)
378
+ # create main menu
379
+ @menu = menu
380
+ build
381
+ menu.foreground('grey40')
382
+ menu.activeforeground('red')
383
+ menu.relief('flat')
384
+ menu.font($arcadia['conf']['main.mainmenu.font'])
385
+ end
386
+
387
+ def build
388
+ menu_spec_file = [
389
+ ['File', 0],
390
+ ['Open', $arcadia['main.action.open_file'], 0],
391
+ ['New', $arcadia['main.action.new_file'], 0],
392
+ '---',
393
+ ['Quit', $arcadia['action.on_exit'], 0]]
394
+ menu_spec_edit = [['Edit', 0],
395
+ ['Cut', $arcadia['main.action.edit_cut'], 2],
396
+ ['Copy', $arcadia['main.action.edit_copy'], 0],
397
+ ['Paste', $arcadia['main.action.edit_paste'], 0]]
398
+ menu_spec_view = [['View', 0],'---']
399
+ menu_spec_tools = [['Utils', 0],
400
+ ['Keys-test', $arcadia['action.test.keys'], 2],
401
+ ['Load code from buffer', $arcadia['action.load_code_from_buffers'], 2]
402
+ ]
403
+ menu_spec_help = [['Help', 0],
404
+ ['About', $arcadia['action.show_about'], 2],]
405
+ @menu.add_menu(menu_spec_file)
406
+ @menu.add_menu(menu_spec_edit)
407
+ #@menu.add_menu(menu_spec_view)
408
+ @menu.add_menu(menu_spec_tools)
409
+ @menu.add_menu(menu_spec_help)
410
+ end
411
+
412
+ end
413
+
414
+ class ArcadiaAboutSplash < TkToplevel
415
+ attr :progress
416
+
417
+ def initialize(_txt=nil)
418
+ #_bgcolor = '#B83333'
419
+ _bgcolor = '#000000'
420
+ super()
421
+ relief 'flat'
422
+ background _bgcolor
423
+ highlightbackground _bgcolor
424
+ highlightthickness 6
425
+ borderwidth 1
426
+ withdraw
427
+ overrideredirect(true)
428
+
429
+ @tkLabel3 = TkLabel.new(self){
430
+ image TkPhotoImage.new('format'=>'GIF','data' =>A_LOGO_GIF)
431
+ background _bgcolor
432
+ place('x'=> 20,'y' => 20)
433
+ }
434
+ @tkLabel1 = TkLabel.new(self){
435
+ text 'Arcadia'
436
+ background _bgcolor
437
+ foreground '#ffffff'
438
+ font Arcadia.instance['conf']['splash.title.font']
439
+ justify 'left'
440
+ place('width' => '190','x' => 120,'y' => 10,'height' => 25)
441
+ }
442
+ @tkLabelRuby = TkLabel.new(self){
443
+ image TkPhotoImage.new('data' =>RUBY_DOCUMENT_GIF)
444
+ background _bgcolor
445
+ place('x'=> 150,'y' => 40)
446
+ }
447
+ @tkLabel2 = TkLabel.new(self){
448
+ text 'Ruby ide'
449
+ background _bgcolor
450
+ foreground '#ffffff'
451
+ font Arcadia.instance['conf']['splash.subtitle.font']
452
+ justify 'left'
453
+ place('width' => '90','x' => 170,'y' => 40,'height' => 19)
454
+ }
455
+ @tkLabelVersion = TkLabel.new(self){
456
+ text 'version: '+$arcadia['applicationParams'].version
457
+ background _bgcolor
458
+ foreground '#ffffff'
459
+ font Arcadia.instance['conf']['splash.version.font']
460
+ justify 'left'
461
+ place('width' => '100','x' => 150,'y' => 60,'height' => 19)
462
+ }
463
+ @tkLabelStep = TkLabel.new(self){
464
+ text _txt
465
+ background _bgcolor
466
+ foreground 'yellow'
467
+ font Arcadia.instance['conf']['splash.banner.font']
468
+ justify 'left'
469
+ anchor 'w'
470
+ place('width'=>-5,'relwidth' => 1,'x' => 5,'y' => 175,'height' => 19)
471
+ }
472
+ @tkLabel21 = TkLabel.new(self){
473
+ text 'by Antonio Galeone - 2007'
474
+ background _bgcolor
475
+ foreground '#ffffff'
476
+ font Arcadia.instance['conf']['splash.credits.font']
477
+ justify 'left'
478
+ place('width' => '190','x' => 130,'y' => 146,'height' => 19)
479
+ }
480
+ @progress = TkVariable.new
481
+ reset
482
+ _width = 340
483
+ _height = 210
484
+ #_width = 0;_height = 0
485
+ _x = TkWinfo.screenwidth(self)/2 - _width / 2
486
+ _y = TkWinfo.screenheight(self)/2 - _height / 2
487
+ geometry = _width.to_s+'x'+_height.to_s+'+'+_x.to_s+'+'+_y.to_s
488
+ Tk.tk_call('wm', 'geometry', self, geometry )
489
+ bind("Double-Button-1", proc{self.destroy})
490
+ end
491
+
492
+ def set_progress(_max=10)
493
+ @max = _max
494
+ Tk::BWidget::ProgressBar.new(self, :width=>150, :height=>10,
495
+ :background=>'black',
496
+ :foreground=>'yellow',
497
+ :variable=>@progress,
498
+ :borderwidth=>0,
499
+ :relief=>'flat',
500
+ :maximum=>_max).place('width' => '150','x' => 145,'y' => 95,'height' => 15)
501
+ end
502
+
503
+ def reset
504
+ @progress.value = -1
505
+ end
506
+
507
+ def next_step(_txt = nil)
508
+ @progress.numeric += 1
509
+ labelStep(_txt) if _txt
510
+ end
511
+
512
+ def labelStep(_txt)
513
+ @tkLabelStep.text = _txt
514
+ Tk.update
515
+ end
516
+
517
+ def last_step(_txt = nil)
518
+ @progress.numeric = @max
519
+ labelStep(_txt) if _txt
520
+ end
521
+
522
+ end
523
+
524
+ class TkBuffersChoiseView < TkToplevel
525
+
526
+ def initialize
527
+ super
528
+ Tk.tk_call('wm', 'title', self, '...hello' )
529
+ Tk.tk_call('wm', 'geometry', self, '150x217+339+198' )
530
+ @lb = TkListbox.new(self){
531
+ background '#fedbd7'
532
+ relief 'groove'
533
+ place('relwidth' => '1','relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => '0','bordermode' => 'inside','width' => '0')
534
+ }
535
+ end
536
+
537
+ end
538
+
539
+ class TkBuffersChoise < TkBuffersChoiseView
540
+
541
+ def initialize
542
+ super
543
+ @lb.value= $arcadia['buffers.code.in_memory'].keys
544
+ @lb.bind("Double-ButtonPress-1",proc{
545
+ _sel = @lb.get('active')
546
+ Revparsel.new($arcadia['buffers.code.in_memory'][_sel])
547
+ @lb.delete('active')
548
+ $arcadia['buffers.code.in_memory'].delete(_sel)
549
+ destroy
550
+ })
551
+ raise
552
+ end
553
+
554
+ end
555
+
556
+ class ArcadiaLayout
557
+ include Observable
558
+ ArcadiaPanelInfo = Struct.new( "ArcadiaPanelInfo",
559
+ :name,
560
+ :title,
561
+ :frame
562
+ )
563
+
564
+ def initialize(_arcadia, _frame, _autotab=true)
565
+ @arcadia = _arcadia
566
+ @frames = Array.new
567
+ @frames[0] = Array.new
568
+ @frames[0][0] = _frame
569
+ @domains = Array.new
570
+ @domains[0] = Array.new
571
+ @domains[0][0] = '_domain_root_'
572
+ @panels = Hash.new
573
+ @panels['_domain_root_']= Hash.new
574
+ @panels['_domain_root_']['root']= _frame
575
+ @panels['_domain_root_']['sons'] = Hash.new
576
+ @autotab = _autotab
577
+ @headed = false
578
+ ArcadiaContractListener.new(self, MainContract, :do_main_event)
579
+ end
580
+
581
+ def do_main_event(_event)
582
+ case _event.signature
583
+ when MainContract::RAISE_EXTENSION
584
+ p = @panels[_event.context.domain]
585
+ if p && p['notebook'] != nil && _event.channel == '0'
586
+ p['notebook'].raise(_event.context.extension)
587
+ end
588
+ end
589
+ end
590
+
591
+ def add_rows(_row,_col, _height, _top_name=nil, _bottom_name=nil)
592
+ if (@frames[_row][_col] != nil)
593
+ _h = AGTkOSplittedFrames.new(@frames[_row][_col],_height)
594
+ if @frames[_row + 1] == nil
595
+ @frames[_row + 1] = Array.new
596
+ @domains[_row + 1] = Array.new
597
+ end
598
+ @frames[_row][_col] = _h.top_frame
599
+ @frames[_row + 1][_col] = _h.bottom_frame
600
+
601
+ _top_name = _row.to_s+'.'+_col.to_s if _top_name == nil
602
+ @panels[_top_name] = Hash.new
603
+ @panels[_top_name]['root'] = @frames[_row][_col]
604
+ @panels[_top_name]['sons'] = Hash.new
605
+ @domains[_row][_col] = _top_name
606
+
607
+ _bottom_name = (_row+1).to_s+'.'+_col.to_s if _bottom_name == nil
608
+ @panels[_bottom_name] = Hash.new
609
+ @panels[_bottom_name]['root'] = @frames[_row + 1][_col]
610
+ @panels[_bottom_name]['sons'] = Hash.new
611
+ @domains[_row + 1][_col] = _bottom_name
612
+ end
613
+ end
614
+
615
+ def add_cols(_row,_col, _width, _left_name=nil, _right_name=nil)
616
+ if (@frames[_row][_col] != nil)
617
+ _w = AGTkVSplittedFrames.new(@frames[_row][_col],_width)
618
+ @frames[_row][_col] = _w.left_frame
619
+ @frames[_row][_col + 1] = _w.right_frame
620
+
621
+ _left_name = _row.to_s+'.'+_col.to_s if _left_name == nil
622
+ @panels[_left_name] = Hash.new
623
+ @panels[_left_name]['root'] = @frames[_row][_col]
624
+ @panels[_left_name]['sons'] = Hash.new
625
+ @domains[_row][_col] = _left_name
626
+
627
+ _right_name = _row.to_s+'.'+(_col+1).to_s if _right_name == nil
628
+ @panels[_right_name] = Hash.new
629
+ @panels[_right_name]['root'] = @frames[_row][_col + 1]
630
+ @panels[_right_name]['sons'] = Hash.new
631
+ @domains[_row][_col + 1] = _right_name
632
+ end
633
+ end
634
+
635
+ def add_headers
636
+ @domains.each{|row|
637
+ row.each{|domain|
638
+ @panels[domain]['root']= TkTitledFrame.new(@panels[domain]['root'], '...').place('x'=>0, 'y'=>0,'relheight'=>1, 'relwidth'=>1) if @panels[domain]
639
+ }
640
+ }
641
+ @headed = true
642
+ end
643
+
644
+ def headed?
645
+ @headed
646
+ end
647
+
648
+ def autotab?
649
+ @autotab
650
+ end
651
+
652
+ def registed?(_domain_name, _name)
653
+ @panels[_domain_name]['sons'][_name] != nil
654
+ end
655
+
656
+ def register_panel(_domain_name, _name, _title)
657
+ p = @panels[_domain_name]
658
+ if p!=nil
659
+ num = p['sons'].length
660
+ if @headed
661
+ p['root'].title(_title)
662
+ root_frame = p['root'].frame
663
+ else
664
+ root_frame = p['root']
665
+ end
666
+ if (num == 0 && @autotab)
667
+ api = ArcadiaPanelInfo.new(_name,_title,nil)
668
+ api.frame = TkFrame.new(root_frame).place('x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
669
+ p['sons'][_name] = api
670
+ return api.frame
671
+ else
672
+ if num == 1 && @autotab && p['notebook'] == nil
673
+ p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
674
+ tabbevelsize 0
675
+ internalborderwidth 0
676
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
677
+ }
678
+ api = p['sons'].values[0]
679
+ api_tab_frame = p['notebook'].insert('end',
680
+ api.name,
681
+ 'text'=>api.title,
682
+ 'raisecmd'=>proc{
683
+ p['root'].title(api.title)
684
+ p['root'].top_text('')
685
+ changed
686
+ notify_observers('RAISE', api.name)
687
+ }
688
+ )
689
+ api.frame.place('in'=>api_tab_frame, 'x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
690
+ api.frame.raise
691
+ elsif (num==0 && !@autotab)
692
+ p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
693
+ tabbevelsize 0
694
+ internalborderwidth 0
695
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
696
+ }
697
+ end
698
+ _panel = p['notebook'].insert('end',_name ,
699
+ 'text'=>_title,
700
+ #'background'=>_tab_bg,
701
+ 'raisecmd'=>proc{
702
+ p['root'].title(_title)
703
+ changed
704
+ notify_observers('RAISE', _name)
705
+ }
706
+ )
707
+
708
+ # if _tab_bg
709
+ # _panel = p['notebook'].insert('end',_name , 'text'=>_title, 'background'=>_tab_bg)
710
+ # else
711
+ # _panel = p['notebook'].insert('end',_name , 'text'=>_title)
712
+ # end
713
+ p['sons'][_name] = ArcadiaPanelInfo.new(_name,_title,_panel)
714
+ p['notebook'].raise(_name)
715
+ return _panel
716
+ end
717
+ end
718
+ end
719
+
720
+ def unregister_panel(_domain_name, _name)
721
+ @panels[_domain_name]['sons'].delete(_name)
722
+ @panels[_domain_name]['notebook'].delete(_name)
723
+ new_raise_key = @panels[_domain_name]['sons'].keys[@panels[_domain_name]['sons'].length-1]
724
+ @panels[_domain_name]['notebook'].raise(new_raise_key)
725
+ end
726
+
727
+ def raise_panel(_domain_name, _name)
728
+ @panels[_domain_name]['notebook'].raise(_name) if @panels[_domain_name] && @panels[_domain_name]['notebook']
729
+ end
730
+
731
+ def [](_row, _col)
732
+ @frames[_row][_col]
733
+ end
734
+
735
+ def frame(_domain_name, _name)
736
+ @panels[_domain_name]['sons'][_name].frame
737
+ end
738
+
739
+ def domain(_domain_name)
740
+ @panels[_domain_name]
741
+ end
742
+
743
+ def domain_root_frame(_domain_name)
744
+ @panels[_domain_name]['root'].frame
745
+ end
746
+ end
747
+
748
+ Arcadia.new.run