github.com/secoba/wails/v2@v2.6.4/internal/frontend/desktop/windows/winc/panel.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 "fmt" 11 12 "github.com/secoba/wails/v2/internal/frontend/desktop/windows/winc/w32" 13 ) 14 15 type Panel struct { 16 ControlBase 17 layoutMng LayoutManager 18 } 19 20 func NewPanel(parent Controller) *Panel { 21 pa := new(Panel) 22 23 RegClassOnlyOnce("winc_Panel") 24 pa.hwnd = CreateWindow("winc_Panel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) 25 pa.parent = parent 26 RegMsgHandler(pa) 27 28 pa.SetFont(DefaultFont) 29 pa.SetText("") 30 pa.SetSize(200, 65) 31 return pa 32 } 33 34 // SetLayout panel implements DockAllow interface. 35 func (pa *Panel) SetLayout(mng LayoutManager) { 36 pa.layoutMng = mng 37 } 38 39 func (pa *Panel) WndProc(msg uint32, wparam, lparam uintptr) uintptr { 40 switch msg { 41 case w32.WM_SIZE, w32.WM_PAINT: 42 if pa.layoutMng != nil { 43 pa.layoutMng.Update() 44 } 45 } 46 return w32.DefWindowProc(pa.hwnd, msg, wparam, lparam) 47 } 48 49 var errorPanelPen = NewPen(w32.PS_GEOMETRIC, 2, NewSolidColorBrush(RGB(255, 128, 128))) 50 var errorPanelOkPen = NewPen(w32.PS_GEOMETRIC, 2, NewSolidColorBrush(RGB(220, 220, 220))) 51 52 // ErrorPanel shows errors or important messages. 53 // It is meant to stand out of other on screen controls. 54 type ErrorPanel struct { 55 ControlBase 56 pen *Pen 57 margin int 58 } 59 60 // NewErrorPanel. 61 func NewErrorPanel(parent Controller) *ErrorPanel { 62 f := new(ErrorPanel) 63 f.init(parent) 64 65 f.SetFont(DefaultFont) 66 f.SetText("No errors") 67 f.SetSize(200, 65) 68 f.margin = 5 69 f.pen = errorPanelOkPen 70 return f 71 } 72 73 func (epa *ErrorPanel) init(parent Controller) { 74 RegClassOnlyOnce("winc_ErrorPanel") 75 76 epa.hwnd = CreateWindow("winc_ErrorPanel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) 77 epa.parent = parent 78 79 RegMsgHandler(epa) 80 } 81 82 func (epa *ErrorPanel) SetMargin(margin int) { 83 epa.margin = margin 84 } 85 86 func (epa *ErrorPanel) Printf(format string, v ...interface{}) { 87 epa.SetText(fmt.Sprintf(format, v...)) 88 epa.ShowAsError(false) 89 } 90 91 func (epa *ErrorPanel) Errorf(format string, v ...interface{}) { 92 epa.SetText(fmt.Sprintf(format, v...)) 93 epa.ShowAsError(true) 94 } 95 96 func (epa *ErrorPanel) ShowAsError(show bool) { 97 if show { 98 epa.pen = errorPanelPen 99 } else { 100 epa.pen = errorPanelOkPen 101 } 102 epa.Invalidate(true) 103 } 104 105 func (epa *ErrorPanel) WndProc(msg uint32, wparam, lparam uintptr) uintptr { 106 switch msg { 107 case w32.WM_ERASEBKGND: 108 canvas := NewCanvasFromHDC(w32.HDC(wparam)) 109 r := epa.Bounds() 110 r.rect.Left += int32(epa.margin) 111 r.rect.Right -= int32(epa.margin) 112 r.rect.Top += int32(epa.margin) 113 r.rect.Bottom -= int32(epa.margin) 114 // old code used NewSystemColorBrush(w32.COLOR_BTNFACE) 115 canvas.DrawFillRect(r, epa.pen, NewSystemColorBrush(w32.COLOR_WINDOW)) 116 117 r.rect.Left += 5 118 canvas.DrawText(epa.Text(), r, 0, epa.Font(), RGB(0, 0, 0)) 119 canvas.Dispose() 120 return 1 121 } 122 return w32.DefWindowProc(epa.hwnd, msg, wparam, lparam) 123 } 124 125 // MultiPanel contains other panels and only makes one of them visible. 126 type MultiPanel struct { 127 ControlBase 128 current int 129 panels []*Panel 130 } 131 132 func NewMultiPanel(parent Controller) *MultiPanel { 133 mpa := new(MultiPanel) 134 135 RegClassOnlyOnce("winc_MultiPanel") 136 mpa.hwnd = CreateWindow("winc_MultiPanel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE) 137 mpa.parent = parent 138 RegMsgHandler(mpa) 139 140 mpa.SetFont(DefaultFont) 141 mpa.SetText("") 142 mpa.SetSize(300, 200) 143 mpa.current = -1 144 return mpa 145 } 146 147 func (mpa *MultiPanel) Count() int { return len(mpa.panels) } 148 149 // AddPanel adds panels to the internal list, first panel is visible all others are hidden. 150 func (mpa *MultiPanel) AddPanel(panel *Panel) { 151 if len(mpa.panels) > 0 { 152 panel.Hide() 153 } 154 mpa.current = 0 155 mpa.panels = append(mpa.panels, panel) 156 } 157 158 // ReplacePanel replaces panel, useful for refreshing controls on screen. 159 func (mpa *MultiPanel) ReplacePanel(index int, panel *Panel) { 160 mpa.panels[index] = panel 161 } 162 163 // DeletePanel removed panel. 164 func (mpa *MultiPanel) DeletePanel(index int) { 165 mpa.panels = append(mpa.panels[:index], mpa.panels[index+1:]...) 166 } 167 168 func (mpa *MultiPanel) Current() int { 169 return mpa.current 170 } 171 172 func (mpa *MultiPanel) SetCurrent(index int) { 173 if index >= len(mpa.panels) { 174 panic("index greater than number of panels") 175 } 176 if mpa.current == -1 { 177 panic("no current panel, add panels first") 178 } 179 for i := range mpa.panels { 180 if i != index { 181 mpa.panels[i].Hide() 182 mpa.panels[i].Invalidate(true) 183 } 184 } 185 mpa.panels[index].Show() 186 mpa.panels[index].Invalidate(true) 187 mpa.current = index 188 } 189 190 func (mpa *MultiPanel) WndProc(msg uint32, wparam, lparam uintptr) uintptr { 191 switch msg { 192 case w32.WM_SIZE: 193 // resize contained panels 194 for _, p := range mpa.panels { 195 p.SetPos(0, 0) 196 p.SetSize(mpa.Size()) 197 } 198 } 199 return w32.DefWindowProc(mpa.hwnd, msg, wparam, lparam) 200 }