github.com/secoba/wails/v2@v2.6.4/internal/frontend/desktop/windows/winc/scrollview.go (about)

     1  //go:build windows
     2  
     3  /*
     4   * Copyright (C) 2019 The Winc Authors. All Rights Reserved.
     5   */
     6  
     7  package winc
     8  
     9  import (
    10  	"unsafe"
    11  
    12  	"github.com/secoba/wails/v2/internal/frontend/desktop/windows/winc/w32"
    13  )
    14  
    15  type ScrollView struct {
    16  	ControlBase
    17  	child Dockable
    18  }
    19  
    20  func NewScrollView(parent Controller) *ScrollView {
    21  	sv := new(ScrollView)
    22  
    23  	RegClassOnlyOnce("winc_ScrollView")
    24  	sv.hwnd = CreateWindow("winc_ScrollView", parent, w32.WS_EX_CONTROLPARENT,
    25  		w32.WS_CHILD|w32.WS_HSCROLL|w32.WS_VISIBLE|w32.WS_VSCROLL)
    26  	sv.parent = parent
    27  	RegMsgHandler(sv)
    28  
    29  	sv.SetFont(DefaultFont)
    30  	sv.SetText("")
    31  	sv.SetSize(200, 200)
    32  	return sv
    33  }
    34  
    35  func (sv *ScrollView) SetChild(child Dockable) {
    36  	sv.child = child
    37  }
    38  
    39  func (sv *ScrollView) UpdateScrollBars() {
    40  	w, h := sv.child.Width(), sv.child.Height()
    41  	sw, sh := sv.Size()
    42  
    43  	var si w32.SCROLLINFO
    44  	si.CbSize = uint32(unsafe.Sizeof(si))
    45  	si.FMask = w32.SIF_PAGE | w32.SIF_RANGE
    46  
    47  	si.NMax = int32(w - 1)
    48  	si.NPage = uint32(sw)
    49  	w32.SetScrollInfo(sv.hwnd, w32.SB_HORZ, &si, true)
    50  	x := sv.scroll(w32.SB_HORZ, w32.SB_THUMBPOSITION)
    51  
    52  	si.NMax = int32(h)
    53  	si.NPage = uint32(sh)
    54  	w32.SetScrollInfo(sv.hwnd, w32.SB_VERT, &si, true)
    55  	y := sv.scroll(w32.SB_VERT, w32.SB_THUMBPOSITION)
    56  
    57  	sv.child.SetPos(x, y)
    58  }
    59  
    60  func (sv *ScrollView) scroll(sb int32, cmd uint16) int {
    61  	var pos int32
    62  	var si w32.SCROLLINFO
    63  	si.CbSize = uint32(unsafe.Sizeof(si))
    64  	si.FMask = w32.SIF_PAGE | w32.SIF_POS | w32.SIF_RANGE | w32.SIF_TRACKPOS
    65  
    66  	w32.GetScrollInfo(sv.hwnd, sb, &si)
    67  	pos = si.NPos
    68  
    69  	switch cmd {
    70  	case w32.SB_LINELEFT: // == win.SB_LINEUP
    71  		pos -= 20
    72  
    73  	case w32.SB_LINERIGHT: // == win.SB_LINEDOWN
    74  		pos += 20
    75  
    76  	case w32.SB_PAGELEFT: // == win.SB_PAGEUP
    77  		pos -= int32(si.NPage)
    78  
    79  	case w32.SB_PAGERIGHT: // == win.SB_PAGEDOWN
    80  		pos += int32(si.NPage)
    81  
    82  	case w32.SB_THUMBTRACK:
    83  		pos = si.NTrackPos
    84  	}
    85  
    86  	if pos < 0 {
    87  		pos = 0
    88  	}
    89  	if pos > si.NMax+1-int32(si.NPage) {
    90  		pos = si.NMax + 1 - int32(si.NPage)
    91  	}
    92  
    93  	si.FMask = w32.SIF_POS
    94  	si.NPos = pos
    95  	w32.SetScrollInfo(sv.hwnd, sb, &si, true)
    96  
    97  	return -int(pos)
    98  }
    99  
   100  func (sv *ScrollView) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
   101  	if sv.child != nil {
   102  		switch msg {
   103  		case w32.WM_PAINT:
   104  			sv.UpdateScrollBars()
   105  
   106  		case w32.WM_HSCROLL:
   107  			x, y := sv.child.Pos()
   108  			x = sv.scroll(w32.SB_HORZ, w32.LOWORD(uint32(wparam)))
   109  			sv.child.SetPos(x, y)
   110  
   111  		case w32.WM_VSCROLL:
   112  			x, y := sv.child.Pos()
   113  			y = sv.scroll(w32.SB_VERT, w32.LOWORD(uint32(wparam)))
   114  			sv.child.SetPos(x, y)
   115  
   116  		case w32.WM_SIZE, w32.WM_SIZING:
   117  			sv.UpdateScrollBars()
   118  		}
   119  	}
   120  	return w32.DefWindowProc(sv.hwnd, msg, wparam, lparam)
   121  }