r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3 GUI]

Robert
23-Jan-2010
[148]
I have used such an approach in one of our apps.For example I have 
three tables, that depending on the app state, show different columns 
and data. So, when app state switches this will trigger the change 
of the tables.


And other example is changing the language just where you are. No 
need to re-enter the current GUI etc. There will be just a change-lang 
XY event send.
Graham
24-Jan-2010
[149]
Wasn't Max proposing a message passing gui in one of his various 
liquid thingies?
Maxim
24-Jan-2010
[150x7]
liquid is a message passing engine, but its complex to use in guis 
as-is.  it can be done (as I shown a few times) but requires a dialect 
or api over it to manage it.
just to make it simpler to use in real world use.
the advantage is that its a generic engine... and can be used to 
link up any aspect of an app. not just its "actions"
for example, right now, in my pain application, if you replace the 
bg-image of the canvas, it refreshes the whole software on its own. 
 the size of the canvas, the crop bars, image properties and input 
management offsets, etc, etc.
but in this app there is no dialect of api beyond the shape/graphic 
element management.
so its not readily obvious just how much goes on in the application 
without following the links in the code.
this app will be released this week.
Graham
24-Jan-2010
[157]
no pain no gain
Pekr
24-Jan-2010
[158]
I think we just need to finish R3 GUI as Carl started it (VID 3.4). 
We might think about some by Max proposed enhancements to Draw, making 
GUI kernel more powefull, and let's see, where it leads us, before 
we start to think about another overhaul. Msg passing concept is 
surely interesting, but it imo creates another layer to implement, 
understand, to work with, so I am just not sure, unless I see the 
currently implemented solution does not allow us to easily work/extend 
the GUI.
Maxim
24-Jan-2010
[159]
exactly what I think.  keep it simple for now... once liquid is revamped 
for R3 we can see how I can make a module to add it so view 3.4, 
just like I did for view R2.
Pekr
24-Jan-2010
[160x2]
by Draw enhancements above, I mean proposal by max, making it "first 
class citizen", so removing the overhead of draw dialect ... but 
that is for gurus to think about :-)
see msg 8-Jan, 15:34
Henrik
24-Jan-2010
[162x2]
Carl's original goal for the GUI was to make it so a child could 
use it. We should not deviate from that goal. That's part of what 
Rebrowse is meant to do. I don't want to risk a forking of the GUI 
work.
I don't mind advanced features at all, but we must be careful not 
to make the GUI difficult to use from the outset or having to place 
the user into a specific mindset, when starting to learn it.
Maxim
24-Jan-2010
[164]
there is VID and there is View.  we must not sacrifice the later 
for the former.
Pekr
24-Jan-2010
[165]
exaclty. I think that VID3.4 is designed in a good way, let's first 
see, if the architecture provides us everything we need ...
Maxim
24-Jan-2010
[166]
to me VID always very easy to use.  making it pretty & dynamic ... 
well that's a bit (a lot ;-) more painfull.
Henrik
24-Jan-2010
[167]
I think it's possible to make it strong for industrial strength applications, 
without making the usability a hindrance. I also wouldn't want to 
lose the ability to write a GUI in 2 minutes for your boss to use.
Maxim
24-Jan-2010
[168x3]
We all agree on that, but I just want to raise the point that a lot 
of the short commings in view are based on some serious issues in 
VID.
oops... hehe shortcommings in VID are based on those in View... heheh
view is already much more powerfull now, but I feel that the current 
design is like going half way. 


instead of having a totally open level 1 (gfx engine) on which level 
2 (view) and level 3 (VID) is built, we have level 1.5 and level 
3

and I mean within REBOL, not within C.
Henrik
24-Jan-2010
[171]
Most of VID's serious issues come down to event handling (solvable 
now) and incompleteness (also solvable, just a bunch of hard work) 
and missing features, like keyboard navigation (already solved that). 
The VID extension kit makes VID much more scalable, simply by finishing 
the work that Carl set out to do. It's easier to write large apps 
because styles are more uniform, and you have more powerful features 
and adherence to face accessors, rather than relying on face hacking.


