Keynav moment
This commit is contained in:
		
							parent
							
								
									80c0a6be71
								
							
						
					
					
						commit
						519e0b9c6b
					
				@ -20,6 +20,7 @@ var buttonCodeTable = map[xproto.Keysym] tomo.Key {
 | 
			
		||||
	0xFF7F: tomo.KeyNumLock,
 | 
			
		||||
	0xFF08: tomo.KeyBackspace,
 | 
			
		||||
	0xFF09: tomo.KeyTab,
 | 
			
		||||
	0xFE20: tomo.KeyTab,
 | 
			
		||||
	0xFF0D: tomo.KeyEnter,
 | 
			
		||||
	0xFF1B: tomo.KeyEscape,
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
@ -82,7 +82,7 @@ func (window *Window) handleKeyPress (
 | 
			
		||||
			window.advanceSelectionInChild(direction)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		window.child.Handle(event)
 | 
			
		||||
		window.child.Handle(keyDownEvent)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -243,8 +243,9 @@ func (window *Window) childMinimumSizeChangeCallback (width, height int) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (window *Window) childSelectionRequestCallback () {
 | 
			
		||||
func (window *Window) childSelectionRequestCallback () (granted bool) {
 | 
			
		||||
	window.child.Handle(tomo.EventSelect { })
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (window *Window) pushRegion (region image.Rectangle) {
 | 
			
		||||
 | 
			
		||||
@ -78,7 +78,7 @@ func (element *Button) Handle (event tomo.Event) {
 | 
			
		||||
 | 
			
		||||
	case tomo.EventKeyUp:
 | 
			
		||||
		keyDownEvent := event.(tomo.EventKeyUp)
 | 
			
		||||
		if keyDownEvent.Key == tomo.KeyEnter {
 | 
			
		||||
		if keyDownEvent.Key == tomo.KeyEnter && element.pressed {
 | 
			
		||||
			element.pressed = false
 | 
			
		||||
			if element.core.HasImage() {
 | 
			
		||||
				element.draw()
 | 
			
		||||
@ -91,9 +91,17 @@ func (element *Button) Handle (event tomo.Event) {
 | 
			
		||||
 | 
			
		||||
	case tomo.EventSelect:
 | 
			
		||||
		element.core.SetSelected(true)
 | 
			
		||||
		if element.core.HasImage() {
 | 
			
		||||
			element.draw()
 | 
			
		||||
			element.core.PushAll()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case tomo.EventDeselect:
 | 
			
		||||
		element.core.SetSelected(false)
 | 
			
		||||
		if element.core.HasImage() {
 | 
			
		||||
			element.draw()
 | 
			
		||||
			element.core.PushAll()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,8 +12,6 @@ type Container struct {
 | 
			
		||||
 | 
			
		||||
	layout     tomo.Layout
 | 
			
		||||
	children   []tomo.LayoutEntry
 | 
			
		||||
	selectable bool
 | 
			
		||||
	selected   bool
 | 
			
		||||
 | 
			
		||||
	drags [10]tomo.Element
 | 
			
		||||
}
 | 
			
		||||
@ -42,6 +40,16 @@ func (element *Container) Adopt (child tomo.Element, expand bool) {
 | 
			
		||||
		SelectabilityChange: func (bool) {
 | 
			
		||||
			element.updateSelectable()
 | 
			
		||||
		},
 | 
			
		||||
		SelectionRequest: func () (granted bool) {
 | 
			
		||||
			if !child.Selectable() { return }
 | 
			
		||||
			if element.core.Select() {
 | 
			
		||||
				element.propogateToSelected(tomo.EventDeselect { })
 | 
			
		||||
				child.Handle(tomo.EventSelect { })
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			return
 | 
			
		||||
		},
 | 
			
		||||
		Draw: func (region tomo.Image) {
 | 
			
		||||
			element.drawChildRegion(child, region)
 | 
			
		||||
		},
 | 
			
		||||
@ -188,28 +196,84 @@ func (element *Container) Handle (event tomo.Event) {
 | 
			
		||||
	case tomo.EventSelect:
 | 
			
		||||
		if !element.Selectable() { break }
 | 
			
		||||
		element.core.SetSelected(true)
 | 
			
		||||
		
 | 
			
		||||
		// select the first selectable element
 | 
			
		||||
		for _, entry := range element.children {
 | 
			
		||||
			if entry.Selectable() {
 | 
			
		||||
				entry.Handle(event)
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case tomo.EventDeselect:
 | 
			
		||||
		element.core.SetSelected(false)
 | 
			
		||||
		// TODO: propogate deselect event to all children who report
 | 
			
		||||
		// themselves as selected.
 | 
			
		||||
		
 | 
			
		||||
		element.propogateToSelected(event)
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		// other events are just directly sent to the selected child.
 | 
			
		||||
		element.propogateToSelected(event)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (element *Container) propogateToSelected (event tomo.Event) {
 | 
			
		||||
	for _, entry := range element.children {
 | 
			
		||||
		if entry.Selected() {
 | 
			
		||||
			entry.Handle(event)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (element *Container) AdvanceSelection (direction int) (ok bool) {
 | 
			
		||||
	// TODO:
 | 
			
		||||
	if !element.Selectable() { return }
 | 
			
		||||
 | 
			
		||||
	firstSelected := element.firstSelected()
 | 
			
		||||
	if firstSelected < 0 {
 | 
			
		||||
		for _, entry := range element.children {
 | 
			
		||||
			if entry.Selectable() {
 | 
			
		||||
				entry.Handle(tomo.EventSelect { })
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		nextSelectable := -1
 | 
			
		||||
		step := 1
 | 
			
		||||
		if direction < 0 { step = - 1 }
 | 
			
		||||
		for index := firstSelected + step;
 | 
			
		||||
			index < len(element.children) && index > 0;
 | 
			
		||||
			index += step {
 | 
			
		||||
 | 
			
		||||
			if element.children[index].Selectable() {
 | 
			
		||||
				nextSelectable = index
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if nextSelectable > 0 {
 | 
			
		||||
			element.children[firstSelected ].Handle(tomo.EventDeselect { })
 | 
			
		||||
			element.children[nextSelectable].Handle(tomo.EventSelect   { })
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (element *Container) firstSelected () (index int) {
 | 
			
		||||
	for currentIndex, entry := range element.children {
 | 
			
		||||
		if entry.Selected() {
 | 
			
		||||
			return currentIndex
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (element *Container) updateSelectable () {
 | 
			
		||||
	selectable := false
 | 
			
		||||
	for _, entry := range element.children {
 | 
			
		||||
		if entry.Selectable() { selectable = true }
 | 
			
		||||
	}
 | 
			
		||||
	element.core.SetSelectable(selectable)
 | 
			
		||||
	if !selectable { element.selected = false }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (element *Container) updateMinimumSize () {
 | 
			
		||||
 | 
			
		||||
@ -81,8 +81,8 @@ func (control CoreControl) HasImage () (has bool) {
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (control CoreControl) Select () {
 | 
			
		||||
	control.core.hooks.RunSelectionRequest()
 | 
			
		||||
func (control CoreControl) Select () (granted bool) {
 | 
			
		||||
	return control.core.hooks.RunSelectionRequest()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (control CoreControl) SetSelected (selected bool) {
 | 
			
		||||
 | 
			
		||||
@ -20,8 +20,10 @@ func run () {
 | 
			
		||||
	cancel := basic.NewButton("Cancel")
 | 
			
		||||
	cancel.SetEnabled(false)
 | 
			
		||||
	container.Adopt(cancel, false)
 | 
			
		||||
	container.Adopt(basic.NewButton("OK"), false)
 | 
			
		||||
	
 | 
			
		||||
	okButton := basic.NewButton("OK")
 | 
			
		||||
	container.Adopt(okButton, false)
 | 
			
		||||
	okButton.Select()
 | 
			
		||||
		
 | 
			
		||||
	window.OnClose(tomo.Stop)
 | 
			
		||||
	window.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -24,12 +24,14 @@ func run () {
 | 
			
		||||
		container.Adopt(basic.NewLabel("Draw here:", false), false)
 | 
			
		||||
		container.Adopt(basic.NewTest(), true)
 | 
			
		||||
		container.Adopt(okButton, false)
 | 
			
		||||
		okButton.Select()
 | 
			
		||||
	})
 | 
			
		||||
	okButton.OnClick(tomo.Stop)
 | 
			
		||||
	
 | 
			
		||||
	container.Adopt(label, true)
 | 
			
		||||
	container.Adopt(button, false)
 | 
			
		||||
	container.Adopt(okButton, false)
 | 
			
		||||
	okButton.Select()
 | 
			
		||||
	
 | 
			
		||||
	window.OnClose(tomo.Stop)
 | 
			
		||||
	window.Show()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								tomo.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								tomo.go
									
									
									
									
									
								
							@ -43,8 +43,9 @@ type ParentHooks struct {
 | 
			
		||||
 | 
			
		||||
	// SelectionRequest is called when the child element element wants
 | 
			
		||||
	// itself to be selected. If the parent element chooses to grant the
 | 
			
		||||
	// request, it must send the child element a selection event.
 | 
			
		||||
	SelectionRequest func ()
 | 
			
		||||
	// request, it must send the child element a selection event and return
 | 
			
		||||
	// true.
 | 
			
		||||
	SelectionRequest func () (granted bool)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RunDraw runs the Draw hook if it is not nil. If it is nil, it does nothing.
 | 
			
		||||
@ -64,10 +65,11 @@ func (hooks ParentHooks) RunMinimumSizeChange (width, height int) {
 | 
			
		||||
 | 
			
		||||
// RunSelectionRequest runs the SelectionRequest hook if it is not nil. If it is
 | 
			
		||||
// nil, it does nothing.
 | 
			
		||||
func (hooks ParentHooks) RunSelectionRequest () {
 | 
			
		||||
func (hooks ParentHooks) RunSelectionRequest () (granted bool) {
 | 
			
		||||
	if hooks.SelectionRequest != nil {
 | 
			
		||||
		hooks.SelectionRequest()
 | 
			
		||||
		granted = hooks.SelectionRequest()
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RunSelectabilityChange runs the SelectionRequest hook if it is not nil. If it
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user