5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 20:03:01 +08:00
wails/v2/internal/frontend/desktop/windows/winc/panel.go
2022-03-29 21:45:16 +11:00

199 lines
4.6 KiB
Go

/*
* Copyright (C) 2019 The Winc Authors. All Rights Reserved.
*/
package winc
import (
"fmt"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32"
)
type Panel struct {
ControlBase
layoutMng LayoutManager
}
func NewPanel(parent Controller) *Panel {
pa := new(Panel)
RegClassOnlyOnce("winc_Panel")
pa.hwnd = CreateWindow("winc_Panel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE)
pa.parent = parent
RegMsgHandler(pa)
pa.SetFont(DefaultFont)
pa.SetText("")
pa.SetSize(200, 65)
return pa
}
// SetLayout panel implements DockAllow interface.
func (pa *Panel) SetLayout(mng LayoutManager) {
pa.layoutMng = mng
}
func (pa *Panel) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
switch msg {
case w32.WM_SIZE, w32.WM_PAINT:
if pa.layoutMng != nil {
pa.layoutMng.Update()
}
}
return w32.DefWindowProc(pa.hwnd, msg, wparam, lparam)
}
var errorPanelPen = NewPen(w32.PS_GEOMETRIC, 2, NewSolidColorBrush(RGB(255, 128, 128)))
var errorPanelOkPen = NewPen(w32.PS_GEOMETRIC, 2, NewSolidColorBrush(RGB(220, 220, 220)))
// ErrorPanel shows errors or important messages.
// It is meant to stand out of other on screen controls.
type ErrorPanel struct {
ControlBase
pen *Pen
margin int
}
// NewErrorPanel.
func NewErrorPanel(parent Controller) *ErrorPanel {
f := new(ErrorPanel)
f.init(parent)
f.SetFont(DefaultFont)
f.SetText("No errors")
f.SetSize(200, 65)
f.margin = 5
f.pen = errorPanelOkPen
return f
}
func (epa *ErrorPanel) init(parent Controller) {
RegClassOnlyOnce("winc_ErrorPanel")
epa.hwnd = CreateWindow("winc_ErrorPanel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE)
epa.parent = parent
RegMsgHandler(epa)
}
func (epa *ErrorPanel) SetMargin(margin int) {
epa.margin = margin
}
func (epa *ErrorPanel) Printf(format string, v ...interface{}) {
epa.SetText(fmt.Sprintf(format, v...))
epa.ShowAsError(false)
}
func (epa *ErrorPanel) Errorf(format string, v ...interface{}) {
epa.SetText(fmt.Sprintf(format, v...))
epa.ShowAsError(true)
}
func (epa *ErrorPanel) ShowAsError(show bool) {
if show {
epa.pen = errorPanelPen
} else {
epa.pen = errorPanelOkPen
}
epa.Invalidate(true)
}
func (epa *ErrorPanel) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
switch msg {
case w32.WM_ERASEBKGND:
canvas := NewCanvasFromHDC(w32.HDC(wparam))
r := epa.Bounds()
r.rect.Left += int32(epa.margin)
r.rect.Right -= int32(epa.margin)
r.rect.Top += int32(epa.margin)
r.rect.Bottom -= int32(epa.margin)
// old code used NewSystemColorBrush(w32.COLOR_BTNFACE)
canvas.DrawFillRect(r, epa.pen, NewSystemColorBrush(w32.COLOR_WINDOW))
r.rect.Left += 5
canvas.DrawText(epa.Text(), r, 0, epa.Font(), RGB(0, 0, 0))
canvas.Dispose()
return 1
}
return w32.DefWindowProc(epa.hwnd, msg, wparam, lparam)
}
// MultiPanel contains other panels and only makes one of them visible.
type MultiPanel struct {
ControlBase
current int
panels []*Panel
}
func NewMultiPanel(parent Controller) *MultiPanel {
mpa := new(MultiPanel)
RegClassOnlyOnce("winc_MultiPanel")
mpa.hwnd = CreateWindow("winc_MultiPanel", parent, w32.WS_EX_CONTROLPARENT, w32.WS_CHILD|w32.WS_VISIBLE)
mpa.parent = parent
RegMsgHandler(mpa)
mpa.SetFont(DefaultFont)
mpa.SetText("")
mpa.SetSize(300, 200)
mpa.current = -1
return mpa
}
func (mpa *MultiPanel) Count() int { return len(mpa.panels) }
// AddPanel adds panels to the internal list, first panel is visible all others are hidden.
func (mpa *MultiPanel) AddPanel(panel *Panel) {
if len(mpa.panels) > 0 {
panel.Hide()
}
mpa.current = 0
mpa.panels = append(mpa.panels, panel)
}
// ReplacePanel replaces panel, useful for refreshing controls on screen.
func (mpa *MultiPanel) ReplacePanel(index int, panel *Panel) {
mpa.panels[index] = panel
}
// DeletePanel removed panel.
func (mpa *MultiPanel) DeletePanel(index int) {
mpa.panels = append(mpa.panels[:index], mpa.panels[index+1:]...)
}
func (mpa *MultiPanel) Current() int {
return mpa.current
}
func (mpa *MultiPanel) SetCurrent(index int) {
if index >= len(mpa.panels) {
panic("index greater than number of panels")
}
if mpa.current == -1 {
panic("no current panel, add panels first")
}
for i := range mpa.panels {
if i != index {
mpa.panels[i].Hide()
mpa.panels[i].Invalidate(true)
}
}
mpa.panels[index].Show()
mpa.panels[index].Invalidate(true)
mpa.current = index
}
func (mpa *MultiPanel) WndProc(msg uint32, wparam, lparam uintptr) uintptr {
switch msg {
case w32.WM_SIZE:
// resize contained panels
for _, p := range mpa.panels {
p.SetPos(0, 0)
p.SetSize(mpa.Size())
}
}
return w32.DefWindowProc(mpa.hwnd, msg, wparam, lparam)
}