Building those features into V3.4 by default, and you have a killer 
UI system without sacrificing usability.
Maxim
24-Jan-2010
[172x2]
glayout already implements 90% of what we want to build for VID 3.4, 
down to the dynamic layout engine, which is just about the same.
themes are a 2 function addition, and localisation would be a single 
function to add.
Henrik
24-Jan-2010
[174]
It's important to lift the UI out of the domain of appearance and 
into the domain of meaning. When your UI intelligently finds the 
default window close button or the first field in a form automatically, 
and automatically assigns correct keyboard navigation shortcuts, 
because of the underlying architecture's emphasis on meaning, there's 
no need to write any code to handle that at all. It's just there. 
You build your styles to adhere to the meaning that was setup by 
the GUI system. In the VID extension kit, this is done through flags 
and powerful face handling features. You don't need to add any code 
for that in the dialect.
Maxim
24-Jan-2010
[175x2]
but VID R2 has some very serious platform limits which we can bypass... 
which is nice to be able to have access to in the next implementation 
of R3 View which is outside the core dll.
can=can't
Pekr
24-Jan-2010
[177]
Max - so what do you propose for the kernel, to not be 1.5 and 3, 
but 1, 2, 3? :-)
Maxim
24-Jan-2010
[178x2]
:-P
it could be 1, 1.5, and 3 also if people like how gobs are currently 
structured. :-)
Pekr
24-Jan-2010
[180]
so what comes into "1"? :-)
Maxim
24-Jan-2010
[181]
gels = graphic elements
Graham
24-Jan-2010
[182x4]
We already have message passing, and these messages are events.
So, maybe we need to have the ability to define custom events and 
have custom event handlers.
I was never convinced by Max's liquid thingy as even as the author, 
he was not readily able to cook up anything other than the most simple 
of demos.
As for semantic meaning in styles ... I think that remains to be 
proven
Pekr
24-Jan-2010
[186]
Graham - IIRC, custom generated events were planned since the very 
beginning? But they are not probably implemented/enabled yet .....
Graham
24-Jan-2010
[187]
Or maybe the docs are just not upto date
Ashley
25-Jan-2010
[188x3]
I've spent a bit of time going over R3/View and believe it now has 
all the "building blocks" required to build a modern/fast gob! based 
GUI. The amazing thing is that these building blocks are the 10 natives 
that View adds [to Core]. They are:

	gob!
	caret-to-offset
	cursor
	draw
	effect
	map-event
	map-gob-offset
	offset-to-caret
	show
	size-text


With these 10 natives (gob! is actually a type!) we should be able 
to construct simple but powerfull gob!-based GUIs with a smaller 
mezz footprint than R2. My preliminary conversion of RebGUI to R3 
seems to take about 50% the code to do the same thing [compared to 
R2] ... very promising at first glance.


