1GtkTextBuffer extend [
2
3    insertAtEnd: aString [
4        <category: 'accessing'>
5
6        self insert: self getEndIter text: aString
7    ]
8]
9
10
11GtkAlignment class extend [
12    new [
13	<category: 'instance creation'>
14        ^self new: 0 yalign: 0 xscale: 1 yscale: 1
15    ]
16]
17
18
19GObject class extend [
20    new [
21	<category: 'instance creation'>
22        ^self new: self getType varargs: #(nil)
23    ]
24]
25
26
27GList extend [
28    do: aOneArgBlock [
29	<category: 'iterating'>
30	| iter |
31	iter := self.
32	[ iter isNull not ] whileTrue: [
33	    aOneArgBlock value: iter data value.
34	    iter := iter next value ]
35    ]
36]
37
38
39GdkDrawable extend [
40
41    withContextDo: aBlock [
42	"Execute aBlock passing a valid Cairo context for the
43	 window.  The context is invalidated after aBlock returns."
44
45	<category: 'accessing'>
46	| context |
47	[ aBlock value: (context := Cairo.CairoContext context: self cairoCreate) ]
48	    ensure: [ context isNil ifFalse: [ context release ] ]
49    ]
50
51]
52
53GtkWidget extend [
54
55    getSizeRequest [
56	"Answer the size the widget has requisitioned."
57
58	<category: 'accessing'>
59	| requisition |
60	requisition := GTK.GtkRequisition new.
61	self sizeRequest: requisition.
62	^requisition asPoint
63    ]
64
65]
66
67
68
69GtkMessageDialog class extend [
70
71    new: parent flags: flags type: type buttons: buttons message: message [
72	<category: 'instance creation'>
73	^self
74	    new: parent
75	    flags: flags
76	    type: type
77	    buttons: buttons
78	    messageFormat: '%s'
79	    varargs: {message}
80    ]
81
82    new: parent flags: flags type: type buttons: buttons message: message tip: tip [
83	<category: 'instance creation'>
84	^self
85	    newWithMarkup: parent
86	    flags: flags
87	    type: type
88	    buttons: buttons
89	    messageFormat: '<big><b>%s</b></big>
90
91%s'
92	    varargs: {message. tip}
93    ]
94
95    newWithMarkup: parent flags: flags type: type buttons: buttons message: message [
96	<category: 'instance creation'>
97	^self
98	    newWithMarkup: parent
99	    flags: flags
100	    type: type
101	    buttons: buttons
102	    messageFormat: (message copyReplaceAll: '%' with: '%%')
103	    varargs: #()
104    ]
105]
106
107
108
109GtkRequisition class extend [
110
111    fromPoint: point [
112	<category: 'instance creation'>
113	| ba |
114	ba := (CShortType arrayType: 2) new.
115	ba at: 0 put: point x.
116	ba at: 1 put: point y.
117	^(ba castTo: self type)
118	    addToBeFinalized;
119	    yourself
120    ]
121
122]
123
124
125
126GtkRequisition extend [
127
128    x [
129	<category: 'accessing'>
130	| ba |
131	ba := self castTo: (CShortType arrayType: 4).
132	^ba at: 0
133    ]
134
135    y [
136	<category: 'accessing'>
137	| ba |
138	ba := self castTo: (CShortType arrayType: 4).
139	^ba at: 1
140    ]
141
142    asPoint [
143	<category: 'conversion'>
144	^
145	{self width value.
146	self height value}
147    ]
148
149]
150
151
152
153GdkRectangle class extend [
154
155    fromRectangle: rect [
156	<category: 'instance creation'>
157	| ba |
158	ba := (CShortType arrayType: 4) new.
159	ba at: 0 put: rect left.
160	ba at: 1 put: rect top.
161	ba at: 2 put: rect width.
162	ba at: 3 put: rect height.
163	^(ba castTo: self type)
164	    addToBeFinalized;
165	    yourself
166    ]
167
168]
169
170
171
172GdkRectangle extend [
173
174    left [
175	<category: 'accessing'>
176	| ba |
177	ba := self castTo: (CShortType arrayType: 4).
178	^ba at: 0
179    ]
180
181    top [
182	<category: 'accessing'>
183	| ba |
184	ba := self castTo: (CShortType arrayType: 4).
185	^ba at: 1
186    ]
187
188    right [
189	<category: 'accessing'>
190	| ba |
191	ba := self castTo: (CShortType arrayType: 4).
192	^(ba at: 0) + (ba at: 2)
193    ]
194
195    bottom [
196	<category: 'accessing'>
197	| ba |
198	ba := self castTo: (CShortType arrayType: 4).
199	^(ba at: 1) + (ba at: 3)
200    ]
201
202    width [
203	<category: 'accessing'>
204	| ba |
205	ba := self castTo: (CShortType arrayType: 4).
206	^ba at: 2
207    ]
208
209    height [
210	<category: 'accessing'>
211	| ba |
212	ba := self castTo: (CShortType arrayType: 4).
213	^ba at: 3
214    ]
215
216    origin [
217	<category: 'accessing'>
218	| ba |
219	ba := self castTo: (CShortType arrayType: 4).
220	^(ba at: 0) @ (ba at: 1)
221    ]
222
223    extent [
224	<category: 'accessing'>
225	| ba |
226	ba := self castTo: (CShortType arrayType: 4).
227	^(ba at: 2) @ (ba at: 3)
228    ]
229
230    corner [
231	<category: 'accessing'>
232	| ba |
233	ba := self castTo: (CShortType arrayType: 4).
234	^((ba at: 0) + (ba at: 2)) @ ((ba at: 1) + (ba at: 3))
235    ]
236
237    asRectangle [
238	<category: 'conversion'>
239	| ba |
240	ba := self castTo: (CShortType arrayType: 4).
241	^(ba at: 0) @ (ba at: 1) extent: (ba at: 2) @ (ba at: 3)
242    ]
243
244]
245
246
247
248GtkTreeIter class extend [
249
250    Prototype := nil.
251
252    gcNew [
253	^self type gcNew
254    ]
255
256    new [
257	<category: 'instance creation'>
258        Prototype isNil ifTrue: [ Prototype := self type gcNew ].
259	^Prototype copy
260	    addToBeFinalized;
261	    yourself
262    ]
263
264]
265
266
267
268GtkTextIter class extend [
269
270    Prototype := nil.
271
272    gcNew [
273	^self type gcNew
274    ]
275
276    new [
277	<category: 'instance creation'>
278        Prototype isNil ifTrue: [ Prototype := self type gcNew ].
279	^Prototype copy
280	    addToBeFinalized;
281	    yourself
282    ]
283
284]
285
286
287
288GtkTreeModel extend [
289
290    getIter: path [
291	<category: 'accessing'>
292	| iter |
293	iter := GTK.GtkTreeIter new.
294	^(self getIter: iter path: path) ifTrue: [iter] ifFalse: [nil]
295    ]
296
297    getIterFirst [
298	<category: 'accessing'>
299	| iter |
300	iter := GTK.GtkTreeIter new.
301	self getIterFirst: iter.
302	^iter
303    ]
304
305    iterChildren: parent [
306	<category: 'accessing'>
307	| iter |
308	iter := GTK.GtkTreeIter new.
309	self iterChildren: iter parent: parent.
310	^iter
311    ]
312
313    iterNthChild: parent n: n [
314	<category: 'accessing'>
315	| iter |
316	iter := GTK.GtkTreeIter new.
317	self
318	    iterNthChild: iter
319	    parent: parent
320	    n: n.
321	^iter
322    ]
323
324    iterParent: child [
325	<category: 'accessing'>
326	| iter |
327	iter := GTK.GtkTreeIter new.
328	self iterParent: iter child: child.
329	^iter
330    ]
331
332]
333
334
335
336GtkTreeSelection extend [
337
338    getSelected [
339	<category: 'accessing'>
340	| has iter |
341	iter := GTK.GtkTreeIter new.
342	has := self getSelected: nil iter: iter.
343	^has ifTrue: [iter] ifFalse: [nil]
344    ]
345
346]
347
348
349
350GtkListStore extend [
351
352    insert: anInteger [
353	<category: 'accessing'>
354	| iter |
355	iter := GTK.GtkTreeIter new.
356	self insert: iter position: anInteger.
357	^iter
358    ]
359
360    insertBefore: sibling [
361	<category: 'accessing'>
362	| iter |
363	iter := GTK.GtkTreeIter new.
364	self insertBefore: iter sibling: sibling.
365	^iter
366    ]
367
368    insertAfter: sibling [
369	<category: 'accessing'>
370	| iter |
371	iter := GTK.GtkTreeIter new.
372	self insertAfter: iter sibling: sibling.
373	^iter
374    ]
375
376    prepend [
377	<category: 'accessing'>
378	| iter |
379	iter := GTK.GtkTreeIter new.
380	self prepend: iter.
381	^iter
382    ]
383
384    append [
385	<category: 'accessing'>
386	| iter |
387	iter := GTK.GtkTreeIter new.
388	self append: iter.
389	^iter
390    ]
391
392]
393
394
395
396GtkTextBuffer extend [
397
398    setText: aString [
399	"Set my contents"
400
401	<category: 'accessing'>
402	self setText: aString len: aString size
403    ]
404
405    insertAtCursor: aString [
406	"Insert aString at the curser."
407
408	<category: 'accessing'>
409	self insertAtCursor: aString len: aString size
410    ]
411
412    getBounds [
413	"Answer my entire contents."
414
415	<category: 'accessing'>
416	| start end |
417	start := GTK.GtkTextIter new.
418	end := GTK.GtkTextIter new.
419	self getBounds: start end: end.
420	^
421	{start.
422	end}
423    ]
424
425    getIterAtMark: mark [
426	"Answer an iterator for mark"
427
428	<category: 'accessing'>
429	| iter |
430	iter := GTK.GtkTextIter new.
431	self getIterAtMark: iter mark: mark.
432	^iter
433    ]
434
435    getSelectionBounds [
436	"Answer my selection bounds"
437
438	<category: 'accessing'>
439	| start end |
440	start := GTK.GtkTextIter new.
441	end := GTK.GtkTextIter new.
442	self getSelectionBounds: start end: end.
443	^
444	{start.
445	end}
446    ]
447
448    getIterAtLine: line [
449	"Answer an iterator at the beginning of line."
450
451	<category: 'accessing'>
452	| result |
453	result := GTK.GtkTextIter new.
454	self getIterAtLine: result lineNumber: line.
455	^result
456    ]
457
458    getIterAtLineOffset: lineNumber charOffset: charOffset [
459	"Answer an iterator at offset in me."
460
461	<category: 'accessing'>
462	| result |
463	result := GTK.GtkTextIter new.
464	self
465	    getIterAtLineOffset: result
466	    lineNumber: lineNumber
467	    charOffset: charOffset.
468	^result
469    ]
470
471    getStartIter [
472	"Answer a start iterator."
473
474	<category: 'accessing'>
475	| result |
476	result := GTK.GtkTextIter new.
477	self getStartIter: result.
478	^result
479    ]
480
481    getEndIter [
482	"Answer an end iterator"
483
484	<category: 'accessing'>
485	| result |
486	result := GTK.GtkTextIter new.
487	self getEndIter: result.
488	^result
489    ]
490
491    insert: iter text: aString [
492	"Insert aString at the insertion point."
493
494	<category: 'accessing'>
495	self
496	    insert: iter
497	    text: aString
498	    len: aString size
499    ]
500
501]
502
503
504
505Gtk class extend [
506    | loop |
507
508    mainQuit [
509        loop quit
510    ]
511
512    main [
513	"Main loop implementation.  Same as gtk_main, but it splits
514         g_main_context_run in two threads so that Smalltalk processes
515         run.  Like gtk_main, it is ended with Gtk>>#mainQuit."
516
517	<category: 'event loop'>
518	| sem newLoop context |
519	sem := Semaphore new.
520	newLoop := GTK.Gtk main: sem.
521        newLoop isNil ifTrue: [ ^self ].
522        loop := newLoop.
523        context := loop getContext.
524
525	[
526            [sem wait.
527	    context iterate.
528            loop isRunning] whileTrue]
529                 ensure: [loop unref]
530    ]
531
532]
533
534
535
536GtkAccelGroup class extend [
537
538    acceleratorParse: accelerator [
539	<category: 'C call-outs'>
540
541	| cAccKey cAccMod |
542	cAccKey := CInt gcValue: 0.
543	cAccMod := CInt gcValue: 0.
544	GTK.Gtk acceleratorParse: accelerator acceleratorKey: cAccKey acceleratorMods: cAccMod.
545	^ {cAccKey value. cAccMod value}
546    ]
547
548    acceleratorGroup: aGtkAccelGroup accelerator: aString path: aPathString [
549	<category: 'C call-outs'>
550
551	| result |
552	result := self acceleratorParse: aString.
553	GTK.GtkAccelMap addEntry: aPathString accelKey: result first accelMods: result second
554    ]
555]
556
557
558GtkAccelGroup extend [
559
560    append: anArray [
561        <category: 'accessing'>
562
563        anArray do: [ :each |
564            self class
565                acceleratorGroup: self
566                accelerator: each first
567                path: each second ]
568    ]
569]
570
571
572
573GtkButton class extend [
574
575    label: aString onPressedSend: aSymbol to: anObject [
576    <category: 'instance creation'>
577
578    ^ (GTK.GtkButton newWithLabel: aString)
579        connectSignal: 'pressed' to: anObject selector: aSymbol userData: nil;
580        yourself
581    ]
582]
583
584
585GTK.GtkDialog extend [
586    run [
587        <category: 'services'>
588
589        | signals sema answer modal destroyed |
590        sema := Semaphore new.
591        modal := self getModal.
592        self setModal: true.
593        signals := {
594            self
595                connectSignal: 'response'
596                to: [ :dialog :integer | answer := integer. sema signal ]
597                selector: #value:value:.
598
599            self
600                connectSignal: 'unmap'
601                to: sema
602                selector: #signal.
603
604            self
605                connectSignal: 'delete_event'
606                to: [ answer := Gtk gtkResponseDeleteEvent. sema signal. true ]
607                selector: #value.
608
609            self
610                connectSignal: 'destroy'
611                to: [ destroyed := true ]
612                selector: #value }.
613
614        self show.
615        sema wait.
616        destroyed ifFalse: [
617            self setModal: modal.
618            signals do: [ :each | self disconnectSignal: each ] ].
619        ^answer
620    ]
621]
622
623
624GTK.GtkFileChooserDialog class extend [
625
626    for: aGtkFileChooserAction title: aString parent: aGtkWidget button: aGtkStock  [
627        <category: 'instance creation'>
628
629        ^ self
630            new: aString
631            parent: aGtkWidget
632            action: aGtkFileChooserAction
633            varargs: {GTK.Gtk gtkStockCancel.
634                    GTK.Gtk gtkResponseCancel.
635                    aGtkStock.
636                    GTK.Gtk gtkResponseAccept.
637                    nil}
638    ]
639
640    save: aString parent: aGtkWidget [
641        <category: 'instance creation'>
642
643        ^ self
644            for: GTK.Gtk gtkFileChooserActionSave
645            title: aString
646            parent: aGtkWidget
647            button: GTK.Gtk gtkStockSave
648    ]
649
650    load: aString parent: aGtkWidget [
651        <category: 'instance creation'>
652
653        ^ self
654            for: GTK.Gtk gtkFileChooserActionOpen
655            title: aString
656            parent: aGtkWidget
657            button: GTK.Gtk gtkStockOpen
658    ]
659
660    selectFolder: aString parent: aGtkWidget [
661        <category: 'instance creation'>
662
663        ^ self
664            for: GTK.Gtk gtkFileChooserActionSelectFolder
665            title: aString
666            parent: aGtkWidget
667            button: GTK.Gtk gtkStockOpen
668    ]
669]
670
671
672GTK.GtkListStore extend [
673
674    appendItem: anArray [
675	<category: 'accessing'>
676
677	| iter |
678	iter := self append.
679	self at: iter put: anArray.
680	^ iter
681    ]
682
683    prependItem: anArray [
684        <category: 'accessing'>
685
686        | iter |
687        iter := self prepend.
688        self at: iter put: anArray.
689        ^ iter
690    ]
691
692    itersDo: aBlock [
693	<category: 'accessing'>
694
695	| iter |
696	((iter := self getIterFirst) isNil or: [ (self iterIsValid: iter) not ] ) ifTrue: [ ^ nil ].
697	aBlock value: iter.
698	[ self iterNext: iter ] whileTrue: [ aBlock value: iter ]
699    ]
700
701    do: aBlock [
702	<category: 'accessing'>
703
704	self itersDo: [ :iter |
705	    aBlock value: (self at: iter) value: iter ]
706    ]
707
708    lastIter [
709	<category: 'accessing'>
710
711	| lastIter iter path |
712	iter := lastIter := GTK.GtkTreeIter new.
713	path := GTK.GtkTreePath newFirst.
714	[ self getIter: iter path: path ] whileTrue: [
715	    lastIter := iter.
716	    iter := GTK.GtkTreeIter new.
717            path next ].
718	^ lastIter
719    ]
720]
721
722
723GTK.GtkMenuItem class extend [
724
725    menuItem: aString connectTo: anObject selector: aSymbol userData: userData [
726	<category: 'instance creation'>
727
728	^ (self newWithLabel: aString)
729	    connectSignal: 'activate' to: anObject selector: aSymbol userData: userData;
730	    yourself
731    ]
732
733    menuItem: aString connectTo: anObject selector: aSymbol [
734        <category: 'instance creation'>
735
736        ^ self menuItem: aString connectTo: anObject selector: aSymbol userData: nil
737    ]
738
739    menuItem: aString accelPath: anAccelPathString [
740	<category: 'instance creation'>
741
742	^ (self newWithLabel: aString)
743	    setAccelPath: anAccelPathString;
744	    yourself
745    ]
746
747    menuItem: aString accelPath: anAccelPathString connectTo: anObject selector: aSymbol [
748        <category: 'instance creation'>
749
750        ^ (self menuItem: aString accelPath: anAccelPathString)
751            connectSignal: 'activate' to: anObject selector: aSymbol userData: nil;
752            yourself
753    ]
754]
755
756
757GTK.GtkMenu extend [
758
759    appendSeparator [
760    <category: 'accessing'>
761
762    self append: GTK.GtkMenuItem new
763    ]
764
765    appendMenuItems: anArray [
766    <category: 'accessing'>
767
768    anArray do: [ :each |
769        self append:
770	(each isEmpty
771	    ifTrue: [ GTK.GtkMenuItem new ]
772	    ifFalse: [ (GTK.GtkMenuItem newWithLabel: (each at: 1))
773		connectSignal: 'activate' to: (each at: 2) selector: (each at: 3) userData: nil;
774		yourself ]) ]
775    ]
776]
777
778
779GTK.GtkScrolledWindow class extend [
780
781    withChild: aGtkWidget [
782    <category: 'instance creation'>
783
784    ^ (GTK.GtkScrolledWindow new: nil vadjustment: nil)
785        add: aGtkWidget;
786        setPolicy: GTK.Gtk gtkPolicyAutomatic vscrollbarPolicy: GTK.Gtk gtkPolicyAutomatic;
787        yourself
788    ]
789]
790
791
792GTK.GtkTextBuffer extend [
793
794    text [
795    <category: 'accessing'>
796
797    ^ self getText: self getStartIter end: self getEndIter includeHiddenChars: false
798    ]
799
800    applyTagByName: aSymbol startOffset: aStartInteger endOffset: anEndInteger [
801    <category: 'accessing'>
802
803    | end start |
804    start := GTK.GtkTextIter new.
805        end := GTK.GtkTextIter new.
806        self getIterAtOffset: start charOffset: aStartInteger.
807        self getIterAtOffset: end charOffset: anEndInteger.
808        self applyTagByName: aSymbol start: start end: end
809    ]
810
811    getIterAtOffset: offset [
812    <category: 'accessing'>
813
814    | result |
815    result := GTK.GtkTextIter new.
816    self getIterAtOffset: result charOffset: offset.
817    ^ result
818    ]
819
820    iterOfSelectedText [
821        <category: 'text accessing'>
822
823        | iter |
824        self getHasSelection
825                ifTrue: [ iter := self getSelectionBounds ifNil: [ ^ self ].
826                        (iter at: 1) getOffset > ((iter at: 2) getOffset)
827                            ifTrue: [ iter swap: 1 with: 2 ] ]
828                ifFalse: [ iter := {self getStartIter. self getEndIter} ].
829        ^ iter
830    ]
831
832    selectedText [
833        <category: 'text accessing'>
834
835        | iter |
836        iter := self iterOfSelectedText.
837        ^ self getText: (iter at: 1) end: (iter at: 2) includeHiddenChars: false
838    ]
839]
840
841
842GTK.GtkTreeModel extend [
843
844    at: aGtkTreeIter [
845        <category: 'accessing'>
846
847        | values |
848        aGtkTreeIter ifNil: [ ^ nil ].
849        values := OrderedCollection new.
850        0 to: self getNColumns - 1 do: [ :column |
851            values add: (self at: aGtkTreeIter column: column) ].
852        ^ values
853    ]
854
855    at: aGtkTreeIter column: anInteger [
856        <category: 'accessing'>
857
858        ^ self getOop: aGtkTreeIter column: anInteger
859    ]
860
861    at: aGtkTreeIter column: anInteger put: anObject [
862        <category: 'accessing'>
863
864        self setOop: aGtkTreeIter column: anInteger value: anObject
865    ]
866
867    at: aGtkTreeIter put: anArray [
868        <category: 'accessing'>
869
870        1 to: anArray size do: [ :i |
871            self at: aGtkTreeIter column: i - 1 put: (anArray at: i) ]
872    ]
873
874    at: aGtkTreeIter do: aBlock [
875	<category: 'accessing'>
876
877	(self at: aGtkTreeIter) do: aBlock
878    ]
879
880    itersDo: aBlock iter: aGtkTreeIter [
881	<category: 'accessing'>
882
883	| childIter |
884	childIter := GTK.GtkTreeIter new.
885	aBlock value: aGtkTreeIter.
886	(self iterChildren: childIter parent: aGtkTreeIter) ifTrue: [ self itersDo: aBlock iter: childIter ].
887	[ self iterNext: aGtkTreeIter ] whileTrue: [
888	    aBlock value: aGtkTreeIter.
889            (self iterChildren: childIter parent: aGtkTreeIter) ifTrue: [ self itersDo: aBlock iter: childIter ] ]
890    ]
891
892    itersDo: aBlock [
893	<category: 'accessing'>
894
895	| iter child |
896	((iter := self getIterFirst) isNil or: [ (self iterIsValid: iter) not ] ) ifTrue: [ ^ nil ].
897	self itersDo: aBlock iter: iter
898    ]
899
900    do: aBlock [
901        <category: 'accessing'>
902
903        self itersDo: [ :iter |
904            aBlock value: (self at: iter) value: iter ]
905    ]
906]
907
908
909GTK.GtkTreeStore extend [
910
911    itersDo: aBlock iter: aGtkTreeIter [
912	<category: 'accessing'>
913
914	| childIter |
915	childIter := GTK.GtkTreeIter new.
916	aBlock value: aGtkTreeIter.
917	(self iterChildren: childIter parent: aGtkTreeIter) ifTrue: [ self itersDo: aBlock iter: childIter ].
918	[ self iterNext: aGtkTreeIter ] whileTrue: [
919	    aBlock value: aGtkTreeIter.
920            (self iterChildren: childIter parent: aGtkTreeIter) ifTrue: [ self itersDo: aBlock iter: childIter ] ]
921    ]
922
923    itersDo: aBlock [
924	<category: 'accessing'>
925
926	| iter child |
927	((iter := self getIterFirst) isNil or: [ (self iterIsValid: iter) not ] ) ifTrue: [ ^ nil ].
928	self itersDo: aBlock iter: iter
929    ]
930
931    do: aBlock [
932        <category: 'accessing'>
933
934        self itersDo: [ :iter |
935            aBlock value: (self at: iter) value: iter ]
936    ]
937
938    appendItem: anArray [
939	<category: 'accessing'>
940
941	^ self append: nil item: anArray
942    ]
943
944    append: aGtkTreeIter item: anArray [
945	<category: 'accessing'>
946
947        | iter |
948        iter := GTK.GtkTreeIter new.
949        self
950	    append: iter parent: aGtkTreeIter;
951	    at: iter put: anArray.
952	^ iter
953    ]
954]
955
956
957GTK.GtkTreeView class extend [
958
959    newWith: aGtkModel columns: anArray [
960        <category: 'user interface'>
961
962        | view |
963        view := self new.
964	view setModel: aGtkModel.
965	anArray keysAndValuesDo: [ :i :each || col render |
966	    col := (GtkTreeViewColumn new)
967		    packStart: (render := each key = 'text' ifFalse: [ GTK.GtkCellRendererPixbuf new ] ifTrue: [ GTK.GtkCellRendererText new ]) expand: true;
968		    addAttribute: render attribute: each key column: i - 1;
969		    yourself.
970	    each value isEmpty ifFalse: [ col setTitle: each value ].
971	    view insertColumn: col position: -1 ].
972	^ view
973    ]
974
975    newWith: aGtkModel pack: anArray title: aString [
976        <category: 'user interface'>
977
978        | view col |
979        view := self new.
980	view setModel: aGtkModel.
981	col := GtkTreeViewColumn new.
982	anArray keysAndValuesDo: [ :i :each || render |
983	    col
984		packStart: (render := each = 'text' ifFalse: [ GTK.GtkCellRendererPixbuf new ] ifTrue: [ GTK.GtkCellRendererText new ]) expand: each = 'text';
985		addAttribute: render attribute: each column: i - 1 ].
986	col setTitle: aString.
987	view insertColumn: col position: -1.
988	^ view
989    ]
990
991    newWithTextColumn: aGtkModel title: aString [
992        <category: 'user interface'>
993
994        | view col render |
995        view := self new
996	    setModel: aGtkModel;
997	    yourself.
998        col := (GtkTreeViewColumn new)
999	    packStart: (render := GTK.GtkCellRendererText new) expand: true;
1000	    addAttribute: render attribute: 'text' column: 0;
1001	    setTitle: aString;
1002	    yourself.
1003        view insertColumn: col position: -1.
1004    ^ view
1005    ]
1006
1007    newWithSortedTextColumn: aGtkModel title: aString [
1008    <category: 'instance creation'>
1009
1010        | view col render |
1011        view := self new
1012                    setModel: aGtkModel;
1013                    yourself.
1014        col := (GtkTreeViewColumn new)
1015                packStart: (render := GtkCellRendererText new) expand: true;
1016                addAttribute: render attribute: 'text' column: 0;
1017                setTitle: aString;
1018                setSortIndicator: true;
1019                setSortColumnId: 0;
1020                setSortOrder: Gtk gtkSortAscending;
1021                yourself.
1022        view
1023            insertColumn: col position: -1.
1024    ^ view
1025    ]
1026]
1027
1028GTK.GtkTreeView extend [
1029
1030    hasSelectedItem [
1031	<category: 'accessing'>
1032
1033	^ self getSelection getSelected isNil not
1034    ]
1035
1036    numberOfItems [
1037	<category: 'accessing'>
1038
1039	^ self getModel iterNChildren: nil
1040    ]
1041
1042    selectedIter [
1043	<category: 'accessing'>
1044
1045	^ self getSelection getSelected
1046    ]
1047
1048    selectedIndex [
1049	<category: 'accessing'>
1050
1051	self hasSelectedItem ifFalse: [ self error: 'Nothing is selected' ].
1052	^ (self getModel getPath: self selectedIter) getIndices value + 1
1053    ]
1054]
1055
1056
1057GTK.GtkToolButton class extend [
1058    newFromStock: icon label: aString [
1059        ^(self newFromStock: icon)
1060	    setLabel: aString;
1061	    yourself
1062    ]
1063]
1064
1065
1066"Finish initialization.  This will be done upon #returnFromSnapshot on
1067 subsequent image loads."
1068
1069Eval [
1070    GLib registerAllTypes
1071]
1072
1073