| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // Copyright 2016 The G3N Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package gui
- import (
- "github.com/g3n/engine/math32"
- "github.com/g3n/engine/window"
- )
- /***************************************
- ScrollBar Panel
- +--------------------------------+
- | scroll button |
- | +--------------+ |
- | | | |
- | | | |
- | +--------------+ |
- +--------------------------------+
- **/
- type ScrollBar struct {
- Panel // Embedded panel
- style *ScrollBarStyle // pointer to current style
- vertical bool // type of scrollbar
- button scrollBarButton // scrollbar button
- }
- type scrollBarButton struct {
- Panel // Embedded panel
- sb *ScrollBar // pointer to parent scroll bar
- pressed bool // mouse button pressed flag
- mouseX float32 // last mouse click x position
- mouseY float32 // last mouse click y position
- }
- type ScrollBarStyle struct {
- Paddings BorderSizes
- Borders BorderSizes
- BordersColor math32.Color4
- Color math32.Color
- Button ScrollBarButtonStyle
- }
- type ScrollBarButtonStyle struct {
- Borders BorderSizes
- BordersColor math32.Color4
- Color math32.Color
- Size float32
- }
- // NewVScrollBar creates and returns a pointer to a new vertical scroll bar
- // with the specified dimensions.
- func NewVScrollBar(width, height float32) *ScrollBar {
- return newScrollBar(width, height, true)
- }
- // NewHScrollBar creates and returns a pointer to a new horizontal scroll bar
- // with the specified dimensions.
- func NewHScrollBar(width, height float32) *ScrollBar {
- return newScrollBar(width, height, false)
- }
- // newScrollBar creates and returns a pointer to a new scroll bar panel
- // with the specified width, height, orientation and target.
- func newScrollBar(width, height float32, vertical bool) *ScrollBar {
- sb := new(ScrollBar)
- sb.initialize(width, height, vertical)
- return sb
- }
- // initialize initializes this scrollbar
- func (sb *ScrollBar) initialize(width, height float32, vertical bool) {
- sb.style = &StyleDefault.ScrollBar
- sb.vertical = vertical
- sb.Panel.Initialize(width, height)
- sb.Panel.Subscribe(OnMouseDown, sb.onMouse)
- // Initialize scrollbar button
- sb.button.Panel.Initialize(0, 0)
- sb.button.Panel.Subscribe(OnMouseDown, sb.button.onMouse)
- sb.button.Panel.Subscribe(OnMouseUp, sb.button.onMouse)
- sb.button.Panel.Subscribe(OnCursor, sb.button.onCursor)
- sb.button.SetMargins(1, 1, 1, 1)
- sb.button.sb = sb
- sb.Add(&sb.button)
- sb.update()
- sb.recalc()
- }
- // Value returns the current position of the button in the scrollbar
- // The returned value is between 0.0 and 1.0
- func (sb *ScrollBar) Value() float64 {
- if sb.vertical {
- return float64(sb.button.Position().Y) / (float64(sb.content.Height) - float64(sb.button.height))
- } else {
- return float64(sb.button.Position().X) / (float64(sb.content.Width) - float64(sb.button.width))
- }
- }
- // SetValue sets the position of the button of the scrollbar
- // from 0.0 (minimum) to 1.0 (maximum).
- func (sb *ScrollBar) SetValue(v float32) {
- v = math32.Clamp(v, 0.0, 1.0)
- if sb.vertical {
- pos := v * (float32(sb.content.Height) - float32(sb.button.height))
- sb.button.SetPositionY(pos)
- } else {
- pos := v * (float32(sb.content.Width) - float32(sb.button.width))
- sb.button.SetPositionX(pos)
- }
- }
- // onMouse receives subscribed mouse events over the scrollbar outer panel
- func (sb *ScrollBar) onMouse(evname string, ev interface{}) {
- e := ev.(*window.MouseEvent)
- if e.Button != window.MouseButtonLeft {
- return
- }
- if sb.vertical {
- posy := e.Ypos - sb.pospix.Y
- newY := math32.Clamp(posy-(sb.button.height/2), 0, sb.content.Height-sb.button.height)
- sb.button.SetPositionY(newY)
- } else {
- posx := e.Xpos - sb.pospix.X
- newX := math32.Clamp(posx-(sb.button.width/2), 0, sb.content.Width-sb.button.width)
- sb.button.SetPositionX(newX)
- }
- sb.root.StopPropagation(Stop3D)
- sb.Dispatch(OnChange, nil)
- }
- // recalc recalculates sizes and positions
- func (sb *ScrollBar) recalc() {
- if sb.vertical {
- sb.button.SetSize(sb.content.Width, sb.style.Button.Size)
- } else {
- sb.button.SetSize(sb.style.Button.Size, sb.content.Height)
- }
- }
- // update updates border sizes and colors
- func (sb *ScrollBar) update() {
- sb.SetBordersFrom(&sb.style.Borders)
- sb.SetPaddingsFrom(&sb.style.Paddings)
- sb.SetBordersColor4(&sb.style.BordersColor)
- sb.SetColor(&sb.style.Color)
- sb.button.SetBordersFrom(&sb.style.Button.Borders)
- sb.button.SetBordersColor4(&sb.style.Button.BordersColor)
- sb.button.SetColor(&sb.style.Button.Color)
- }
- // onMouse receives subscribed mouse events for the scroll bar button
- func (button *scrollBarButton) onMouse(evname string, ev interface{}) {
- e := ev.(*window.MouseEvent)
- if e.Button != window.MouseButtonLeft {
- return
- }
- switch evname {
- case OnMouseDown:
- button.pressed = true
- button.mouseX = e.Xpos
- button.mouseY = e.Ypos
- button.sb.root.SetMouseFocus(button)
- case OnMouseUp:
- button.pressed = false
- button.sb.root.SetMouseFocus(nil)
- default:
- return
- }
- button.sb.root.StopPropagation(Stop3D)
- }
- // onCursor receives subscribed cursor events for the scroll bar button
- func (button *scrollBarButton) onCursor(evname string, ev interface{}) {
- e := ev.(*window.CursorEvent)
- if !button.pressed {
- return
- }
- if button.sb.vertical {
- dy := button.mouseY - e.Ypos
- py := button.Position().Y
- button.SetPositionY(math32.Clamp(py-dy, 0, button.sb.content.Height-button.sb.style.Button.Size))
- } else {
- dx := button.mouseX - e.Xpos
- px := button.Position().X
- button.SetPositionX(math32.Clamp(px-dx, 0, button.sb.content.Width-button.sb.style.Button.Size))
- }
- button.mouseX = e.Xpos
- button.mouseY = e.Ypos
- button.sb.Dispatch(OnChange, nil)
- button.sb.root.StopPropagation(Stop3D)
- }
|