To get a feeling for how tight the code can be the next post is the 
entire [skeleton] source of a working gob!-based GUI.
ctx-rebgui3: make object! [

	cursors: make object! [
		app-start: 32650
		hand: 32649
		help: 32651
		hourglass: 32650
		arrow: 32512
		cross: 32515
		i-shape: 32513
		no: 32648
		size-all: 32646
		size-nesw: 32643
		size-ns: 32645
		size-nwse: 32642
		size-we: 32644
		up-arrow: 32516
		wait: 32514
	]

	colors: make object! [
		page: white
		edit: white
		text: black
		true: leaf
		false: red
		link: blue
		theme: [165.217.246 0.105.207 0.55.155]
		outline: [207.207.207 160.160.160 112.112.112]
	]

	metrics: make object! [
		cell: 4
		gap: cell * 2
		line: cell * 5
		margin: cell * 4
		margin-size: as-pair margin margin
		radius: 2
	]

	;	Private functions

	set 'make-gob make function! [[

  spec [block!] ; offset, size and one or more attribute/value pairs
		/data object
		/local size text gob axis
	][
		size: spec/2
		if any [negative? size/x negative? size/y] [
			text: select spec 'text
			all [block? text text: first find text string!]

   size: 8x4 + size-text make gob! compose [size: 9999x9999 text: (text)]
			all [negative? spec/2/x spec/2/x: size/x]
			all [negative? spec/2/y spec/2/y: size/y]
		]
		gob: copy []
		;	attributes are (text, color, effect, image and draw)
		foreach [attribute value] spec [
			switch attribute [
				box [
					attribute: 'draw
					value: compose [
						pen (get value/1)
						line-width 1
						fill-pen (get value/2)
						box 0x0 (spec/2 - 1x1) (metrics/radius)
					]
				]
				pill [
					attribute: 'draw
					axis: either spec/2/x >= spec/2/y [2] [1]
					value: compose/deep [
						pen (colors/outline/3)
						line-width 1

      grad-pen linear (spec/2/:axis * .1) (spec/2/:axis * .9) (all [axis 
      = 2 90]) [(colors/outline/1) (white) (colors/outline/1)]
						box 0x0 (spec/2 - 1x1) (metrics/radius)
					]
				]
			]
			append gob reduce [attribute value]
		]
		spec: gob

  gob: make gob! compose [offset: spec/1 size: spec/2 (to set-word! 
  spec/3) spec/4 data: (make object! any [object copy []])]
		foreach [attribute value] skip spec 2 [

   append gob make gob! compose [offset: 0x0 size: spec/2 (to set-word! 
   attribute) value]
		]
		gob
	]]

	;	Public functions

	set 'display make function! [[
		title spec

  /local gob xy max-x max-y left-to-right? after-count after-limit 
  here arg append-widget widget last-widget word
		action
		handler
		size
		text
		color
	][
		xy: metrics/margin-size
		max-x: xy/x
		max-y: xy/y
		left-to-right?: true
		after-count: 1
		after-limit: 9999
		
		gob: make gob! compose [text: (title) data: (make object! [])]

		append-widget: make function! [[][
			unless widget [exit]
			unless handler [

    handler: compose/deep [on-down: make function! [[event][(action)]]]
			]
			append gob switch widget [
				bar [

     make-gob compose [(xy) (as-pair max-x - metrics/margin 1) color (colors/outline/3)]
				]
				button [
					all [none? size size: 15x5]

     make-gob/data compose/deep [(xy) (size * metrics/cell) pill none 
     text [center (text)]] handler
				]
				text [
					all [none? size size: 15x5]

     make-gob/data compose/only [(xy) (size * metrics/cell) color (white) 
     text (text)] handler
				]
			]
			last-widget: last gob/pane
			;	1st reverse item?
			unless left-to-right? [

    last-widget/offset/x: last-widget/offset/x - last-widget/size/x
			]
			xy: last-widget/offset
			;	max vertical size
			max-y: max max-y xy/y + last-widget/size/y
			;	horizontal pos adjustments
			all [
				left-to-right?
				xy/x: xy/x + last-widget/size/x
				max-x: max max-x xy/x
			]
			;	after limit reached?
			either after-count < after-limit [
				;	spacing

    xy/x: xy/x + either left-to-right? [metrics/gap] [negate metrics/gap]
				++ after-count
			] [
				xy: as-pair metrics/margin max-y + metrics/gap
				after-count: 1
			]
			all [:word set :word last-widget]
			word: widget: action: handler: size: text: color: none
		]]


  parse reduce/only spec [after bar button handler return reverse rich 
  text] [
			any [
				opt [here: set arg paren! (here/1: do arg) :here] [
					'return (
						append-widget
						xy: as-pair metrics/margin max-y + metrics/gap
						left-to-right?: true
						after-limit: 9999
					)
					| 'reverse (
						append-widget
						xy: as-pair max-x max-y + metrics/gap
						left-to-right?: false
						after-limit: 9999
					)
					| 'after set arg integer! (
						;	return unless this is first widget
						if widget [
							append-widget
							xy: as-pair metrics/margin max-y + metrics/gap
						]
						after-count: 1
						after-limit: arg
					)
					| 'handler set arg block! (handler: arg)
					| 'rich set arg block! (text: arg)
					| [set arg integer! | set arg pair!] (size: arg)
					| set arg string! (text: arg)
					| [set arg tuple! | set arg none!] (color: arg)
					| set arg block! (action: arg)
					| set arg set-word! (append-widget word: :arg)
					| set arg word! (append-widget widget: arg)
				]
			]
		]

		append-widget
		gob/size: metrics/margin-size + as-pair max-x max-y
		gob/offset: system/view/metrics/work-size - gob/size / 2
		append system/view/screen-gob gob
		show system/view/screen-gob
	]]

	set 'undisplay make function! [[gob][
		remove find system/view/screen-gob gob
		show system/view/screen-gob
	]]

	;	Start global GUI event handler

	active-gob: none
	system/view/event-port: open [scheme: 'event]

 system/view/event-port/awake: make function! [[event /local evt gob][
		evt: map-event event
		gob: evt/gob
		while [not object? gob/data] [gob: gob/parent]
		if all [event/type = 'move gob <> active-gob] [
			attempt [active-gob/data/on-away event]
			active-gob: gob
			attempt [active-gob/data/on-over event]
		]
		evt: to word! ajoin ['on- event/type]
		attempt [gob/data/:evt event]
	]]
]
add a closing ']'. An example app is:

blk: copy []
foreach word words-of ctx-rebgui3/cursors [
	append blk compose/deep [
		text (form word) handler [

   on-over: make function! [[event][cursor (ctx-rebgui3/cursors/:word)]]

   on-away: make function! [[event][cursor ctx-rebgui3/cursors/arrow]]
		]
	]
]

display "Test Window" compose [
	text 83x10 rich [size 36 center red "Reb" black "GUI" leaf "3"]
	after 5
	(blk)
	return
	bar
	reverse
	button "Close" [undisplay event/gob]
	button "Open" [
		display "Alert" [
			after 1
			text 50x5 "Some more text."
			bar
			reverse
			button "Close" [undisplay event/gob]
		]
	]
]
Graham
25-Jan-2010
[191]
why post these examples to r3 chat so that we can try them ...
Ashley
25-Jan-2010
[192]
Even better, I'll upload it as a script to my website. Oh, and the 
above app example is missing an important line at the end:

	wait system/view/event-port
Graham
25-Jan-2010
[193]
altme right click copy doesn't work for me ...
Ashley
25-Jan-2010
[194]
do http://www.dobeash.com/gui.r
Pekr
25-Jan-2010
[195]
hehe, so we might get RebGUI 3 sooner, than VID3 :-)
Henrik
25-Jan-2010
[196]
Ashley, are you taking it in the same direction as RebGUI?
Ashley
25-Jan-2010
[197]
Yes and no. Yes it's going to be as minimalistic and bloat free as 
before ... no as I'm aiming for something that allows seperation 
of form and function. RebGUI has a number of limitations that under 
R2 were problematic to resolve but under R3 are doable.