1 Star 0 Fork 0

zxy/walk

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
util.go 11.10 KB
一键复制 编辑 原始数据 按行查看 历史
Simon Rozman 提交于 2019-10-27 03:36 +08:00 . Metafile, DPI: Cleanup
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package walk
import (
"bytes"
"math"
"math/big"
"strconv"
"strings"
"syscall"
"time"
"github.com/lxn/win"
)
var (
decimalSepB byte
decimalSepUint16 uint16
decimalSepS string
groupSepB byte
groupSepUint16 uint16
groupSepS string
)
func init() {
AppendToWalkInit(func() {
var buf [4]uint16
win.GetLocaleInfo(win.LOCALE_USER_DEFAULT, win.LOCALE_SDECIMAL, &buf[0], int32(len(buf)))
decimalSepB = byte(buf[0])
decimalSepS = syscall.UTF16ToString(buf[0:1])
decimalSepUint16 = buf[0]
win.GetLocaleInfo(win.LOCALE_USER_DEFAULT, win.LOCALE_STHOUSAND, &buf[0], int32(len(buf)))
groupSepB = byte(buf[0])
groupSepS = syscall.UTF16ToString(buf[0:1])
groupSepUint16 = buf[0]
})
}
func maxi(a, b int) int {
if a > b {
return a
}
return b
}
func mini(a, b int) int {
if a < b {
return a
}
return b
}
func boolToInt(value bool) int {
if value {
return 1
}
return 0
}
func uint16IndexUint16(s []uint16, v uint16) int {
for i, u := range s {
if u == v {
return i
}
}
return -1
}
func uint16ContainsUint16(s []uint16, v uint16) bool {
return uint16IndexUint16(s, v) != -1
}
func uint16CountUint16(s []uint16, v uint16) int {
var count int
for _, u := range s {
if u == v {
count++
}
}
return count
}
func uint16RemoveUint16(s []uint16, v uint16) []uint16 {
count := uint16CountUint16(s, v)
if count == 0 {
return s
}
ret := make([]uint16, 0, len(s)-count)
for _, u := range s {
if u != v {
ret = append(ret, u)
}
}
return ret
}
func assertFloat64Or(value interface{}, defaultValue float64) float64 {
if f, ok := value.(float64); ok {
return f
}
return defaultValue
}
func assertIntOr(value interface{}, defaultValue int) int {
if n, ok := value.(int); ok {
return n
}
return defaultValue
}
func assertStringOr(value interface{}, defaultValue string) string {
if s, ok := value.(string); ok {
return s
}
return defaultValue
}
func assertTimeOr(value interface{}, defaultValue time.Time) time.Time {
if t, ok := value.(time.Time); ok {
return t
}
return defaultValue
}
func ParseFloat(s string) (float64, error) {
s = strings.TrimSpace(s)
t := FormatFloatGrouped(1000, 2)
replaceSep := func(new string, index func(string, func(rune) bool) int) {
i := index(t, func(r rune) bool {
return r < '0' || r > '9'
})
var sep string
if i > -1 {
sep = string(t[i])
}
if sep != "" {
s = strings.Replace(s, string(sep), new, -1)
}
}
replaceSep("", strings.IndexFunc)
replaceSep(".", strings.LastIndexFunc)
return strconv.ParseFloat(s, 64)
}
func FormatFloat(f float64, prec int) string {
return formatFloatString(strconv.FormatFloat(f, 'f', prec, 64), prec, false)
}
func FormatFloatGrouped(f float64, prec int) string {
return formatFloatString(strconv.FormatFloat(f, 'f', maxi(1, prec), 64), prec, true)
}
func formatBigRat(r *big.Rat, prec int) string {
return formatFloatString(r.FloatString(prec), prec, false)
}
func formatBigRatGrouped(r *big.Rat, prec int) string {
return formatFloatString(r.FloatString(prec), prec, true)
}
func formatFloatString(s string, prec int, grouped bool) string {
switch s {
case "NaN", "-Inf", "+Inf":
return s
}
s = strings.Replace(s, ".", decimalSepS, 1)
if !grouped {
return s
}
b := new(bytes.Buffer)
var firstDigit int
if len(s) > 0 && s[0] == '-' {
firstDigit = 1
b.WriteByte('-')
s = s[1:]
}
intLen := len(s) - maxi(1, prec) - 1
n := intLen % 3
if n != 0 {
b.WriteString(s[:n])
}
for i := n; i < intLen; i += 3 {
if b.Len() > firstDigit {
b.WriteByte(groupSepB)
}
b.WriteString(s[i : i+3])
}
b.WriteString(s[intLen:])
s = b.String()
if prec == 0 {
s = s[:len(s)-2]
}
return s
}
func applyEnabledToDescendants(window Window, enabled bool) {
wb := window.AsWindowBase()
wb.applyEnabled(enabled)
walkDescendants(window, func(w Window) bool {
if w.Handle() == wb.hWnd {
return true
}
if enabled && !w.AsWindowBase().enabled {
return false
}
w.(applyEnableder).applyEnabled(enabled)
return true
})
}
var seenInApplyFontToDescendantsDuringDPIChange map[*WindowBase]bool
func applyFontToDescendants(window Window, font *Font) {
wb := window.AsWindowBase()
wb.applyFont(font)
walkDescendants(window, func(w Window) bool {
if w.Handle() == wb.hWnd {
return true
}
if w.AsWindowBase().font != nil {
return false
}
if seenInApplyFontToDescendantsDuringDPIChange != nil {
wb := w.AsWindowBase()
if seenInApplyFontToDescendantsDuringDPIChange[wb] {
return true
}
seenInApplyFontToDescendantsDuringDPIChange[wb] = true
}
w.(applyFonter).applyFont(font)
return true
})
}
func applySysColorsToDescendants(window Window) {
wb := window.AsWindowBase()
wb.ApplySysColors()
walkDescendants(window, func(w Window) bool {
if w.Handle() == wb.hWnd {
return true
}
w.(ApplySysColorser).ApplySysColors()
return true
})
}
var seenInApplyDPIToDescendantsDuringDPIChange map[*WindowBase]bool
func applyDPIToDescendants(window Window, dpi int) {
wb := window.AsWindowBase()
wb.ApplyDPI(dpi)
walkDescendants(window, func(w Window) bool {
if w.Handle() == wb.hWnd {
return true
}
if seenInApplyDPIToDescendantsDuringDPIChange != nil {
wb := w.AsWindowBase()
if seenInApplyDPIToDescendantsDuringDPIChange[wb] {
return true
}
seenInApplyDPIToDescendantsDuringDPIChange[wb] = true
}
w.(ApplyDPIer).ApplyDPI(dpi)
return true
})
}
func walkDescendants(window Window, f func(w Window) bool) {
window = window.AsWindowBase().window
if window == nil || !f(window) {
return
}
var children []*WidgetBase
switch w := window.(type) {
case *NumberEdit:
if w.edit != nil {
children = append(children, w.edit.AsWidgetBase())
}
case *TabWidget:
for _, p := range w.Pages().items {
children = append(children, p.AsWidgetBase())
}
case Container:
if c := w.Children(); c != nil {
children = c.items
} else {
children = nil
}
}
for _, wb := range children {
walkDescendants(wb.window.(Widget), f)
}
}
func less(a, b interface{}, order SortOrder) bool {
if _, ok := a.(error); ok {
_, bIsErr := b.(error)
return order == SortAscending == !bIsErr
}
if _, ok := b.(error); ok {
return order == SortDescending
}
if a == nil {
return order == SortAscending == (b != nil)
}
if b == nil {
return order == SortDescending
}
switch av := a.(type) {
case string:
if bv, ok := b.(string); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case int:
if bv, ok := b.(int); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case float64:
if bv, ok := b.(float64); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case float32:
if bv, ok := b.(float32); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case int64:
if bv, ok := b.(int64); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case int32:
if bv, ok := b.(int32); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case int16:
if bv, ok := b.(int16); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case int8:
if bv, ok := b.(int8); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case uint:
if bv, ok := b.(uint); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case uint64:
if bv, ok := b.(uint64); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case uint32:
if bv, ok := b.(uint32); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case uint16:
if bv, ok := b.(uint16); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case uint8:
if bv, ok := b.(uint8); ok {
if order == SortAscending {
return av < bv
} else {
return bv < av
}
}
case time.Time:
if bv, ok := b.(time.Time); ok {
if order == SortAscending {
return av.Before(bv)
} else {
return bv.Before(av)
}
}
case bool:
if bv, ok := b.(bool); ok {
if order == SortAscending {
return !av && bv
} else {
return !bv && av
}
}
}
return false
}
func dpiForHDC(hdc win.HDC) int {
if hwnd := win.WindowFromDC(hdc); hwnd != 0 {
return int(win.GetDpiForWindow(hwnd))
}
return int(win.GetDeviceCaps(hdc, win.LOGPIXELSX))
}
// IntFrom96DPI converts from 1/96" units to native pixels.
func IntFrom96DPI(value, dpi int) int {
return scaleInt(value, float64(dpi)/96.0)
}
// IntTo96DPI converts from native pixels to 1/96" units.
func IntTo96DPI(value, dpi int) int {
return scaleInt(value, 96.0/float64(dpi))
}
func scaleInt(value int, scale float64) int {
return int(math.Round(float64(value) * scale))
}
// MarginsFrom96DPI converts from 1/96" units to native pixels.
func MarginsFrom96DPI(value Margins, dpi int) Margins {
return scaleMargins(value, float64(dpi)/96.0)
}
// MarginsTo96DPI converts from native pixels to 1/96" units.
func MarginsTo96DPI(value Margins, dpi int) Margins {
return scaleMargins(value, 96.0/float64(dpi))
}
func scaleMargins(value Margins, scale float64) Margins {
return Margins{
HNear: scaleInt(value.HNear, scale),
VNear: scaleInt(value.VNear, scale),
HFar: scaleInt(value.HFar, scale),
VFar: scaleInt(value.VFar, scale),
}
}
// PointFrom96DPI converts from 1/96" units to native pixels.
func PointFrom96DPI(value Point, dpi int) Point {
return scalePoint(value, float64(dpi)/96.0)
}
// PointTo96DPI converts from native pixels to 1/96" units.
func PointTo96DPI(value Point, dpi int) Point {
return scalePoint(value, 96.0/float64(dpi))
}
func scalePoint(value Point, scale float64) Point {
return Point{
X: scaleInt(value.X, scale),
Y: scaleInt(value.Y, scale),
}
}
// RectangleFrom96DPI converts from 1/96" units to native pixels.
func RectangleFrom96DPI(value Rectangle, dpi int) Rectangle {
return scaleRectangle(value, float64(dpi)/96.0)
}
// RectangleTo96DPI converts from native pixels to 1/96" units.
func RectangleTo96DPI(value Rectangle, dpi int) Rectangle {
return scaleRectangle(value, 96.0/float64(dpi))
}
func scaleRectangle(value Rectangle, scale float64) Rectangle {
return Rectangle{
X: scaleInt(value.X, scale),
Y: scaleInt(value.Y, scale),
Width: scaleInt(value.Width, scale),
Height: scaleInt(value.Height, scale),
}
}
// SizeFrom96DPI converts from 1/96" units to native pixels.
func SizeFrom96DPI(value Size, dpi int) Size {
return scaleSize(value, float64(dpi)/96.0)
}
// SizeTo96DPI converts from native pixels to 1/96" units.
func SizeTo96DPI(value Size, dpi int) Size {
return scaleSize(value, 96.0/float64(dpi))
}
func scaleSize(value Size, scale float64) Size {
return Size{
Width: scaleInt(value.Width, scale),
Height: scaleInt(value.Height, scale),
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/zxy4096/walk.git
git@gitee.com:zxy4096/walk.git
zxy4096
walk
walk
c389da54e794

搜索帮助