summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAlexander Neumann <alexander.neumann@picos-software.com>2019-05-07 11:55:35 +0200
committerAlexander Neumann <alexander.neumann@picos-software.com>2019-05-07 11:55:35 +0200
commitc5be165f31cdc19dceb1ad0729a8d9d4a46ae073 (patch)
tree3708b7cf089f57e3ddadadc0c8eedc4d9f6958a0
parentMerge branch 'master' of github.com:lxn/walk (diff)
downloadwireguard-windows-c5be165f31cdc19dceb1ad0729a8d9d4a46ae073.tar.xz
wireguard-windows-c5be165f31cdc19dceb1ad0729a8d9d4a46ae073.zip
More work on multi monitor HIDPI
-rw-r--r--boxlayout.go4
-rw-r--r--brush.go2
-rw-r--r--container.go10
-rw-r--r--declarative/dialog.go4
-rw-r--r--declarative/mainwindow.go4
-rw-r--r--dialog.go8
-rw-r--r--flowlayout.go4
-rw-r--r--form.go32
-rw-r--r--gradientcomposite.go4
-rw-r--r--graphicseffects.go4
-rw-r--r--gridlayout.go4
-rw-r--r--groupbox.go10
-rw-r--r--imageview.go2
-rw-r--r--lineerrorpresenter.go4
-rw-r--r--mainwindow.go16
-rw-r--r--numberedit.go4
-rw-r--r--scrollview.go28
-rw-r--r--splitter.go33
-rw-r--r--splitterlayout.go14
-rw-r--r--static.go6
-rw-r--r--statusbar.go8
-rw-r--r--tableview.go4
-rw-r--r--tableviewcolumn.go9
-rw-r--r--tabwidget.go15
-rw-r--r--textlabel.go2
-rw-r--r--toolbar.go4
-rw-r--r--tooltip.go2
-rw-r--r--webview.go2
-rw-r--r--webview_dwebbrowserevents2.go9
-rw-r--r--widget.go14
-rw-r--r--window.go205
31 files changed, 315 insertions, 156 deletions
diff --git a/boxlayout.go b/boxlayout.go
index ce08199f..6c2f73bd 100644
--- a/boxlayout.go
+++ b/boxlayout.go
@@ -163,7 +163,7 @@ func (l *BoxLayout) MinSize() Size {
return Size{}
}
- return l.MinSizeForSize(l.container.ClientBounds().Size())
+ return l.MinSizeForSize(l.container.ClientBoundsPixels().Size())
}
func (l *BoxLayout) MinSizeForSize(size Size) Size {
@@ -251,7 +251,7 @@ func (l *BoxLayout) Update(reset bool) error {
ifContainerIsScrollViewDoCoolSpecialLayoutStuff(l)
- items, err := boxLayoutItems(widgetsToLayout(l.Container().Children()), l.orientation, l.alignment, l.container.ClientBounds(), l.margins, l.spacing, l.hwnd2StretchFactor)
+ items, err := boxLayoutItems(widgetsToLayout(l.Container().Children()), l.orientation, l.alignment, l.container.ClientBoundsPixels(), l.margins, l.spacing, l.hwnd2StretchFactor)
if err != nil {
return err
}
diff --git a/brush.go b/brush.go
index 617c4978..81c7f4ec 100644
--- a/brush.go
+++ b/brush.go
@@ -413,7 +413,7 @@ func (b *GradientBrush) attachWindow(wb *WindowBase) {
var info *windowBrushInfo
update := func() {
- if bb, err := b.create(wb.window.ClientBounds().Size()); err == nil {
+ if bb, err := b.create(wb.window.ClientBoundsPixels().Size()); err == nil {
if info.Delegate != nil {
info.Delegate.bitmap.Dispose()
info.Delegate.Dispose()
diff --git a/container.go b/container.go
index 64d7b791..de1f9966 100644
--- a/container.go
+++ b/container.go
@@ -61,13 +61,13 @@ func performScheduledLayouts() {
if formResizeScheduled {
formResizeScheduled = false
- bounds := appSingleton.activeForm.Bounds()
+ bounds := appSingleton.activeForm.BoundsPixels()
if appSingleton.activeForm.AsFormBase().fixedSize() {
bounds.Width, bounds.Height = 0, 0
}
- appSingleton.activeForm.SetBounds(bounds)
+ appSingleton.activeForm.SetBoundsPixels(bounds)
} else {
for _, layout := range layouts {
if widget, ok := layout.Container().(Widget); ok && widget.Form() != appSingleton.activeForm {
@@ -246,7 +246,7 @@ func applyLayoutResults(container Container, items []layoutResultItem) error {
widget := item.widget
x, y, w, h := item.bounds.X, item.bounds.Y, item.bounds.Width, item.bounds.Height
- b := widget.Bounds()
+ b := widget.BoundsPixels()
if b.X == x && b.Y == y && b.Width == w {
if _, ok := widget.(*ComboBox); ok {
@@ -595,7 +595,7 @@ func (cb *ContainerBase) doPaint() error {
continue
}
- b := widget.Bounds().toRECT()
+ b := widget.BoundsPixels().toRECT()
win.ExcludeClipRect(hdc, b.Left, b.Top, b.Right, b.Bottom)
if err := effect.Draw(widget, canvas); err != nil {
@@ -620,7 +620,7 @@ func (cb *ContainerBase) doPaint() error {
if widget != nil && widget.Parent() != nil && widget.Parent().Handle() == cb.hWnd {
for _, effect := range widget.GraphicsEffects().items {
if effect == FocusEffect {
- b := widget.Bounds().toRECT()
+ b := widget.BoundsPixels().toRECT()
win.ExcludeClipRect(hdc, b.Left, b.Top, b.Right, b.Bottom)
if err := FocusEffect.Draw(widget, canvas); err != nil {
diff --git a/declarative/dialog.go b/declarative/dialog.go
index a42edb3f..87590f4f 100644
--- a/declarative/dialog.go
+++ b/declarative/dialog.go
@@ -116,7 +116,7 @@ func (d Dialog) Create(owner walk.Form) error {
w.SetSuspended(true)
builder.Defer(func() error {
w.SetSuspended(false)
- w.SetBounds(w.Bounds())
+ w.SetBoundsPixels(w.BoundsPixels())
return nil
})
@@ -125,7 +125,7 @@ func (d Dialog) Create(owner walk.Form) error {
}
return builder.InitWidget(fi, w, func() error {
- if err := w.SetSize(d.Size.toW()); err != nil {
+ if err := w.SetSizePixels(d.Size.toW()); err != nil {
return err
}
diff --git a/declarative/mainwindow.go b/declarative/mainwindow.go
index cb967701..f483564b 100644
--- a/declarative/mainwindow.go
+++ b/declarative/mainwindow.go
@@ -103,7 +103,7 @@ func (mw MainWindow) Create() error {
w.SetSuspended(true)
builder.Defer(func() error {
w.SetSuspended(false)
- w.SetBounds(w.Bounds())
+ w.SetBoundsPixels(w.BoundsPixels())
return nil
})
@@ -149,7 +149,7 @@ func (mw MainWindow) Create() error {
w.StatusBar().SetVisible(true)
}
- if err := w.SetSize(mw.Size.toW()); err != nil {
+ if err := w.SetSizePixels(mw.Size.toW()); err != nil {
return err
}
diff --git a/dialog.go b/dialog.go
index 8f4f0eca..2549c5ef 100644
--- a/dialog.go
+++ b/dialog.go
@@ -162,13 +162,13 @@ func (dlg *Dialog) Show() {
size.Width = maxi(size.Width, min.Width)
size.Height = maxi(size.Height, min.Height)
} else {
- size = dlg.Size()
+ size = dlg.SizePixels()
}
- ob := dlg.owner.Bounds()
+ ob := dlg.owner.BoundsPixels()
if dlg.centerInOwnerWhenRun {
- dlg.SetBounds(fitRectToScreen(dlg.hWnd, Rectangle{
+ dlg.SetBoundsPixels(fitRectToScreen(dlg.hWnd, Rectangle{
ob.X + (ob.Width-size.Width)/2,
ob.Y + (ob.Height-size.Height)/2,
size.Width,
@@ -176,7 +176,7 @@ func (dlg *Dialog) Show() {
}))
}
} else {
- dlg.SetBounds(dlg.Bounds())
+ dlg.SetBoundsPixels(dlg.BoundsPixels())
}
dlg.FormBase.Show()
diff --git a/flowlayout.go b/flowlayout.go
index 6292e281..db6d912a 100644
--- a/flowlayout.go
+++ b/flowlayout.go
@@ -90,7 +90,7 @@ func (l *FlowLayout) MinSize() Size {
return Size{}
}
- return l.MinSizeForSize(l.container.ClientBounds().Size())
+ return l.MinSizeForSize(l.container.ClientBoundsPixels().Size())
}
func (l *FlowLayout) MinSizeForSize(size Size) Size {
@@ -195,7 +195,7 @@ func (l *FlowLayout) Update(reset bool) error {
ifContainerIsScrollViewDoCoolSpecialLayoutStuff(l)
- bounds := l.container.ClientBounds()
+ bounds := l.container.ClientBoundsPixels()
sections := l.sectionsForPrimarySize(bounds.Width)
for i, section := range sections {
diff --git a/form.go b/form.go
index 2a7117af..794d6b60 100644
--- a/form.go
+++ b/form.go
@@ -200,9 +200,9 @@ func (fb *FormBase) SetLayout(value Layout) error {
return fb.clientComposite.SetLayout(value)
}
-func (fb *FormBase) SetBounds(bounds Rectangle) error {
+func (fb *FormBase) SetBoundsPixels(bounds Rectangle) error {
if layout := fb.Layout(); layout != nil {
- minSize := fb.sizeFromClientSize(layout.MinSizeForSize(fb.clientComposite.Size()))
+ minSize := fb.sizeFromClientSizePixels(layout.MinSizeForSize(fb.clientComposite.SizePixels()))
if bounds.Width < minSize.Width {
bounds.Width = minSize.Width
@@ -212,7 +212,7 @@ func (fb *FormBase) SetBounds(bounds Rectangle) error {
}
}
- if err := fb.WindowBase.SetBounds(bounds); err != nil {
+ if err := fb.WindowBase.SetBoundsPixels(bounds); err != nil {
return err
}
@@ -270,10 +270,10 @@ func (fb *FormBase) onInsertedWidget(index int, widget Widget) error {
if err == nil {
if layout := fb.Layout(); layout != nil && !fb.Suspended() {
minClientSize := fb.Layout().MinSize()
- clientSize := fb.clientComposite.Size()
+ clientSize := fb.clientComposite.SizePixels()
if clientSize.Width < minClientSize.Width || clientSize.Height < minClientSize.Height {
- fb.SetClientSize(minClientSize)
+ fb.SetClientSizePixels(minClientSize)
}
}
}
@@ -376,7 +376,7 @@ func (fb *FormBase) Run() int {
fb.started = true
fb.startingPublisher.Publish()
- fb.SetBounds(fb.Bounds())
+ fb.SetBoundsPixels(fb.BoundsPixels())
// Some widgets perform weird scrolling stunts, when initially focused.
// We try to fix that here and hope for the best.
@@ -602,7 +602,7 @@ func (fb *FormBase) RestoreState() error {
wp.Length = uint32(unsafe.Sizeof(wp))
if layout := fb.Layout(); layout != nil && fb.fixedSize() {
- minSize := fb.sizeFromClientSize(layout.MinSize())
+ minSize := fb.sizeFromClientSizePixels(layout.MinSize())
wp.RcNormalPosition.Right = wp.RcNormalPosition.Left + int32(minSize.Width) - 1
wp.RcNormalPosition.Bottom = wp.RcNormalPosition.Top + int32(minSize.Height) - 1
@@ -674,11 +674,11 @@ func (fb *FormBase) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) u
var min Size
if layout := fb.clientComposite.layout; layout != nil {
- size := fb.clientSizeFromSize(fb.proposedSize)
- min = fb.sizeFromClientSize(layout.MinSizeForSize(size))
+ size := fb.clientSizeFromSizePixels(fb.proposedSize)
+ min = fb.sizeFromClientSizePixels(layout.MinSizeForSize(size))
if fb.proposedSize.Width < min.Width {
- min = fb.sizeFromClientSize(layout.MinSizeForSize(min))
+ min = fb.sizeFromClientSizePixels(layout.MinSizeForSize(min))
}
}
@@ -699,21 +699,23 @@ func (fb *FormBase) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) u
fb.proposedSize = rectangleFromRECT(*rc).Size()
- fb.clientComposite.SetBounds(fb.window.ClientBounds())
+ fb.clientComposite.SetBoundsPixels(fb.window.ClientBoundsPixels())
case win.WM_SIZE:
- fb.clientComposite.SetBounds(fb.window.ClientBounds())
+ fb.clientComposite.SetBoundsPixels(fb.window.ClientBoundsPixels())
case win.WM_DPICHANGED:
wasSuspended := fb.Suspended()
fb.SetSuspended(true)
defer fb.SetSuspended(wasSuspended)
- rc := (*win.RECT)(unsafe.Pointer(lParam))
- fb.window.SetBounds(rectangleFromRECT(*rc))
-
fb.ApplyDPI(int(win.HIWORD(uint32(wParam))))
+ applyDPIToDescendants(fb.window, int(win.HIWORD(uint32(wParam))))
+
+ rc := (*win.RECT)(unsafe.Pointer(lParam))
+ fb.window.SetBoundsPixels(rectangleFromRECT(*rc))
+
case win.WM_SYSCOMMAND:
if wParam == win.SC_CLOSE {
fb.closeReason = CloseReasonUser
diff --git a/gradientcomposite.go b/gradientcomposite.go
index 54642b32..5a6c22ba 100644
--- a/gradientcomposite.go
+++ b/gradientcomposite.go
@@ -194,7 +194,7 @@ func (gc *GradientComposite) SetColor2(c Color) (err error) {
}
func (gc *GradientComposite) updateBackground() error {
- bounds := gc.ClientBounds()
+ bounds := gc.ClientBoundsPixels()
if bounds.Width < 1 || bounds.Height < 1 {
return nil
}
@@ -262,7 +262,7 @@ func (gc *GradientComposite) Dispose() {
func (gc *GradientComposite) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
switch msg {
case win.WM_SIZE, win.WM_SIZING:
- size := gc.ClientBounds().Size()
+ size := gc.ClientBoundsPixels().Size()
if gc.brush != nil && gc.brush.bitmap.size == size {
break
}
diff --git a/graphicseffects.go b/graphicseffects.go
index 5527e4db..d204846c 100644
--- a/graphicseffects.go
+++ b/graphicseffects.go
@@ -111,7 +111,7 @@ func NewBorderGlowEffect(color Color) (*BorderGlowEffect, error) {
}
func (bge *BorderGlowEffect) Draw(widget Widget, canvas *Canvas) error {
- b := widget.Bounds()
+ b := widget.BoundsPixels()
canvas.DrawBitmapPart(bge.bitmap, Rectangle{b.X - 5, b.Y - 5, 5, 5}, Rectangle{0, 0, 5, 5})
canvas.DrawBitmapPart(bge.bitmap, Rectangle{b.X, b.Y - 5, b.Width, 5}, Rectangle{5 + 1, 0, 1, 5})
@@ -140,7 +140,7 @@ func NewDropShadowEffect(color Color) (*DropShadowEffect, error) {
}
func (dse *DropShadowEffect) Draw(widget Widget, canvas *Canvas) error {
- b := widget.Bounds()
+ b := widget.BoundsPixels()
canvas.DrawBitmapPart(dse.bitmap, Rectangle{b.X + b.Width, b.Y + 10 - 5, 5, 5}, Rectangle{5 + 2, 0, 5, 5})
canvas.DrawBitmapPart(dse.bitmap, Rectangle{b.X + b.Width, b.Y + 10, 5, b.Height - 10}, Rectangle{5 + 2, 5 + 1, 5, 1})
diff --git a/gridlayout.go b/gridlayout.go
index c418a956..66f58fd7 100644
--- a/gridlayout.go
+++ b/gridlayout.go
@@ -319,7 +319,7 @@ func (l *GridLayout) MinSize() Size {
return Size{}
}
- return l.MinSizeForSize(l.container.ClientBounds().Size())
+ return l.MinSizeForSize(l.container.ClientBoundsPixels().Size())
}
func (l *GridLayout) MinSizeForSize(size Size) Size {
@@ -518,7 +518,7 @@ func (l *GridLayout) Update(reset bool) error {
ifContainerIsScrollViewDoCoolSpecialLayoutStuff(l)
- cb := l.container.ClientBounds()
+ cb := l.container.ClientBoundsPixels()
widths := l.sectionSizesForSpace(Horizontal, cb.Width, nil)
heights := l.sectionSizesForSpace(Vertical, cb.Height, widths)
diff --git a/groupbox.go b/groupbox.go
index 3e37c5f6..f8faaf0d 100644
--- a/groupbox.go
+++ b/groupbox.go
@@ -159,7 +159,7 @@ func (gb *GroupBox) HeightForWidth(width int) int {
return cmsh.Height + gb.headerHeight
}
-func (gb *GroupBox) ClientBounds() Rectangle {
+func (gb *GroupBox) ClientBoundsPixels() Rectangle {
cb := windowClientBounds(gb.hWndGroupBox)
if gb.Layout() == nil {
@@ -353,7 +353,7 @@ func (gb *GroupBox) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) u
win.UpdateWindow(gb.checkBox.hWnd)
case win.WM_SIZE, win.WM_SIZING:
- wbcb := gb.WidgetBase.ClientBounds()
+ wbcb := gb.WidgetBase.ClientBoundsPixels()
if !win.MoveWindow(
gb.hWndGroupBox,
int32(wbcb.X),
@@ -374,12 +374,12 @@ func (gb *GroupBox) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) u
} else {
x = gb.headerHeight * 2 / 3
}
- gb.checkBox.SetBounds(Rectangle{x, gb.headerHeight, s.Width, s.Height})
+ gb.checkBox.SetBoundsPixels(Rectangle{x, gb.headerHeight, s.Width, s.Height})
}
- gbcb := gb.ClientBounds()
+ gbcb := gb.ClientBoundsPixels()
gbcb.Height -= 2
- gb.composite.SetBounds(gbcb)
+ gb.composite.SetBoundsPixels(gbcb)
}
}
diff --git a/imageview.go b/imageview.go
index 18a07dba..e1908694 100644
--- a/imageview.go
+++ b/imageview.go
@@ -196,7 +196,7 @@ func (iv *ImageView) drawImage(canvas *Canvas, updateBounds Rectangle) error {
return nil
}
- cb := iv.ClientBounds()
+ cb := iv.ClientBoundsPixels()
cb.Width -= iv.margin * 2
cb.Height -= iv.margin * 2
diff --git a/lineerrorpresenter.go b/lineerrorpresenter.go
index bd9e98c4..f16604d0 100644
--- a/lineerrorpresenter.go
+++ b/lineerrorpresenter.go
@@ -214,8 +214,8 @@ func (lep *LineErrorPresenter) WndProc(hwnd win.HWND, msg uint32, wParam, lParam
switch msg {
case win.WM_SIZE, win.WM_SIZING:
if lep.composite != nil {
- b := lep.ClientBounds()
- lep.composite.SetBounds(Rectangle{b.X + 2, b.Y + 2, b.Width - 4, b.Height - 4})
+ b := lep.ClientBoundsPixels()
+ lep.composite.SetBoundsPixels(Rectangle{b.X + 2, b.Y + 2, b.Width - 4, b.Height - 4})
}
}
diff --git a/mainwindow.go b/mainwindow.go
index 07ab2015..efc77b58 100644
--- a/mainwindow.go
+++ b/mainwindow.go
@@ -78,7 +78,7 @@ func NewMainWindowWithName(name string) (*MainWindow, error) {
mw.statusBar.parent = mw
win.SetParent(mw.statusBar.hWnd, mw.hWnd)
mw.statusBar.visibleChangedPublisher.event.Attach(func() {
- mw.SetBounds(mw.Bounds())
+ mw.SetBoundsPixels(mw.BoundsPixels())
})
succeeded = true
@@ -114,18 +114,18 @@ func (mw *MainWindow) StatusBar() *StatusBar {
return mw.statusBar
}
-func (mw *MainWindow) ClientBounds() Rectangle {
- bounds := mw.FormBase.ClientBounds()
+func (mw *MainWindow) ClientBoundsPixels() Rectangle {
+ bounds := mw.FormBase.ClientBoundsPixels()
if mw.toolBar != nil && mw.toolBar.Actions().Len() > 0 {
- tlbBounds := mw.toolBar.Bounds()
+ tlbBounds := mw.toolBar.BoundsPixels()
bounds.Y += tlbBounds.Height
bounds.Height -= tlbBounds.Height
}
if mw.statusBar.Visible() {
- bounds.Height -= mw.statusBar.Height()
+ bounds.Height -= mw.statusBar.HeightPixels()
}
return bounds
@@ -214,13 +214,13 @@ func (mw *MainWindow) SetFullscreen(fullscreen bool) error {
func (mw *MainWindow) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
switch msg {
case win.WM_SIZE, win.WM_SIZING:
- cb := mw.ClientBounds()
+ cb := mw.ClientBoundsPixels()
if mw.toolBar != nil {
- mw.toolBar.SetBounds(Rectangle{0, 0, cb.Width, mw.toolBar.Height()})
+ mw.toolBar.SetBoundsPixels(Rectangle{0, 0, cb.Width, mw.toolBar.HeightPixels()})
}
- mw.statusBar.SetBounds(Rectangle{0, cb.Y + cb.Height, cb.Width, mw.statusBar.Height()})
+ mw.statusBar.SetBoundsPixels(Rectangle{0, cb.Y + cb.Height, cb.Width, mw.statusBar.HeightPixels()})
}
return mw.FormBase.WndProc(hwnd, msg, wParam, lParam)
diff --git a/numberedit.go b/numberedit.go
index 0e4fb983..49665c2c 100644
--- a/numberedit.go
+++ b/numberedit.go
@@ -408,8 +408,8 @@ func (ne *NumberEdit) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr)
break
}
- cb := ne.ClientBounds()
- if err := ne.edit.SetBounds(cb); err != nil {
+ cb := ne.ClientBoundsPixels()
+ if err := ne.edit.SetBoundsPixels(cb); err != nil {
break
}
}
diff --git a/scrollview.go b/scrollview.go
index 188da93e..a3bcfa2a 100644
--- a/scrollview.go
+++ b/scrollview.go
@@ -90,7 +90,7 @@ func (sv *ScrollView) sizeHint(ideal bool) Size {
}
s := sv.composite.MinSizeHint()
- cb := sv.ClientBounds()
+ cb := sv.ClientBoundsPixels()
h, v := sv.Scrollbars()
@@ -217,13 +217,13 @@ func (sv *ScrollView) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr)
switch msg {
case win.WM_HSCROLL:
- sv.composite.SetX(sv.scroll(win.SB_HORZ, win.LOWORD(uint32(wParam))))
+ sv.composite.SetX(sv.IntTo96DPI(sv.scroll(win.SB_HORZ, win.LOWORD(uint32(wParam)))))
if wParam == win.SB_ENDSCROLL {
avoidBGArtifacts()
}
case win.WM_VSCROLL:
- sv.composite.SetY(sv.scroll(win.SB_VERT, win.LOWORD(uint32(wParam))))
+ sv.composite.SetY(sv.IntTo96DPI(sv.scroll(win.SB_VERT, win.LOWORD(uint32(wParam)))))
if wParam == win.SB_ENDSCROLL {
avoidBGArtifacts()
}
@@ -240,7 +240,7 @@ func (sv *ScrollView) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr)
cmd = win.SB_LINEUP
}
- sv.composite.SetY(sv.scroll(win.SB_VERT, cmd))
+ sv.composite.SetY(sv.IntTo96DPI(sv.scroll(win.SB_VERT, cmd)))
avoidBGArtifacts()
return 0
@@ -259,18 +259,18 @@ func (sv *ScrollView) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr)
func (sv *ScrollView) updateCompositeSize() {
var minSize Size
if fl, ok := sv.composite.layout.(*FlowLayout); ok {
- minSize = fl.MinSizeForSize(sv.ClientBounds().Size())
+ minSize = fl.MinSizeForSize(sv.ClientBoundsPixels().Size())
} else {
minSize = sv.composite.layout.MinSize()
}
- s := maxSize(minSize, sv.ClientBounds().Size())
- sv.composite.SetSize(s)
+ s := maxSize(minSize, sv.ClientBoundsPixels().Size())
+ sv.composite.SetSizePixels(s)
sv.updateScrollBars()
}
func (sv *ScrollView) updateScrollBars() {
- s := sv.composite.Size()
- clb := sv.ClientBounds()
+ s := sv.composite.SizePixels()
+ clb := sv.ClientBoundsPixels()
var si win.SCROLLINFO
si.CbSize = uint32(unsafe.Sizeof(si))
@@ -284,18 +284,18 @@ func (sv *ScrollView) updateScrollBars() {
si.NMax = int32(s.Width - 1)
si.NPage = uint32(clb.Width)
win.SetScrollInfo(sv.hWnd, win.SB_HORZ, &si, false)
- sv.composite.SetX(sv.scroll(win.SB_HORZ, win.SB_THUMBPOSITION))
+ sv.composite.SetX(sv.IntTo96DPI(sv.scroll(win.SB_HORZ, win.SB_THUMBPOSITION)))
}
if v {
if h {
- clb = sv.ClientBounds()
+ clb = sv.ClientBoundsPixels()
}
si.NMax = int32(s.Height - 1)
si.NPage = uint32(clb.Height)
win.SetScrollInfo(sv.hWnd, win.SB_VERT, &si, false)
- sv.composite.SetY(sv.scroll(win.SB_VERT, win.SB_THUMBPOSITION))
+ sv.composite.SetY(sv.IntTo96DPI(sv.scroll(win.SB_VERT, win.SB_THUMBPOSITION)))
}
if sbFlags != win.GetWindowLong(sv.hWnd, win.GWL_STYLE)&(win.WS_HSCROLL|win.WS_VSCROLL) {
@@ -351,7 +351,7 @@ func ifContainerIsScrollViewDoCoolSpecialLayoutStuff(layout Layout) bool {
min := layout.MinSize()
flags := layout.LayoutFlags()
- s := widget.Bounds().Size()
+ s := widget.BoundsPixels().Size()
hsb, vsb := sv.Scrollbars()
@@ -366,7 +366,7 @@ func ifContainerIsScrollViewDoCoolSpecialLayoutStuff(layout Layout) bool {
}
if changeCompositeSize {
- widget.SetBounds(Rectangle{X: 0, Y: 0, Width: s.Width, Height: s.Height})
+ widget.SetBoundsPixels(Rectangle{X: 0, Y: 0, Width: s.Width, Height: s.Height})
sv.updateScrollBars()
return false
}
diff --git a/splitter.go b/splitter.go
index 88dca5fb..8a730b20 100644
--- a/splitter.go
+++ b/splitter.go
@@ -23,6 +23,7 @@ func init() {
MustRegisterWindowClass(splitterWindowClass)
splitterHandleDraggingBrush, _ = NewSolidColorBrush(Color(win.GetSysColor(win.COLOR_BTNSHADOW)))
+ splitterHandleDraggingBrush.wb2info = map[*WindowBase]*windowBrushInfo{nil: nil}
}
type Splitter struct {
@@ -299,9 +300,9 @@ func (s *Splitter) SetFixed(widget Widget, fixed bool) error {
item.fixed = fixed
- if b := widget.Bounds(); fixed && b.Width == 0 || b.Height == 0 {
+ if b := widget.BoundsPixels(); fixed && b.Width == 0 || b.Height == 0 {
b.Width, b.Height = 100, 100
- widget.SetBounds(b)
+ widget.SetBoundsPixels(b)
item.size = 100
}
@@ -342,9 +343,9 @@ func (s *Splitter) onInsertedWidget(index int, widget Widget) (err error) {
}
} else {
layout := s.Layout().(*splitterLayout)
- item := &splitterLayoutItem{stretchFactor: 1}
+ item := &splitterLayoutItem{stretchFactor: 1, wasVisible: true}
layout.hwnd2Item[widget.Handle()] = item
- item.visibleChangedHandle = widget.AsWidgetBase().Property("Visible").Changed().Attach(func() {
+ item.visibleChangedHandle = widget.VisibleChanged().Attach(func() {
if !layout.suspended && widget.AsWidgetBase().visible != item.wasVisible {
layout.Update(true)
}
@@ -396,18 +397,18 @@ func (s *Splitter) onInsertedWidget(index int, widget Widget) (err error) {
}
handleIndex := s.children.Index(s.draggedHandle)
- bh := s.draggedHandle.Bounds()
+ bh := s.draggedHandle.BoundsPixels()
prev := closestVisibleWidget(handleIndex, -1)
- bp := prev.Bounds()
+ bp := prev.BoundsPixels()
msep := minSizeEffective(prev)
next := closestVisibleWidget(handleIndex, 1)
- bn := next.Bounds()
+ bn := next.BoundsPixels()
msen := minSizeEffective(next)
if s.Orientation() == Horizontal {
- xh := s.draggedHandle.X()
+ xh := s.draggedHandle.XPixels()
xnew := xh + x - s.mouseDownPos.X
if xnew < bp.X+msep.Width {
@@ -416,11 +417,11 @@ func (s *Splitter) onInsertedWidget(index int, widget Widget) (err error) {
xnew = bn.X + bn.Width - msen.Width - s.handleWidth
}
- if e := s.draggedHandle.SetX(xnew); e != nil {
+ if e := s.draggedHandle.SetXPixels(xnew); e != nil {
return
}
} else {
- yh := s.draggedHandle.Y()
+ yh := s.draggedHandle.YPixels()
ynew := yh + y - s.mouseDownPos.Y
if ynew < bp.Y+msep.Height {
@@ -429,7 +430,7 @@ func (s *Splitter) onInsertedWidget(index int, widget Widget) (err error) {
ynew = bn.Y + bn.Height - msen.Height - s.handleWidth
}
- if e := s.draggedHandle.SetY(ynew); e != nil {
+ if e := s.draggedHandle.SetYPixels(ynew); e != nil {
return
}
}
@@ -480,9 +481,9 @@ func (s *Splitter) onInsertedWidget(index int, widget Widget) (err error) {
defer next.Invalidate()
defer next.SetSuspended(false)
- bh := dragHandle.Bounds()
- bp := prev.Bounds()
- bn := next.Bounds()
+ bh := dragHandle.BoundsPixels()
+ bp := prev.BoundsPixels()
+ bn := next.BoundsPixels()
var sizePrev int
var sizeNext int
@@ -501,11 +502,11 @@ func (s *Splitter) onInsertedWidget(index int, widget Widget) (err error) {
sizeNext = bn.Height
}
- if e := prev.SetBounds(bp); e != nil {
+ if e := prev.SetBoundsPixels(bp); e != nil {
return
}
- if e := next.SetBounds(bn); e != nil {
+ if e := next.SetBoundsPixels(bn); e != nil {
return
}
diff --git a/splitterlayout.go b/splitterlayout.go
index a52192a4..cc046d7a 100644
--- a/splitterlayout.go
+++ b/splitterlayout.go
@@ -159,7 +159,7 @@ func (l *splitterLayout) MinSize() Size {
return Size{}
}
- return l.MinSizeForSize(l.container.ClientBounds().Size())
+ return l.MinSizeForSize(l.container.ClientBoundsPixels().Size())
}
func (l *splitterLayout) MinSizeForSize(size Size) Size {
@@ -178,7 +178,7 @@ func (l *splitterLayout) MinSizeForSize(size Size) Size {
var cur Size
if anyNonFixed && l.Fixed(widget) {
- cur = widget.Size()
+ cur = widget.SizePixels()
if l.orientation == Horizontal {
cur.Height = 0
@@ -203,7 +203,7 @@ func (l *splitterLayout) MinSizeForSize(size Size) Size {
func (l *splitterLayout) anyNonFixed() bool {
for i, widget := range l.container.Children().items {
- if i%2 == 0 && !l.Fixed(widget) {
+ if i%2 == 0 && widget.visible && !l.Fixed(widget) {
return true
}
}
@@ -213,7 +213,7 @@ func (l *splitterLayout) anyNonFixed() bool {
func (l *splitterLayout) spaceForRegularWidgets() int {
splitter := l.container.(*Splitter)
- s := splitter.ClientBounds().Size()
+ s := splitter.ClientBoundsPixels().Size()
var space int
if l.orientation == Horizontal {
@@ -257,7 +257,7 @@ func (l *splitterLayout) reset() {
if i == 0 {
if len(children.items) > 1 {
- handleIndex = i + 1
+ handleIndex = 1
} else {
handleIndex = -1
}
@@ -365,7 +365,7 @@ func (l *splitterLayout) Update(reset bool) error {
splitter := l.container.(*Splitter)
handleWidth := splitter.HandleWidth()
sizes := make([]int, len(widgets))
- cb := splitter.ClientBounds()
+ cb := splitter.ClientBoundsPixels()
cb.X += l.margins.HNear
cb.Y += l.margins.HFar
cb.Width -= l.margins.HNear + l.margins.HFar
@@ -514,7 +514,7 @@ func (l *splitterLayout) Update(reset bool) error {
}
if maybeInvalidate {
- if b := widget.Bounds(); w == b.Width && h == b.Height && (x != b.X || y != b.Y) {
+ if b := widget.BoundsPixels(); w == b.Width && h == b.Height && (x != b.X || y != b.Y) {
widget.Invalidate()
}
}
diff --git a/static.go b/static.go
index ac3438d0..0fbd0573 100644
--- a/static.go
+++ b/static.go
@@ -178,13 +178,13 @@ func (s *static) setText(text string) (changed bool, err error) {
return false, err
}
- size := s.Bounds().Size()
+ size := s.BoundsPixels().Size()
if err := s.updateParentLayout(); err != nil {
return false, err
}
- if s.Bounds().Size() == size && size != (Size{}) {
+ if s.BoundsPixels().Size() == size && size != (Size{}) {
s.updateStaticBounds()
}
@@ -226,7 +226,7 @@ func (s *static) updateStaticBounds() {
format |= TextBottom
}
- cb := s.ClientBounds()
+ cb := s.ClientBoundsPixels()
if format&TextVCenter != 0 || format&TextBottom != 0 {
var size Size
diff --git a/statusbar.go b/statusbar.go
index 0302b50f..b5d3b1f9 100644
--- a/statusbar.go
+++ b/statusbar.go
@@ -61,6 +61,12 @@ func (sb *StatusBar) SetVisible(visible bool) {
sb.Parent().SendMessage(win.WM_SIZE, 0, 0)
}
+func (sb *StatusBar) ApplyDPI(dpi int) {
+ sb.WidgetBase.ApplyDPI(dpi)
+
+ sb.update()
+}
+
func (sb *StatusBar) update() error {
if err := sb.updateParts(); err != nil {
return err
@@ -83,7 +89,7 @@ func (sb *StatusBar) updateParts() error {
rightEdges := make([]int32, len(items))
var right int32
for i, item := range items {
- right += int32(item.width)
+ right += int32(sb.IntFrom96DPI(item.width))
rightEdges[i] = right
}
var rep *int32
diff --git a/tableview.go b/tableview.go
index 23f68b2c..6d3cbfe8 100644
--- a/tableview.go
+++ b/tableview.go
@@ -2259,7 +2259,7 @@ func (tv *TableView) WndProc(hwnd win.HWND, msg uint32, wp, lp uintptr) uintptr
}
func (tv *TableView) updateLVSizes() {
- cb := tv.ClientBounds()
+ cb := tv.ClientBoundsPixels()
var width int
for i := tv.columns.Len() - 1; i >= 0; i-- {
@@ -2268,6 +2268,8 @@ func (tv *TableView) updateLVSizes() {
}
}
+ width = tv.IntFrom96DPI(width)
+
win.MoveWindow(tv.hwndNormalLV, int32(width), 0, int32(cb.Width-width), int32(cb.Height), true)
var sbh int
diff --git a/tableviewcolumn.go b/tableviewcolumn.go
index f8aa4f40..8e902d20 100644
--- a/tableviewcolumn.go
+++ b/tableviewcolumn.go
@@ -298,7 +298,7 @@ func (tvc *TableViewColumn) Width() int {
return tvc.width
}
- return int(tvc.sendMessage(win.LVM_GETCOLUMNWIDTH, uintptr(tvc.indexInListView()), 0))
+ return tvc.tv.IntTo96DPI(int(tvc.sendMessage(win.LVM_GETCOLUMNWIDTH, uintptr(tvc.indexInListView()), 0)))
}
// SetWidth sets the width of the column in pixels.
@@ -431,10 +431,15 @@ func (tvc *TableViewColumn) update() error {
func (tvc *TableViewColumn) getLVCOLUMN() *win.LVCOLUMN {
var lvc win.LVCOLUMN
+ width := tvc.width
+ if tvc.tv != nil {
+ width = tvc.tv.IntFrom96DPI(width)
+ }
+
lvc.Mask = win.LVCF_FMT | win.LVCF_WIDTH | win.LVCF_TEXT | win.LVCF_SUBITEM
lvc.ISubItem = int32(tvc.indexInListView())
lvc.PszText = syscall.StringToUTF16Ptr(tvc.TitleEffective())
- lvc.Cx = int32(tvc.width)
+ lvc.Cx = int32(width)
switch tvc.alignment {
case AlignCenter:
diff --git a/tabwidget.go b/tabwidget.go
index 6508171b..5e97a4dd 100644
--- a/tabwidget.go
+++ b/tabwidget.go
@@ -125,8 +125,8 @@ func (tw *TabWidget) MinSizeHint() Size {
min.Height = maxi(min.Height, s.Height)
}
- b := tw.Bounds()
- pb := tw.pages.At(0).Bounds()
+ b := tw.BoundsPixels()
+ pb := tw.pages.At(0).BoundsPixels()
size := Size{b.Width - pb.Width + min.Width, b.Height - pb.Height + min.Height}
@@ -139,8 +139,8 @@ func (tw *TabWidget) HeightForWidth(width int) int {
}
var height int
- margin := tw.Size()
- pageSize := tw.pages.At(0).Size()
+ margin := tw.SizePixels()
+ pageSize := tw.pages.At(0).SizePixels()
margin.Width -= pageSize.Width
margin.Height -= pageSize.Height
@@ -171,7 +171,8 @@ func (tw *TabWidget) applyFont(font *Font) {
setWindowFont(tw.hWndTab, font)
- applyFontToDescendants(tw, font)
+ // FIXME: won't work with ApplyDPI
+ // applyFontToDescendants(tw, font)
}
func (tw *TabWidget) CurrentIndex() int {
@@ -280,7 +281,7 @@ func (tw *TabWidget) resizePages() {
win.SendMessage(tw.hWndTab, win.TCM_ADJUSTRECT, 0, uintptr(unsafe.Pointer(&r)))
for _, page := range tw.pages.items {
- if err := page.SetBounds(
+ if err := page.SetBoundsPixels(
Rectangle{
int(r.Left - 2),
int(r.Top),
@@ -367,7 +368,7 @@ func tabWidgetTabWndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uint
hdc := win.BeginPaint(hwnd, &ps)
defer win.EndPaint(hwnd, &ps)
- cb := tw.ClientBounds()
+ cb := tw.ClientBoundsPixels()
bitmap, err := NewBitmap(cb.Size())
if err != nil {
diff --git a/textlabel.go b/textlabel.go
index ab06ca69..ad05bd75 100644
--- a/textlabel.go
+++ b/textlabel.go
@@ -53,7 +53,7 @@ func (tl *TextLabel) MinSizeHint() Size {
}
func (tl *TextLabel) SizeHint() Size {
- return tl.calculateTextSizeForWidth(tl.Width())
+ return tl.calculateTextSizeForWidth(tl.WidthPixels())
}
func (tl *TextLabel) HeightForWidth(width int) int {
diff --git a/toolbar.go b/toolbar.go
index 2ccf2c8e..0690c783 100644
--- a/toolbar.go
+++ b/toolbar.go
@@ -258,8 +258,8 @@ func (tb *ToolBar) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) ui
case win.WM_MOUSEMOVE, win.WM_MOUSELEAVE, win.WM_LBUTTONDOWN:
tb.Invalidate()
- case win.WM_PAINT:
- tb.Invalidate()
+ // case win.WM_PAINT:
+ // tb.Invalidate()
case win.WM_COMMAND:
switch win.HIWORD(uint32(wParam)) {
diff --git a/tooltip.go b/tooltip.go
index dde551ea..81b6f85d 100644
--- a/tooltip.go
+++ b/tooltip.go
@@ -142,7 +142,7 @@ func (tt *ToolTip) track(tool Widget) error {
tt.SendMessage(win.TTM_TRACKACTIVATE, 1, uintptr(unsafe.Pointer(ti)))
- b := tool.Bounds()
+ b := tool.BoundsPixels()
p := win.POINT{X: 0, Y: int32(b.Y + b.Height)}
if form.RightToLeftLayout() {
diff --git a/webview.go b/webview.go
index 4a6baf8a..05851e26 100644
--- a/webview.go
+++ b/webview.go
@@ -431,7 +431,7 @@ func (wv *WebView) withWebBrowser2(f func(webBrowser2 *win.IWebBrowser2) error)
func (wv *WebView) onResize() {
// FIXME: handle error?
wv.withWebBrowser2(func(webBrowser2 *win.IWebBrowser2) error {
- bounds := wv.ClientBounds()
+ bounds := wv.ClientBoundsPixels()
webBrowser2.Put_Left(0)
webBrowser2.Put_Top(0)
diff --git a/webview_dwebbrowserevents2.go b/webview_dwebbrowserevents2.go
index 4649a9e2..ec2b448e 100644
--- a/webview_dwebbrowserevents2.go
+++ b/webview_dwebbrowserevents2.go
@@ -12,8 +12,9 @@ import (
)
import (
- "github.com/lxn/win"
"time"
+
+ "github.com/lxn/win"
)
var webViewDWebBrowserEvents2Vtbl *win.DWebBrowserEvents2Vtbl
@@ -180,11 +181,11 @@ func webView_DWebBrowserEvents2_Invoke(
// FIXME: Horrible hack to avoid glitch where the document is not displayed.
time.AfterFunc(time.Millisecond*100, func() {
wv.Synchronize(func() {
- b := wv.Bounds()
+ b := wv.BoundsPixels()
b.Width++
- wv.SetBounds(b)
+ wv.SetBoundsPixels(b)
b.Width--
- wv.SetBounds(b)
+ wv.SetBoundsPixels(b)
})
})
diff --git a/widget.go b/widget.go
index 83a73d29..fe6cd7bb 100644
--- a/widget.go
+++ b/widget.go
@@ -151,12 +151,12 @@ func (wb *WidgetBase) AsWidgetBase() *WidgetBase {
return wb
}
-// Bounds returns the outer bounding box Rectangle of the WidgetBase, including
+// BoundsPixels returns the outer bounding box Rectangle of the WidgetBase, including
// decorations.
//
// The coordinates are relative to the parent of the Widget.
-func (wb *WidgetBase) Bounds() Rectangle {
- b := wb.WindowBase.Bounds()
+func (wb *WidgetBase) BoundsPixels() Rectangle {
+ b := wb.WindowBase.BoundsPixels()
if wb.parent != nil {
p := win.POINT{int32(b.X), int32(b.Y)}
@@ -316,7 +316,7 @@ func (wb *WidgetBase) SetParent(parent Container) (err error) {
}
}
- b := wb.Bounds()
+ b := wb.BoundsPixels()
if !win.SetWindowPos(
wb.hWnd,
@@ -420,7 +420,7 @@ func (wb *WidgetBase) onClearedGraphicsEffects() error {
func (wb *WidgetBase) invalidateBorderInParent() {
if wb.parent != nil && wb.parent.Layout() != nil {
- b := wb.Bounds().toRECT()
+ b := wb.BoundsPixels().toRECT()
s := int32(wb.parent.Layout().Spacing())
hwnd := wb.parent.Handle()
@@ -503,13 +503,13 @@ func (wb *WidgetBase) updateParentLayoutWithReset(reset bool) error {
if len(inProgressEventsByForm[appSingleton.activeForm]) > 0 {
formResizeScheduled = true
} else {
- bounds := wnd.Bounds()
+ bounds := wnd.BoundsPixels()
if wnd.AsFormBase().fixedSize() {
bounds.Width, bounds.Height = 0, 0
}
- wnd.SetBounds(bounds)
+ wnd.SetBoundsPixels(bounds)
return nil
}
diff --git a/window.go b/window.go
index d7da77d8..77bb12f6 100644
--- a/window.go
+++ b/window.go
@@ -46,6 +46,14 @@ type Window interface {
// parent.
Bounds() Rectangle
+ // BoundsPixels returns the outer bounding box Rectangle of the Window, including
+ // decorations.
+ //
+ // For a Form, like *MainWindow or *Dialog, the Rectangle is in screen
+ // coordinates, for a child Window the coordinates are relative to its
+ // parent.
+ BoundsPixels() Rectangle
+
// BoundsChanged returns an *Event that you can attach to for handling bounds
// changed events for the Window.
BoundsChanged() *Event
@@ -57,13 +65,17 @@ type Window interface {
// excluding decorations.
ClientBounds() Rectangle
+ // ClientBoundsPixels returns the inner bounding box Rectangle of the Window,
+ // excluding decorations.
+ ClientBoundsPixels() Rectangle
+
// ContextMenu returns the context menu of the Window.
//
// By default this is nil.
ContextMenu() *Menu
// CreateCanvas creates and returns a *Canvas that can be used to draw
- // inside the ClientBounds of the Window.
+ // inside the ClientBoundsPixels of the Window.
//
// Remember to call the Dispose method on the canvas to release resources,
// when you no longer need it.
@@ -114,6 +126,9 @@ type Window interface {
// Height returns the outer height of the Window, including decorations.
Height() int
+ // HeightPixels returns the outer height of the Window, including decorations.
+ HeightPixels() int
+
// Invalidate schedules a full repaint of the Window.
Invalidate() error
@@ -182,9 +197,17 @@ type Window interface {
// parent.
SetBounds(value Rectangle) error
- // SetClientSize sets the Size of the inner bounding box of the Window,
+ // SetBoundsPixels sets the outer bounding box Rectangle of the Window, including
+ // decorations.
+ //
+ // For a Form, like *MainWindow or *Dialog, the Rectangle is in screen
+ // coordinates, for a child Window the coordinates are relative to its
+ // parent.
+ SetBoundsPixels(value Rectangle) error
+
+ // SetClientSizePixels sets the Size of the inner bounding box of the Window,
// excluding decorations.
- SetClientSize(value Size) error
+ SetClientSizePixels(value Size) error
// SetContextMenu sets the context menu of the Window.
SetContextMenu(value *Menu)
@@ -208,6 +231,9 @@ type Window interface {
// SetHeight sets the outer height of the Window, including decorations.
SetHeight(value int) error
+ // SetHeightPixels sets the outer height of the Window, including decorations.
+ SetHeightPixels(value int) error
+
// SetMinMaxSize sets the minimum and maximum outer Size of the Window,
// including decorations.
//
@@ -228,6 +254,9 @@ type Window interface {
// SetSize sets the outer Size of the Window, including decorations.
SetSize(value Size) error
+ // SetSizePixels sets the outer Size of the Window, including decorations.
+ SetSizePixels(value Size) error
+
// SetSuspended sets if the Window is suspended for layout and repainting
// purposes.
//
@@ -242,19 +271,35 @@ type Window interface {
// SetWidth sets the outer width of the Window, including decorations.
SetWidth(value int) error
+ // SetWidthPixels sets the outer width of the Window, including decorations.
+ SetWidthPixels(value int) error
+
// SetX sets the x coordinate of the Window, relative to the screen for
// RootWidgets like *MainWindow or *Dialog and relative to the parent for
// child Windows.
SetX(value int) error
+ // SetXPixels sets the x coordinate of the Window, relative to the screen for
+ // RootWidgets like *MainWindow or *Dialog and relative to the parent for
+ // child Windows.
+ SetXPixels(value int) error
+
// SetY sets the y coordinate of the Window, relative to the screen for
// RootWidgets like *MainWindow or *Dialog and relative to the parent for
// child Windows.
SetY(value int) error
+ // SetYPixels sets the y coordinate of the Window, relative to the screen for
+ // RootWidgets like *MainWindow or *Dialog and relative to the parent for
+ // child Windows.
+ SetYPixels(value int) error
+
// Size returns the outer Size of the Window, including decorations.
Size() Size
+ // SizePixels returns the outer Size of the Window, including decorations.
+ SizePixels() Size
+
// SizeChanged returns an *Event that you can attach to for handling size
// changed events for the Window.
SizeChanged() *Event
@@ -277,6 +322,9 @@ type Window interface {
// Width returns the outer width of the Window, including decorations.
Width() int
+ // WidthPixels returns the outer width of the Window, including decorations.
+ WidthPixels() int
+
// WndProc is the window procedure of the window.
//
// When implementing your own WndProc to add or modify behavior, call the
@@ -288,10 +336,20 @@ type Window interface {
// child Windows.
X() int
+ // XPixels returns the x coordinate of the Window, relative to the screen for
+ // RootWidgets like *MainWindow or *Dialog and relative to the parent for
+ // child Windows.
+ XPixels() int
+
// Y returns the y coordinate of the Window, relative to the screen for
// RootWidgets like *MainWindow or *Dialog and relative to the parent for
// child Windows.
Y() int
+
+ // YPixels returns the y coordinate of the Window, relative to the screen for
+ // RootWidgets like *MainWindow or *Dialog and relative to the parent for
+ // child Windows.
+ YPixels() int
}
type calcTextSizeInfo struct {
@@ -815,7 +873,9 @@ type ApplyDPIer interface {
func (wb *WindowBase) ApplyDPI(dpi int) {
wb.dpi = dpi
- wb.window.SetFont(wb.window.Font())
+ if af, ok := wb.window.(applyFonter); ok {
+ af.applyFont(wb.window.Font())
+ }
}
func (wb *WindowBase) IntFrom96DPI(value int) int {
@@ -1173,6 +1233,23 @@ func (wb *WindowBase) BringToTop() error {
//
// The coordinates are relative to the screen.
func (wb *WindowBase) Bounds() Rectangle {
+ return wb.RectangleTo96DPI(wb.BoundsPixels())
+}
+
+// SetBounds sets the outer bounding box Rectangle of the *WindowBase,
+// including decorations.
+//
+// For a Form, like *MainWindow or *Dialog, the Rectangle is in screen
+// coordinates, for a child Window the coordinates are relative to its parent.
+func (wb *WindowBase) SetBounds(bounds Rectangle) error {
+ return wb.SetBoundsPixels(wb.RectangleFrom96DPI(bounds))
+}
+
+// BoundsPixels returns the outer bounding box Rectangle of the *WindowBase, including
+// decorations.
+//
+// The coordinates are relative to the screen.
+func (wb *WindowBase) BoundsPixels() Rectangle {
var r win.RECT
if !win.GetWindowRect(wb.hWnd, &r) {
@@ -1188,12 +1265,12 @@ func (wb *WindowBase) Bounds() Rectangle {
}
}
-// SetBounds sets the outer bounding box Rectangle of the *WindowBase,
+// SetBoundsPixels sets the outer bounding box Rectangle of the *WindowBase,
// including decorations.
//
// For a Form, like *MainWindow or *Dialog, the Rectangle is in screen
// coordinates, for a child Window the coordinates are relative to its parent.
-func (wb *WindowBase) SetBounds(bounds Rectangle) error {
+func (wb *WindowBase) SetBoundsPixels(bounds Rectangle) error {
if !win.MoveWindow(
wb.hWnd,
int32(bounds.X),
@@ -1406,74 +1483,132 @@ func (wb *WindowBase) calculateTextSizeForWidth(width int) Size {
// Size returns the outer Size of the *WindowBase, including decorations.
func (wb *WindowBase) Size() Size {
- return wb.window.Bounds().Size()
+ return wb.SizeTo96DPI(wb.SizePixels())
+}
+
+// SizePixels returns the outer Size of the *WindowBase, including decorations.
+func (wb *WindowBase) SizePixels() Size {
+ return wb.window.BoundsPixels().Size()
}
// SetSize sets the outer Size of the *WindowBase, including decorations.
func (wb *WindowBase) SetSize(size Size) error {
- bounds := wb.window.Bounds()
+ return wb.SetSizePixels(wb.SizeFrom96DPI(size))
+}
+
+// SetSizePixels sets the outer Size of the *WindowBase, including decorations.
+func (wb *WindowBase) SetSizePixels(size Size) error {
+ bounds := wb.window.BoundsPixels()
- return wb.SetBounds(bounds.SetSize(size))
+ return wb.SetBoundsPixels(bounds.SetSize(size))
}
// X returns the x coordinate of the *WindowBase, relative to the screen for
// RootWidgets like *MainWindow or *Dialog and relative to the parent for
// child Windows.
func (wb *WindowBase) X() int {
- return wb.window.Bounds().X
+ return wb.IntTo96DPI(wb.XPixels())
+}
+
+// XPixels returns the x coordinate of the *WindowBase, relative to the screen for
+// RootWidgets like *MainWindow or *Dialog and relative to the parent for
+// child Windows.
+func (wb *WindowBase) XPixels() int {
+ return wb.window.BoundsPixels().X
}
// SetX sets the x coordinate of the *WindowBase, relative to the screen for
// RootWidgets like *MainWindow or *Dialog and relative to the parent for
// child Windows.
func (wb *WindowBase) SetX(value int) error {
- bounds := wb.window.Bounds()
+ return wb.SetXPixels(wb.IntFrom96DPI(value))
+}
+
+// SetXPixels sets the x coordinate of the *WindowBase, relative to the screen for
+// RootWidgets like *MainWindow or *Dialog and relative to the parent for
+// child Windows.
+func (wb *WindowBase) SetXPixels(value int) error {
+ bounds := wb.window.BoundsPixels()
bounds.X = value
- return wb.SetBounds(bounds)
+ return wb.SetBoundsPixels(bounds)
}
// Y returns the y coordinate of the *WindowBase, relative to the screen for
// RootWidgets like *MainWindow or *Dialog and relative to the parent for
// child Windows.
func (wb *WindowBase) Y() int {
- return wb.window.Bounds().Y
+ return wb.IntTo96DPI(wb.YPixels())
+}
+
+// YPixels returns the y coordinate of the *WindowBase, relative to the screen for
+// RootWidgets like *MainWindow or *Dialog and relative to the parent for
+// child Windows.
+func (wb *WindowBase) YPixels() int {
+ return wb.window.BoundsPixels().Y
}
// SetY sets the y coordinate of the *WindowBase, relative to the screen for
// RootWidgets like *MainWindow or *Dialog and relative to the parent for
// child Windows.
func (wb *WindowBase) SetY(value int) error {
- bounds := wb.window.Bounds()
+ return wb.SetYPixels(wb.IntFrom96DPI(value))
+}
+
+// SetYPixels sets the y coordinate of the *WindowBase, relative to the screen for
+// RootWidgets like *MainWindow or *Dialog and relative to the parent for
+// child Windows.
+func (wb *WindowBase) SetYPixels(value int) error {
+ bounds := wb.window.BoundsPixels()
bounds.Y = value
- return wb.SetBounds(bounds)
+ return wb.SetBoundsPixels(bounds)
}
// Width returns the outer width of the *WindowBase, including decorations.
func (wb *WindowBase) Width() int {
- return wb.window.Bounds().Width
+ return wb.IntTo96DPI(wb.WidthPixels())
+}
+
+// WidthPixels returns the outer width of the *WindowBase, including decorations.
+func (wb *WindowBase) WidthPixels() int {
+ return wb.window.BoundsPixels().Width
}
// SetWidth sets the outer width of the *WindowBase, including decorations.
func (wb *WindowBase) SetWidth(value int) error {
- bounds := wb.window.Bounds()
+ return wb.SetWidthPixels(wb.IntFrom96DPI(value))
+}
+
+// SetWidthPixels sets the outer width of the *WindowBase, including decorations.
+func (wb *WindowBase) SetWidthPixels(value int) error {
+ bounds := wb.window.BoundsPixels()
bounds.Width = value
- return wb.SetBounds(bounds)
+ return wb.SetBoundsPixels(bounds)
}
// Height returns the outer height of the *WindowBase, including decorations.
func (wb *WindowBase) Height() int {
- return wb.window.Bounds().Height
+ return wb.IntTo96DPI(wb.HeightPixels())
+}
+
+// HeightPixels returns the outer height of the *WindowBase, including decorations.
+func (wb *WindowBase) HeightPixels() int {
+ return wb.window.BoundsPixels().Height
}
// SetHeight sets the outer height of the *WindowBase, including decorations.
func (wb *WindowBase) SetHeight(value int) error {
- bounds := wb.window.Bounds()
+ return wb.SetHeightPixels(wb.IntFrom96DPI(value))
+}
+
+// SetHeightPixels sets the outer height of the *WindowBase, including decorations.
+func (wb *WindowBase) SetHeightPixels(value int) error {
+ bounds := wb.window.BoundsPixels()
bounds.Height = value
- return wb.SetBounds(bounds)
+ return wb.SetBoundsPixels(bounds)
}
func windowClientBounds(hwnd win.HWND) Rectangle {
@@ -1495,31 +1630,37 @@ func windowClientBounds(hwnd win.HWND) Rectangle {
// ClientBounds returns the inner bounding box Rectangle of the *WindowBase,
// excluding decorations.
func (wb *WindowBase) ClientBounds() Rectangle {
+ return wb.RectangleTo96DPI(wb.ClientBoundsPixels())
+}
+
+// ClientBoundsPixels returns the inner bounding box Rectangle of the *WindowBase,
+// excluding decorations.
+func (wb *WindowBase) ClientBoundsPixels() Rectangle {
return windowClientBounds(wb.hWnd)
}
-func (wb *WindowBase) sizeFromClientSize(clientSize Size) Size {
+func (wb *WindowBase) sizeFromClientSizePixels(clientSize Size) Size {
window := wb.window
- s := window.Size()
- cs := window.ClientBounds().Size()
+ s := window.SizePixels()
+ cs := window.ClientBoundsPixels().Size()
ncs := Size{s.Width - cs.Width, s.Height - cs.Height}
return Size{clientSize.Width + ncs.Width, clientSize.Height + ncs.Height}
}
-func (wb *WindowBase) clientSizeFromSize(size Size) Size {
+func (wb *WindowBase) clientSizeFromSizePixels(size Size) Size {
window := wb.window
- s := window.Size()
- cs := window.ClientBounds().Size()
+ s := window.SizePixels()
+ cs := window.ClientBoundsPixels().Size()
ncs := Size{s.Width - cs.Width, s.Height - cs.Height}
return Size{size.Width - ncs.Width, size.Height - ncs.Height}
}
-// SetClientSize sets the Size of the inner bounding box of the *WindowBase,
+// SetClientSizePixels sets the Size of the inner bounding box of the *WindowBase,
// excluding decorations.
-func (wb *WindowBase) SetClientSize(value Size) error {
- return wb.SetSize(wb.sizeFromClientSize(value))
+func (wb *WindowBase) SetClientSizePixels(value Size) error {
+ return wb.SetSizePixels(wb.sizeFromClientSizePixels(value))
}
// RightToLeftReading returns whether the reading order of the Window
@@ -1571,7 +1712,7 @@ func (wb *WindowBase) FocusedChanged() *Event {
}
// CreateCanvas creates and returns a *Canvas that can be used to draw
-// inside the ClientBounds of the *WindowBase.
+// inside the ClientBoundsPixels of the *WindowBase.
//
// Remember to call the Dispose method on the canvas to release resources,
// when you no longer need it.
@@ -1930,7 +2071,7 @@ func (wb *WindowBase) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr)
wb.prepareDCForBackground(hdc, hwnd, wnd)
- if err := canvas.FillRectangle(bg, wb.ClientBounds()); err != nil {
+ if err := canvas.FillRectangle(bg, wb.ClientBoundsPixels()); err != nil {
break
}