├── AUTHORS ├── LICENSE ├── README.mdown ├── accessibility.go ├── action.go ├── actionlist.go ├── application.go ├── bitmap.go ├── boxlayout.go ├── brush.go ├── button.go ├── cancelevent.go ├── canvas.go ├── checkbox.go ├── clipboard.go ├── closeevent.go ├── color.go ├── combobox.go ├── commondialogs.go ├── composite.go ├── condition.go ├── container.go ├── cursor.go ├── customwidget.go ├── data ├── drawing.png └── filebrowser.png ├── databinding.go ├── dateedit.go ├── datelabel.go ├── declarative ├── accessibility.go ├── action.go ├── brush.go ├── builder.go ├── checkbox.go ├── combobox.go ├── composite.go ├── customwidget.go ├── databinder.go ├── dateedit.go ├── datelabel.go ├── dialog.go ├── font.go ├── gradientcomposite.go ├── groupbox.go ├── imageview.go ├── interfaces.go ├── label.go ├── layouts.go ├── lineedit.go ├── linklabel.go ├── listbox.go ├── mainwindow.go ├── nonwin.go ├── numberedit.go ├── numberlabel.go ├── progressbar.go ├── pushbutton.go ├── radiobutton.go ├── radiobuttongroup.go ├── radiobuttongroupbox.go ├── scrollview.go ├── separator.go ├── slider.go ├── spacer.go ├── splitbutton.go ├── splitter.go ├── tableview.go ├── tableviewcolumn.go ├── tabpage.go ├── tabwidget.go ├── textedit.go ├── textlabel.go ├── toolbar.go ├── toolbutton.go ├── treeview.go ├── validators.go └── webview.go ├── dialog.go ├── dropfilesevent.go ├── error.go ├── errorevent.go ├── event.go ├── examples ├── actions │ ├── actions.exe.manifest │ ├── actions.go │ └── rsrc.syso ├── clipboard │ ├── clipboard.exe.manifest │ ├── clipboard.go │ └── rsrc.syso ├── databinding │ ├── databinding.exe.manifest │ ├── databinding.go │ └── rsrc.syso ├── drawing │ ├── drawing.exe.manifest │ ├── drawing.go │ └── rsrc.syso ├── dropfiles │ ├── dropfiles.exe.manifest │ ├── dropfiles.go │ └── rsrc.syso ├── externalwidgets │ ├── externalwidgets.exe.manifest │ ├── externalwidgets.go │ └── rsrc.syso ├── filebrowser │ ├── filebrowser.exe.manifest │ ├── filebrowser.go │ └── rsrc.syso ├── gradientcomposite │ ├── gradientcomposite.exe.manifest │ ├── gradientcomposite.go │ └── rsrc.syso ├── imageicon │ ├── imageicon.exe.manifest │ ├── main.go │ └── rsrc.syso ├── imageview │ ├── imageview.exe.manifest │ ├── imageview.go │ └── rsrc.syso ├── imageviewer │ ├── imageviewer.exe.manifest │ ├── imageviewer.go │ └── rsrc.syso ├── img │ ├── README │ ├── check.ico │ ├── document-new.png │ ├── document-properties.png │ ├── open.png │ ├── plus.png │ ├── stop.ico │ └── system-shutdown.png ├── linklabel │ ├── linklabel.exe.manifest │ ├── linklabel.go │ └── rsrc.syso ├── listbox │ ├── listbox.exe.manifest │ ├── listbox.go │ └── rsrc.syso ├── listbox_ownerdrawing │ ├── listbox_ownerdrawing.exe.manifest │ ├── listbox_ownerdrawing.go │ └── rsrc.syso ├── logview │ ├── logview.exe.manifest │ ├── logview.go │ ├── logviewapp.go │ └── rsrc.syso ├── multiplepages │ ├── main.go │ ├── multipagemainwindow.go │ ├── multiplepages.exe.manifest │ └── rsrc.syso ├── notifyicon │ ├── notifyicon.exe.manifest │ ├── notifyicon.go │ └── rsrc.syso ├── progressindicator │ ├── dialog.ui │ ├── dialog_ui.go │ ├── pi.go │ ├── progressindicator.exe.manifest │ └── rsrc.syso ├── radiobutton │ ├── radiobutton.exe.manifest │ ├── radiobutton.go │ └── rsrc.syso ├── settings │ ├── rsrc.syso │ ├── settings.exe.manifest │ └── settings.go ├── slider │ ├── rsrc.syso │ ├── slider.exe.manifest │ └── slider.go ├── statusbar │ ├── rsrc.syso │ ├── statusbar.exe.manifest │ └── statusbar.go ├── tableview │ ├── rsrc.syso │ ├── tableview.exe.manifest │ └── tableview.go ├── webview │ ├── rsrc.syso │ ├── webview.exe.manifest │ └── webview.go └── webview_events │ ├── rsrc.syso │ ├── webview_events.exe.manifest │ └── webview_events.go ├── expression.go ├── flowlayout.go ├── font.go ├── fontresource.go ├── form.go ├── gradientcomposite.go ├── graphicseffects.go ├── gridlayout.go ├── groupbox.go ├── icon.go ├── iconcache.go ├── image.go ├── imagelist.go ├── imageview.go ├── inifilesettings.go ├── intevent.go ├── intrangeevent.go ├── keyboard.go ├── keyevent.go ├── l10n ├── update.bat ├── walk-de.tr └── walk-ko.tr ├── label.go ├── layout.go ├── lineedit.go ├── linklabel.go ├── listbox.go ├── mainloop_cgo.go ├── mainloop_default.go ├── mainwindow.go ├── maptablemodel.go ├── menu.go ├── messagebox.go ├── metafile.go ├── models.go ├── mouseevent.go ├── notifyicon.go ├── numberedit.go ├── numberlabel.go ├── path.go ├── pen.go ├── point.go ├── progressbar.go ├── progressindicator.go ├── property.go ├── pushbutton.go ├── radiobutton.go ├── rectangle.go ├── reflectmodels.go ├── registry.go ├── resourcemanager.go ├── scrollview.go ├── separator.go ├── simpletypes.go ├── size.go ├── slider.go ├── spacer.go ├── splitbutton.go ├── splitter.go ├── splitterhandle.go ├── splitterlayout.go ├── static.go ├── statusbar.go ├── stopwatch.go ├── stringevent.go ├── tableview.go ├── tableviewcolumn.go ├── tableviewcolumnlist.go ├── tabpage.go ├── tabpagelist.go ├── tabwidget.go ├── textedit.go ├── textlabel.go ├── toolbar.go ├── toolbutton.go ├── tools └── ui2walk │ └── ui2walk.go ├── tooltip.go ├── tooltiperrorpresenter.go ├── treeitemevent.go ├── treeview.go ├── util.go ├── validators.go ├── walk.go ├── webview.go ├── webview_dwebbrowserevents2.go ├── webview_events.go ├── webview_idochostuihandler.go ├── webview_ioleclientsite.go ├── webview_ioleinplaceframe.go ├── webview_ioleinplacesite.go ├── widget.go ├── widgetlist.go ├── window.go └── windowgroup.go /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of 'Walk' authors for copyright purposes. 2 | 3 | # Names should be added to this file as 4 | # Name or Organization 5 | # The email address is not required for organizations. 6 | 7 | # Please keep the list sorted. 8 | 9 | # Contributors 10 | # ============ 11 | 12 | Alexander Neumann 13 | Aman Gupta 14 | Anthony Dong 15 | Attila Tajti 16 | Audrius Karabanovas 17 | Benny Siegert 18 | Cary Cherng 19 | Dmitry Bagdanov 20 | Ham Yeongtaek 21 | Hill 22 | iquanxin 23 | James Scholes 24 | Jason A. Donenfeld 25 | Joseph Watson 26 | Joshua D. Sjoding 27 | ktye 28 | llxwj 29 | Mateusz Czapliński 30 | Michael Teichgräber 31 | Paul Wolf 32 | ryujimiya 33 | Semyon Tokarev 34 | Shawn Sun 35 | Simon Rozman 36 | Tim Dufrane 37 | Vincent Vanackere 38 | xoviat 39 | evangwt 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 The Walk Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. The names of the authors may not be used to endorse or promote products 12 | derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 15 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /cancelevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type cancelEventHandlerInfo struct { 10 | handler CancelEventHandler 11 | once bool 12 | } 13 | 14 | type CancelEventHandler func(canceled *bool) 15 | 16 | type CancelEvent struct { 17 | handlers []cancelEventHandlerInfo 18 | } 19 | 20 | func (e *CancelEvent) Attach(handler CancelEventHandler) int { 21 | handlerInfo := cancelEventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *CancelEvent) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *CancelEvent) Once(handler CancelEventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type CancelEventPublisher struct { 45 | event CancelEvent 46 | } 47 | 48 | func (p *CancelEventPublisher) Event() *CancelEvent { 49 | return &p.event 50 | } 51 | 52 | func (p *CancelEventPublisher) Publish(canceled *bool) { 53 | for i, h := range p.event.handlers { 54 | if h.handler != nil { 55 | h.handler(canceled) 56 | 57 | if h.once { 58 | p.event.Detach(i) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /closeevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type closeEventHandlerInfo struct { 10 | handler CloseEventHandler 11 | once bool 12 | } 13 | 14 | type CloseEventHandler func(canceled *bool, reason CloseReason) 15 | 16 | type CloseEvent struct { 17 | handlers []closeEventHandlerInfo 18 | } 19 | 20 | func (e *CloseEvent) Attach(handler CloseEventHandler) int { 21 | handlerInfo := closeEventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *CloseEvent) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *CloseEvent) Once(handler CloseEventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type CloseEventPublisher struct { 45 | event CloseEvent 46 | } 47 | 48 | func (p *CloseEventPublisher) Event() *CloseEvent { 49 | return &p.event 50 | } 51 | 52 | func (p *CloseEventPublisher) Publish(canceled *bool, reason CloseReason) { 53 | for i, h := range p.event.handlers { 54 | if h.handler != nil { 55 | h.handler(canceled, reason) 56 | 57 | if h.once { 58 | p.event.Detach(i) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /color.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type Color uint32 10 | 11 | func RGB(r, g, b byte) Color { 12 | return Color(uint32(r) | uint32(g)<<8 | uint32(b)<<16) 13 | } 14 | 15 | func (c Color) R() byte { 16 | return byte(c & 0xff) 17 | } 18 | 19 | func (c Color) G() byte { 20 | return byte((c >> 8) & 0xff) 21 | } 22 | 23 | func (c Color) B() byte { 24 | return byte((c >> 16) & 0xff) 25 | } 26 | -------------------------------------------------------------------------------- /composite.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | ) 12 | 13 | const compositeWindowClass = `\o/ Walk_Composite_Class \o/` 14 | 15 | func init() { 16 | AppendToWalkInit(func() { 17 | MustRegisterWindowClass(compositeWindowClass) 18 | }) 19 | } 20 | 21 | type Composite struct { 22 | ContainerBase 23 | } 24 | 25 | func NewCompositeWithStyle(parent Window, style uint32) (*Composite, error) { 26 | c := new(Composite) 27 | c.children = newWidgetList(c) 28 | c.SetPersistent(true) 29 | 30 | if err := InitWidget( 31 | c, 32 | parent, 33 | compositeWindowClass, 34 | win.WS_CHILD|win.WS_VISIBLE|style, 35 | win.WS_EX_CONTROLPARENT); err != nil { 36 | return nil, err 37 | } 38 | 39 | c.SetBackground(NullBrush()) 40 | 41 | return c, nil 42 | } 43 | 44 | func NewComposite(parent Container) (*Composite, error) { 45 | return NewCompositeWithStyle(parent, 0) 46 | } 47 | -------------------------------------------------------------------------------- /data/drawing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/data/drawing.png -------------------------------------------------------------------------------- /data/filebrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/data/filebrowser.png -------------------------------------------------------------------------------- /datelabel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "time" 11 | ) 12 | 13 | type DateLabel struct { 14 | static 15 | date time.Time 16 | dateChangedPublisher EventPublisher 17 | format string 18 | formatChangedPublisher EventPublisher 19 | } 20 | 21 | func NewDateLabel(parent Container) (*DateLabel, error) { 22 | dl := new(DateLabel) 23 | 24 | if err := dl.init(dl, parent, 0); err != nil { 25 | return nil, err 26 | } 27 | 28 | dl.SetTextAlignment(AlignFar) 29 | if _, err := dl.updateText(); err != nil { 30 | return nil, err 31 | } 32 | 33 | dl.MustRegisterProperty("Date", NewProperty( 34 | func() interface{} { 35 | return dl.Date() 36 | }, 37 | func(v interface{}) error { 38 | return dl.SetDate(assertTimeOr(v, time.Time{})) 39 | }, 40 | dl.dateChangedPublisher.Event())) 41 | 42 | dl.MustRegisterProperty("Format", NewProperty( 43 | func() interface{} { 44 | return dl.Format() 45 | }, 46 | func(v interface{}) error { 47 | return dl.SetFormat(assertStringOr(v, "")) 48 | }, 49 | dl.formatChangedPublisher.Event())) 50 | 51 | return dl, nil 52 | } 53 | 54 | func (dl *DateLabel) asStatic() *static { 55 | return &dl.static 56 | } 57 | 58 | func (dl *DateLabel) TextAlignment() Alignment1D { 59 | return dl.textAlignment1D() 60 | } 61 | 62 | func (dl *DateLabel) SetTextAlignment(alignment Alignment1D) error { 63 | if alignment == AlignDefault { 64 | alignment = AlignNear 65 | } 66 | 67 | return dl.setTextAlignment1D(alignment) 68 | } 69 | 70 | func (dl *DateLabel) Date() time.Time { 71 | return dl.date 72 | } 73 | 74 | func (dl *DateLabel) SetDate(date time.Time) error { 75 | if date == dl.date { 76 | return nil 77 | } 78 | 79 | old := dl.date 80 | 81 | dl.date = date 82 | 83 | if _, err := dl.updateText(); err != nil { 84 | dl.date = old 85 | return err 86 | } 87 | 88 | dl.dateChangedPublisher.Publish() 89 | 90 | return nil 91 | } 92 | 93 | func (dl *DateLabel) Format() string { 94 | return dl.format 95 | } 96 | 97 | func (dl *DateLabel) SetFormat(format string) error { 98 | if format == dl.format { 99 | return nil 100 | } 101 | 102 | old := dl.format 103 | 104 | dl.format = format 105 | 106 | if _, err := dl.updateText(); err != nil { 107 | dl.format = old 108 | return err 109 | } 110 | 111 | dl.formatChangedPublisher.Publish() 112 | 113 | return nil 114 | } 115 | 116 | func (dl *DateLabel) updateText() (changed bool, err error) { 117 | return dl.setText(dl.date.Format(dl.format)) 118 | } 119 | -------------------------------------------------------------------------------- /declarative/brush.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "strconv" 11 | 12 | "github.com/lxn/walk" 13 | ) 14 | 15 | type TransparentBrush struct { 16 | } 17 | 18 | func (TransparentBrush) Create() (walk.Brush, error) { 19 | return walk.NullBrush(), nil 20 | } 21 | 22 | type SolidColorBrush struct { 23 | Color walk.Color 24 | } 25 | 26 | func (scb SolidColorBrush) Create() (walk.Brush, error) { 27 | return walk.NewSolidColorBrush(scb.Color) 28 | } 29 | 30 | type SystemColorBrush struct { 31 | Color walk.SystemColor 32 | } 33 | 34 | func (scb SystemColorBrush) Create() (walk.Brush, error) { 35 | return walk.NewSystemColorBrush(scb.Color) 36 | } 37 | 38 | type BitmapBrush struct { 39 | Image interface{} 40 | } 41 | 42 | func (bb BitmapBrush) Create() (walk.Brush, error) { 43 | var bmp *walk.Bitmap 44 | var err error 45 | 46 | switch img := bb.Image.(type) { 47 | case *walk.Bitmap: 48 | bmp = img 49 | 50 | case string: 51 | if bmp, err = walk.Resources.Bitmap(img); err != nil { 52 | return nil, err 53 | } 54 | 55 | case int: 56 | if bmp, err = walk.Resources.Bitmap(strconv.Itoa(img)); err != nil { 57 | return nil, err 58 | } 59 | 60 | default: 61 | return nil, walk.ErrInvalidType 62 | } 63 | 64 | return walk.NewBitmapBrush(bmp) 65 | } 66 | 67 | type GradientBrush struct { 68 | Vertexes []walk.GradientVertex 69 | Triangles []walk.GradientTriangle 70 | } 71 | 72 | func (gb GradientBrush) Create() (walk.Brush, error) { 73 | return walk.NewGradientBrush(gb.Vertexes, gb.Triangles) 74 | } 75 | 76 | type HorizontalGradientBrush struct { 77 | Stops []walk.GradientStop 78 | } 79 | 80 | func (hgb HorizontalGradientBrush) Create() (walk.Brush, error) { 81 | return walk.NewHorizontalGradientBrush(hgb.Stops) 82 | } 83 | 84 | type VerticalGradientBrush struct { 85 | Stops []walk.GradientStop 86 | } 87 | 88 | func (vgb VerticalGradientBrush) Create() (walk.Brush, error) { 89 | return walk.NewVerticalGradientBrush(vgb.Stops) 90 | } 91 | -------------------------------------------------------------------------------- /declarative/checkbox.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type CheckBox struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Button 50 | 51 | Checked Property 52 | OnCheckedChanged walk.EventHandler 53 | OnClicked walk.EventHandler 54 | Text Property 55 | 56 | // CheckBox 57 | 58 | AssignTo **walk.CheckBox 59 | CheckState Property 60 | OnCheckStateChanged walk.EventHandler 61 | TextOnLeftSide bool 62 | Tristate bool 63 | } 64 | 65 | func (cb CheckBox) Create(builder *Builder) error { 66 | w, err := walk.NewCheckBox(builder.Parent()) 67 | if err != nil { 68 | return err 69 | } 70 | 71 | if cb.AssignTo != nil { 72 | *cb.AssignTo = w 73 | } 74 | 75 | return builder.InitWidget(cb, w, func() error { 76 | w.SetPersistent(cb.Persistent) 77 | 78 | if err := w.SetTextOnLeftSide(cb.TextOnLeftSide); err != nil { 79 | return err 80 | } 81 | 82 | if err := w.SetTristate(cb.Tristate); err != nil { 83 | return err 84 | } 85 | 86 | if _, isBindData := cb.CheckState.(bindData); cb.Tristate && (cb.CheckState == nil || isBindData) { 87 | w.SetCheckState(walk.CheckIndeterminate) 88 | } 89 | 90 | if cb.OnClicked != nil { 91 | w.Clicked().Attach(cb.OnClicked) 92 | } 93 | 94 | if cb.OnCheckedChanged != nil { 95 | w.CheckedChanged().Attach(cb.OnCheckedChanged) 96 | } 97 | 98 | if cb.OnCheckStateChanged != nil { 99 | w.CheckStateChanged().Attach(cb.OnCheckStateChanged) 100 | } 101 | 102 | return nil 103 | }) 104 | } 105 | -------------------------------------------------------------------------------- /declarative/composite.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | "github.com/lxn/win" 12 | ) 13 | 14 | type Composite struct { 15 | // Window 16 | 17 | Accessibility Accessibility 18 | Background Brush 19 | ContextMenuItems []MenuItem 20 | DoubleBuffering bool 21 | Enabled Property 22 | Font Font 23 | MaxSize Size 24 | MinSize Size 25 | Name string 26 | OnBoundsChanged walk.EventHandler 27 | OnKeyDown walk.KeyEventHandler 28 | OnKeyPress walk.KeyEventHandler 29 | OnKeyUp walk.KeyEventHandler 30 | OnMouseDown walk.MouseEventHandler 31 | OnMouseMove walk.MouseEventHandler 32 | OnMouseUp walk.MouseEventHandler 33 | OnSizeChanged walk.EventHandler 34 | Persistent bool 35 | RightToLeftReading bool 36 | ToolTipText Property 37 | Visible Property 38 | 39 | // Widget 40 | 41 | Alignment Alignment2D 42 | AlwaysConsumeSpace bool 43 | Column int 44 | ColumnSpan int 45 | GraphicsEffects []walk.WidgetGraphicsEffect 46 | Row int 47 | RowSpan int 48 | StretchFactor int 49 | 50 | // Container 51 | 52 | Children []Widget 53 | DataBinder DataBinder 54 | Layout Layout 55 | 56 | // Composite 57 | 58 | AssignTo **walk.Composite 59 | Border bool 60 | Expressions func() map[string]walk.Expression 61 | Functions map[string]func(args ...interface{}) (interface{}, error) 62 | } 63 | 64 | func (c Composite) Create(builder *Builder) error { 65 | var style uint32 66 | if c.Border { 67 | style |= win.WS_BORDER 68 | } 69 | w, err := walk.NewCompositeWithStyle(builder.Parent(), style) 70 | if err != nil { 71 | return err 72 | } 73 | 74 | if c.AssignTo != nil { 75 | *c.AssignTo = w 76 | } 77 | 78 | w.SetSuspended(true) 79 | builder.Defer(func() error { 80 | w.SetSuspended(false) 81 | return nil 82 | }) 83 | 84 | return builder.InitWidget(c, w, func() error { 85 | if c.Expressions != nil { 86 | for name, expr := range c.Expressions() { 87 | builder.expressions[name] = expr 88 | } 89 | } 90 | if c.Functions != nil { 91 | for name, fn := range c.Functions { 92 | builder.functions[name] = fn 93 | } 94 | } 95 | 96 | return nil 97 | }) 98 | } 99 | -------------------------------------------------------------------------------- /declarative/customwidget.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type PaintMode int 14 | 15 | const ( 16 | PaintNormal PaintMode = iota // erase background before PaintFunc 17 | PaintNoErase // PaintFunc clears background, single buffered 18 | PaintBuffered // PaintFunc clears background, double buffered 19 | ) 20 | 21 | type CustomWidget struct { 22 | // Window 23 | 24 | Accessibility Accessibility 25 | Background Brush 26 | ContextMenuItems []MenuItem 27 | DoubleBuffering bool 28 | Enabled Property 29 | Font Font 30 | MaxSize Size 31 | MinSize Size 32 | Name string 33 | OnBoundsChanged walk.EventHandler 34 | OnKeyDown walk.KeyEventHandler 35 | OnKeyPress walk.KeyEventHandler 36 | OnKeyUp walk.KeyEventHandler 37 | OnMouseDown walk.MouseEventHandler 38 | OnMouseMove walk.MouseEventHandler 39 | OnMouseUp walk.MouseEventHandler 40 | OnSizeChanged walk.EventHandler 41 | Persistent bool 42 | RightToLeftReading bool 43 | ToolTipText Property 44 | Visible Property 45 | 46 | // Widget 47 | 48 | Alignment Alignment2D 49 | AlwaysConsumeSpace bool 50 | Column int 51 | ColumnSpan int 52 | GraphicsEffects []walk.WidgetGraphicsEffect 53 | Row int 54 | RowSpan int 55 | StretchFactor int 56 | 57 | // CustomWidget 58 | 59 | AssignTo **walk.CustomWidget 60 | ClearsBackground bool 61 | InvalidatesOnResize bool 62 | Paint walk.PaintFunc 63 | PaintPixels walk.PaintFunc 64 | PaintMode PaintMode 65 | Style uint32 66 | } 67 | 68 | func (cw CustomWidget) Create(builder *Builder) error { 69 | var w *walk.CustomWidget 70 | var err error 71 | if cw.PaintPixels != nil { 72 | w, err = walk.NewCustomWidgetPixels(builder.Parent(), uint(cw.Style), cw.PaintPixels) 73 | } else { 74 | w, err = walk.NewCustomWidget(builder.Parent(), uint(cw.Style), cw.Paint) 75 | } 76 | if err != nil { 77 | return err 78 | } 79 | 80 | if cw.AssignTo != nil { 81 | *cw.AssignTo = w 82 | } 83 | 84 | return builder.InitWidget(cw, w, func() error { 85 | if cw.PaintMode != PaintNormal && cw.ClearsBackground { 86 | panic("PaintMode and ClearsBackground are incompatible") 87 | } 88 | w.SetClearsBackground(cw.ClearsBackground) 89 | w.SetInvalidatesOnResize(cw.InvalidatesOnResize) 90 | w.SetPaintMode(walk.PaintMode(cw.PaintMode)) 91 | 92 | return nil 93 | }) 94 | } 95 | -------------------------------------------------------------------------------- /declarative/databinder.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "time" 11 | 12 | "github.com/lxn/walk" 13 | ) 14 | 15 | type DataBinder struct { 16 | AssignTo **walk.DataBinder 17 | AutoSubmit bool 18 | AutoSubmitDelay time.Duration 19 | DataSource interface{} 20 | ErrorPresenter ErrorPresenter 21 | Name string 22 | OnCanSubmitChanged walk.EventHandler 23 | OnDataSourceChanged walk.EventHandler 24 | OnReset walk.EventHandler 25 | OnSubmitted walk.EventHandler 26 | } 27 | 28 | func (db DataBinder) create() (*walk.DataBinder, error) { 29 | b := walk.NewDataBinder() 30 | 31 | if db.AssignTo != nil { 32 | *db.AssignTo = b 33 | } 34 | 35 | if db.ErrorPresenter != nil { 36 | ep, err := db.ErrorPresenter.Create() 37 | if err != nil { 38 | return nil, err 39 | } 40 | b.SetErrorPresenter(ep) 41 | } 42 | 43 | b.SetDataSource(db.DataSource) 44 | 45 | b.SetAutoSubmit(db.AutoSubmit) 46 | b.SetAutoSubmitDelay(db.AutoSubmitDelay) 47 | 48 | if db.OnCanSubmitChanged != nil { 49 | b.CanSubmitChanged().Attach(db.OnCanSubmitChanged) 50 | } 51 | if db.OnDataSourceChanged != nil { 52 | b.DataSourceChanged().Attach(db.OnDataSourceChanged) 53 | } 54 | if db.OnReset != nil { 55 | b.ResetFinished().Attach(db.OnReset) 56 | } 57 | if db.OnSubmitted != nil { 58 | b.Submitted().Attach(db.OnSubmitted) 59 | } 60 | 61 | return b, nil 62 | } 63 | -------------------------------------------------------------------------------- /declarative/dateedit.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "time" 11 | ) 12 | 13 | import ( 14 | "github.com/lxn/walk" 15 | ) 16 | 17 | type DateEdit struct { 18 | // Window 19 | 20 | Accessibility Accessibility 21 | Background Brush 22 | ContextMenuItems []MenuItem 23 | DoubleBuffering bool 24 | Enabled Property 25 | Font Font 26 | MaxSize Size 27 | MinSize Size 28 | Name string 29 | OnBoundsChanged walk.EventHandler 30 | OnKeyDown walk.KeyEventHandler 31 | OnKeyPress walk.KeyEventHandler 32 | OnKeyUp walk.KeyEventHandler 33 | OnMouseDown walk.MouseEventHandler 34 | OnMouseMove walk.MouseEventHandler 35 | OnMouseUp walk.MouseEventHandler 36 | OnSizeChanged walk.EventHandler 37 | Persistent bool 38 | RightToLeftReading bool 39 | ToolTipText Property 40 | Visible Property 41 | 42 | // Widget 43 | 44 | Alignment Alignment2D 45 | AlwaysConsumeSpace bool 46 | Column int 47 | ColumnSpan int 48 | GraphicsEffects []walk.WidgetGraphicsEffect 49 | Row int 50 | RowSpan int 51 | StretchFactor int 52 | 53 | // DateEdit 54 | 55 | AssignTo **walk.DateEdit 56 | Date Property 57 | Format string 58 | MaxDate time.Time 59 | MinDate time.Time 60 | NoneOption bool // Deprecated: use Optional instead 61 | OnDateChanged walk.EventHandler 62 | Optional bool 63 | } 64 | 65 | func (de DateEdit) Create(builder *Builder) error { 66 | var w *walk.DateEdit 67 | var err error 68 | 69 | if de.Optional || de.NoneOption { 70 | w, err = walk.NewDateEditWithNoneOption(builder.Parent()) 71 | } else { 72 | w, err = walk.NewDateEdit(builder.Parent()) 73 | } 74 | if err != nil { 75 | return err 76 | } 77 | 78 | if de.AssignTo != nil { 79 | *de.AssignTo = w 80 | } 81 | 82 | return builder.InitWidget(de, w, func() error { 83 | if err := w.SetFormat(de.Format); err != nil { 84 | return err 85 | } 86 | 87 | if err := w.SetRange(de.MinDate, de.MaxDate); err != nil { 88 | return err 89 | } 90 | 91 | if de.OnDateChanged != nil { 92 | w.DateChanged().Attach(de.OnDateChanged) 93 | } 94 | 95 | return nil 96 | }) 97 | } 98 | -------------------------------------------------------------------------------- /declarative/datelabel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type DateLabel struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // static 50 | 51 | TextColor walk.Color 52 | 53 | // DateLabel 54 | 55 | AssignTo **walk.DateLabel 56 | Date Property 57 | Format Property 58 | TextAlignment Alignment1D 59 | } 60 | 61 | func (dl DateLabel) Create(builder *Builder) error { 62 | w, err := walk.NewDateLabel(builder.Parent()) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | if dl.AssignTo != nil { 68 | *dl.AssignTo = w 69 | } 70 | 71 | return builder.InitWidget(dl, w, func() error { 72 | if err := w.SetTextAlignment(walk.Alignment1D(dl.TextAlignment)); err != nil { 73 | return err 74 | } 75 | 76 | w.SetTextColor(dl.TextColor) 77 | 78 | return nil 79 | }) 80 | } 81 | -------------------------------------------------------------------------------- /declarative/font.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type Font struct { 14 | Family string 15 | PointSize int 16 | Bold bool 17 | Italic bool 18 | Underline bool 19 | StrikeOut bool 20 | } 21 | 22 | func (f Font) Create() (*walk.Font, error) { 23 | if f.Family == "" && f.PointSize == 0 { 24 | return nil, nil 25 | } 26 | 27 | var fs walk.FontStyle 28 | 29 | if f.Bold { 30 | fs |= walk.FontBold 31 | } 32 | if f.Italic { 33 | fs |= walk.FontItalic 34 | } 35 | if f.Underline { 36 | fs |= walk.FontUnderline 37 | } 38 | if f.StrikeOut { 39 | fs |= walk.FontStrikeOut 40 | } 41 | 42 | return walk.NewFont(f.Family, f.PointSize, fs) 43 | } 44 | -------------------------------------------------------------------------------- /declarative/gradientcomposite.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | "github.com/lxn/win" 12 | ) 13 | 14 | type GradientComposite struct { 15 | // Window 16 | 17 | Accessibility Accessibility 18 | Background Brush 19 | ContextMenuItems []MenuItem 20 | DoubleBuffering bool 21 | Enabled Property 22 | Font Font 23 | MaxSize Size 24 | MinSize Size 25 | Name string 26 | OnBoundsChanged walk.EventHandler 27 | OnKeyDown walk.KeyEventHandler 28 | OnKeyPress walk.KeyEventHandler 29 | OnKeyUp walk.KeyEventHandler 30 | OnMouseDown walk.MouseEventHandler 31 | OnMouseMove walk.MouseEventHandler 32 | OnMouseUp walk.MouseEventHandler 33 | OnSizeChanged walk.EventHandler 34 | Persistent bool 35 | RightToLeftReading bool 36 | ToolTipText Property 37 | Visible Property 38 | 39 | // Widget 40 | 41 | Alignment Alignment2D 42 | AlwaysConsumeSpace bool 43 | Column int 44 | ColumnSpan int 45 | GraphicsEffects []walk.WidgetGraphicsEffect 46 | Row int 47 | RowSpan int 48 | StretchFactor int 49 | 50 | // Container 51 | 52 | Children []Widget 53 | Layout Layout 54 | DataBinder DataBinder 55 | 56 | // GradientComposite 57 | 58 | AssignTo **walk.GradientComposite 59 | Border bool 60 | Color1 Property 61 | Color2 Property 62 | Expressions func() map[string]walk.Expression 63 | Functions map[string]func(args ...interface{}) (interface{}, error) 64 | Vertical Property 65 | } 66 | 67 | func (gc GradientComposite) Create(builder *Builder) error { 68 | var style uint32 69 | if gc.Border { 70 | style |= win.WS_BORDER 71 | } 72 | w, err := walk.NewGradientCompositeWithStyle(builder.Parent(), style) 73 | if err != nil { 74 | return err 75 | } 76 | 77 | if gc.AssignTo != nil { 78 | *gc.AssignTo = w 79 | } 80 | 81 | w.SetSuspended(true) 82 | builder.Defer(func() error { 83 | w.SetSuspended(false) 84 | return nil 85 | }) 86 | 87 | return builder.InitWidget(gc, w, func() error { 88 | if gc.Expressions != nil { 89 | for name, expr := range gc.Expressions() { 90 | builder.expressions[name] = expr 91 | } 92 | } 93 | if gc.Functions != nil { 94 | for name, fn := range gc.Functions { 95 | builder.functions[name] = fn 96 | } 97 | } 98 | 99 | return nil 100 | }) 101 | } 102 | -------------------------------------------------------------------------------- /declarative/groupbox.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type GroupBox struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Container 50 | 51 | Children []Widget 52 | DataBinder DataBinder 53 | Layout Layout 54 | 55 | // GroupBox 56 | 57 | AssignTo **walk.GroupBox 58 | Checkable bool 59 | Checked Property 60 | Title string 61 | } 62 | 63 | func (gb GroupBox) Create(builder *Builder) error { 64 | w, err := walk.NewGroupBox(builder.Parent()) 65 | if err != nil { 66 | return err 67 | } 68 | 69 | if gb.AssignTo != nil { 70 | *gb.AssignTo = w 71 | } 72 | 73 | w.SetSuspended(true) 74 | builder.Defer(func() error { 75 | w.SetSuspended(false) 76 | return nil 77 | }) 78 | 79 | return builder.InitWidget(gb, w, func() error { 80 | if err := w.SetTitle(gb.Title); err != nil { 81 | return err 82 | } 83 | 84 | w.SetCheckable(gb.Checkable) 85 | 86 | return nil 87 | }) 88 | } 89 | -------------------------------------------------------------------------------- /declarative/imageview.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type ImageViewMode int 14 | 15 | const ( 16 | ImageViewModeIdeal = ImageViewMode(walk.ImageViewModeIdeal) 17 | ImageViewModeCorner = ImageViewMode(walk.ImageViewModeCorner) 18 | ImageViewModeCenter = ImageViewMode(walk.ImageViewModeCenter) 19 | ImageViewModeShrink = ImageViewMode(walk.ImageViewModeShrink) 20 | ImageViewModeZoom = ImageViewMode(walk.ImageViewModeZoom) 21 | ImageViewModeStretch = ImageViewMode(walk.ImageViewModeStretch) 22 | ) 23 | 24 | type ImageView struct { 25 | // Window 26 | 27 | Accessibility Accessibility 28 | Background Brush 29 | ContextMenuItems []MenuItem 30 | DoubleBuffering bool 31 | Enabled Property 32 | Font Font 33 | MaxSize Size 34 | MinSize Size 35 | Name string 36 | OnBoundsChanged walk.EventHandler 37 | OnKeyDown walk.KeyEventHandler 38 | OnKeyPress walk.KeyEventHandler 39 | OnKeyUp walk.KeyEventHandler 40 | OnMouseDown walk.MouseEventHandler 41 | OnMouseMove walk.MouseEventHandler 42 | OnMouseUp walk.MouseEventHandler 43 | OnSizeChanged walk.EventHandler 44 | Persistent bool 45 | RightToLeftReading bool 46 | ToolTipText Property 47 | Visible Property 48 | 49 | // Widget 50 | 51 | Alignment Alignment2D 52 | AlwaysConsumeSpace bool 53 | Column int 54 | ColumnSpan int 55 | GraphicsEffects []walk.WidgetGraphicsEffect 56 | Row int 57 | RowSpan int 58 | StretchFactor int 59 | 60 | // ImageView 61 | 62 | AssignTo **walk.ImageView 63 | Image Property 64 | Margin Property 65 | Mode ImageViewMode 66 | } 67 | 68 | func (iv ImageView) Create(builder *Builder) error { 69 | w, err := walk.NewImageView(builder.Parent()) 70 | if err != nil { 71 | return err 72 | } 73 | 74 | if iv.AssignTo != nil { 75 | *iv.AssignTo = w 76 | } 77 | 78 | return builder.InitWidget(iv, w, func() error { 79 | w.SetMode(walk.ImageViewMode(iv.Mode)) 80 | 81 | return nil 82 | }) 83 | } 84 | -------------------------------------------------------------------------------- /declarative/label.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | "github.com/lxn/win" 12 | ) 13 | 14 | type EllipsisMode int 15 | 16 | const ( 17 | EllipsisNone = EllipsisMode(walk.EllipsisNone) 18 | EllipsisEnd = EllipsisMode(walk.EllipsisEnd) 19 | EllipsisPath = EllipsisMode(walk.EllipsisPath) 20 | ) 21 | 22 | type Label struct { 23 | // Window 24 | 25 | Accessibility Accessibility 26 | Background Brush 27 | ContextMenuItems []MenuItem 28 | DoubleBuffering bool 29 | Enabled Property 30 | Font Font 31 | MaxSize Size 32 | MinSize Size 33 | Name string 34 | OnBoundsChanged walk.EventHandler 35 | OnKeyDown walk.KeyEventHandler 36 | OnKeyPress walk.KeyEventHandler 37 | OnKeyUp walk.KeyEventHandler 38 | OnMouseDown walk.MouseEventHandler 39 | OnMouseMove walk.MouseEventHandler 40 | OnMouseUp walk.MouseEventHandler 41 | OnSizeChanged walk.EventHandler 42 | Persistent bool 43 | RightToLeftReading bool 44 | ToolTipText Property 45 | Visible Property 46 | 47 | // Widget 48 | 49 | Alignment Alignment2D 50 | AlwaysConsumeSpace bool 51 | Column int 52 | ColumnSpan int 53 | GraphicsEffects []walk.WidgetGraphicsEffect 54 | Row int 55 | RowSpan int 56 | StretchFactor int 57 | 58 | // Label 59 | 60 | AssignTo **walk.Label 61 | EllipsisMode EllipsisMode 62 | NoPrefix bool 63 | Text Property 64 | TextAlignment Alignment1D 65 | TextColor walk.Color 66 | } 67 | 68 | func (l Label) Create(builder *Builder) error { 69 | var style uint32 70 | if l.NoPrefix { 71 | style |= win.SS_NOPREFIX 72 | } 73 | 74 | w, err := walk.NewLabelWithStyle(builder.Parent(), style) 75 | if err != nil { 76 | return err 77 | } 78 | 79 | if l.AssignTo != nil { 80 | *l.AssignTo = w 81 | } 82 | 83 | return builder.InitWidget(l, w, func() error { 84 | if err := w.SetEllipsisMode(walk.EllipsisMode(l.EllipsisMode)); err != nil { 85 | return err 86 | } 87 | 88 | if err := w.SetTextAlignment(walk.Alignment1D(l.TextAlignment)); err != nil { 89 | return err 90 | } 91 | 92 | w.SetTextColor(l.TextColor) 93 | 94 | return nil 95 | }) 96 | } 97 | -------------------------------------------------------------------------------- /declarative/lineedit.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type CaseMode uint32 14 | 15 | const ( 16 | CaseModeMixed CaseMode = CaseMode(walk.CaseModeMixed) 17 | CaseModeUpper CaseMode = CaseMode(walk.CaseModeUpper) 18 | CaseModeLower CaseMode = CaseMode(walk.CaseModeLower) 19 | ) 20 | 21 | type LineEdit struct { 22 | // Window 23 | 24 | Accessibility Accessibility 25 | Background Brush 26 | ContextMenuItems []MenuItem 27 | DoubleBuffering bool 28 | Enabled Property 29 | Font Font 30 | MaxSize Size 31 | MinSize Size 32 | Name string 33 | OnBoundsChanged walk.EventHandler 34 | OnKeyDown walk.KeyEventHandler 35 | OnKeyPress walk.KeyEventHandler 36 | OnKeyUp walk.KeyEventHandler 37 | OnMouseDown walk.MouseEventHandler 38 | OnMouseMove walk.MouseEventHandler 39 | OnMouseUp walk.MouseEventHandler 40 | OnSizeChanged walk.EventHandler 41 | Persistent bool 42 | RightToLeftReading bool 43 | ToolTipText Property 44 | Visible Property 45 | 46 | // Widget 47 | 48 | Alignment Alignment2D 49 | AlwaysConsumeSpace bool 50 | Column int 51 | ColumnSpan int 52 | GraphicsEffects []walk.WidgetGraphicsEffect 53 | Row int 54 | RowSpan int 55 | StretchFactor int 56 | 57 | // LineEdit 58 | 59 | AssignTo **walk.LineEdit 60 | CaseMode CaseMode 61 | CueBanner string 62 | MaxLength int 63 | OnEditingFinished walk.EventHandler 64 | OnTextChanged walk.EventHandler 65 | PasswordMode bool 66 | ReadOnly Property 67 | Text Property 68 | TextAlignment Alignment1D 69 | TextColor walk.Color 70 | } 71 | 72 | func (le LineEdit) Create(builder *Builder) error { 73 | w, err := walk.NewLineEdit(builder.Parent()) 74 | if err != nil { 75 | return err 76 | } 77 | 78 | if le.AssignTo != nil { 79 | *le.AssignTo = w 80 | } 81 | 82 | return builder.InitWidget(le, w, func() error { 83 | w.SetTextColor(le.TextColor) 84 | 85 | if err := w.SetTextAlignment(walk.Alignment1D(le.TextAlignment)); err != nil { 86 | return err 87 | } 88 | 89 | if le.CueBanner != "" { 90 | if err := w.SetCueBanner(le.CueBanner); err != nil { 91 | return err 92 | } 93 | } 94 | w.SetMaxLength(le.MaxLength) 95 | w.SetPasswordMode(le.PasswordMode) 96 | 97 | if err := w.SetCaseMode(walk.CaseMode(le.CaseMode)); err != nil { 98 | return err 99 | } 100 | 101 | if le.OnEditingFinished != nil { 102 | w.EditingFinished().Attach(le.OnEditingFinished) 103 | } 104 | if le.OnTextChanged != nil { 105 | w.TextChanged().Attach(le.OnTextChanged) 106 | } 107 | 108 | return nil 109 | }) 110 | } 111 | -------------------------------------------------------------------------------- /declarative/linklabel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type LinkLabel struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // LinkLabel 50 | 51 | AssignTo **walk.LinkLabel 52 | OnLinkActivated walk.LinkLabelLinkEventHandler 53 | Text Property 54 | } 55 | 56 | func (ll LinkLabel) Create(builder *Builder) error { 57 | w, err := walk.NewLinkLabel(builder.Parent()) 58 | if err != nil { 59 | return err 60 | } 61 | 62 | if ll.AssignTo != nil { 63 | *ll.AssignTo = w 64 | } 65 | 66 | return builder.InitWidget(ll, w, func() error { 67 | if ll.OnLinkActivated != nil { 68 | w.LinkActivated().Attach(ll.OnLinkActivated) 69 | } 70 | 71 | return nil 72 | }) 73 | } 74 | -------------------------------------------------------------------------------- /declarative/nonwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The win Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !windows 6 | 7 | package declarative 8 | -------------------------------------------------------------------------------- /declarative/numberedit.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type NumberEdit struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // NumberEdit 50 | 51 | AssignTo **walk.NumberEdit 52 | Decimals int 53 | Increment float64 54 | MaxValue float64 55 | MinValue float64 56 | Prefix Property 57 | OnValueChanged walk.EventHandler 58 | ReadOnly Property 59 | SpinButtonsVisible bool 60 | Suffix Property 61 | TextColor walk.Color 62 | Value Property 63 | } 64 | 65 | func (ne NumberEdit) Create(builder *Builder) error { 66 | w, err := walk.NewNumberEdit(builder.Parent()) 67 | if err != nil { 68 | return err 69 | } 70 | 71 | if ne.AssignTo != nil { 72 | *ne.AssignTo = w 73 | } 74 | 75 | return builder.InitWidget(ne, w, func() error { 76 | w.SetTextColor(ne.TextColor) 77 | 78 | if err := w.SetDecimals(ne.Decimals); err != nil { 79 | return err 80 | } 81 | 82 | inc := ne.Increment 83 | if inc == 0 { 84 | inc = 1 85 | } 86 | 87 | if err := w.SetIncrement(inc); err != nil { 88 | return err 89 | } 90 | 91 | if ne.MinValue != 0 || ne.MaxValue != 0 { 92 | if err := w.SetRange(ne.MinValue, ne.MaxValue); err != nil { 93 | return err 94 | } 95 | } 96 | 97 | if err := w.SetSpinButtonsVisible(ne.SpinButtonsVisible); err != nil { 98 | return err 99 | } 100 | 101 | if ne.OnValueChanged != nil { 102 | w.ValueChanged().Attach(ne.OnValueChanged) 103 | } 104 | 105 | return nil 106 | }) 107 | } 108 | -------------------------------------------------------------------------------- /declarative/numberlabel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type NumberLabel struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // static 50 | 51 | TextColor walk.Color 52 | 53 | // NumberLabel 54 | 55 | AssignTo **walk.NumberLabel 56 | Decimals Property 57 | Suffix Property 58 | TextAlignment Alignment1D 59 | Value Property 60 | } 61 | 62 | func (nl NumberLabel) Create(builder *Builder) error { 63 | w, err := walk.NewNumberLabel(builder.Parent()) 64 | if err != nil { 65 | return err 66 | } 67 | 68 | if nl.AssignTo != nil { 69 | *nl.AssignTo = w 70 | } 71 | 72 | return builder.InitWidget(nl, w, func() error { 73 | if err := w.SetTextAlignment(walk.Alignment1D(nl.TextAlignment)); err != nil { 74 | return err 75 | } 76 | 77 | w.SetTextColor(nl.TextColor) 78 | 79 | return nil 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /declarative/progressbar.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type ProgressBar struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // ProgressBar 50 | 51 | AssignTo **walk.ProgressBar 52 | MarqueeMode bool 53 | MaxValue int 54 | MinValue int 55 | Value int 56 | } 57 | 58 | func (pb ProgressBar) Create(builder *Builder) error { 59 | w, err := walk.NewProgressBar(builder.Parent()) 60 | if err != nil { 61 | return err 62 | } 63 | 64 | if pb.AssignTo != nil { 65 | *pb.AssignTo = w 66 | } 67 | 68 | return builder.InitWidget(pb, w, func() error { 69 | if pb.MaxValue > pb.MinValue { 70 | w.SetRange(pb.MinValue, pb.MaxValue) 71 | } 72 | w.SetValue(pb.Value) 73 | 74 | if err := w.SetMarqueeMode(pb.MarqueeMode); err != nil { 75 | return err 76 | } 77 | 78 | return nil 79 | }) 80 | } 81 | -------------------------------------------------------------------------------- /declarative/pushbutton.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type PushButton struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Button 50 | 51 | Image Property 52 | OnClicked walk.EventHandler 53 | Text Property 54 | 55 | // PushButton 56 | 57 | AssignTo **walk.PushButton 58 | ImageAboveText bool 59 | } 60 | 61 | func (pb PushButton) Create(builder *Builder) error { 62 | w, err := walk.NewPushButton(builder.Parent()) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | if pb.AssignTo != nil { 68 | *pb.AssignTo = w 69 | } 70 | 71 | return builder.InitWidget(pb, w, func() error { 72 | if err := w.SetImageAboveText(pb.ImageAboveText); err != nil { 73 | return err 74 | } 75 | 76 | if pb.OnClicked != nil { 77 | w.Clicked().Attach(pb.OnClicked) 78 | } 79 | 80 | return nil 81 | }) 82 | } 83 | -------------------------------------------------------------------------------- /declarative/radiobutton.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type RadioButton struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Button 50 | 51 | OnClicked walk.EventHandler 52 | Text Property 53 | 54 | // RadioButton 55 | 56 | AssignTo **walk.RadioButton 57 | TextOnLeftSide bool 58 | Value interface{} 59 | } 60 | 61 | func (rb RadioButton) Create(builder *Builder) error { 62 | w, err := walk.NewRadioButton(builder.Parent()) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | if rb.AssignTo != nil { 68 | *rb.AssignTo = w 69 | } 70 | 71 | return builder.InitWidget(rb, w, func() error { 72 | w.SetValue(rb.Value) 73 | 74 | if err := w.SetTextOnLeftSide(rb.TextOnLeftSide); err != nil { 75 | return err 76 | } 77 | 78 | if rb.OnClicked != nil { 79 | w.Clicked().Attach(rb.OnClicked) 80 | } 81 | 82 | return nil 83 | }) 84 | } 85 | -------------------------------------------------------------------------------- /declarative/radiobuttongroup.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "bytes" 11 | "errors" 12 | ) 13 | 14 | import ( 15 | "github.com/lxn/walk" 16 | ) 17 | 18 | type RadioButtonGroup struct { 19 | Buttons []RadioButton 20 | DataMember string 21 | Optional bool 22 | } 23 | 24 | func (rbg RadioButtonGroup) Create(builder *Builder) error { 25 | if len(rbg.Buttons) == 0 { 26 | return nil 27 | } 28 | 29 | var first *walk.RadioButton 30 | 31 | for _, rb := range rbg.Buttons { 32 | if first == nil { 33 | if rb.AssignTo == nil { 34 | rb.AssignTo = &first 35 | } 36 | } 37 | 38 | if err := rb.Create(builder); err != nil { 39 | return err 40 | } 41 | 42 | if first == nil { 43 | first = *rb.AssignTo 44 | } 45 | } 46 | 47 | parent := builder.Parent() 48 | 49 | builder.Defer(func() error { 50 | group := first.Group() 51 | 52 | validator := newRadioButtonGroupValidator(group, parent) 53 | 54 | for _, rb := range group.Buttons() { 55 | prop := rb.AsWindowBase().Property("CheckedValue") 56 | 57 | if err := prop.SetSource(rbg.DataMember); err != nil { 58 | return err 59 | } 60 | if err := prop.SetValidator(validator); err != nil { 61 | return err 62 | } 63 | } 64 | 65 | return nil 66 | }) 67 | 68 | return nil 69 | } 70 | 71 | type radioButtonGroupValidator struct { 72 | group *walk.RadioButtonGroup 73 | err error 74 | } 75 | 76 | func newRadioButtonGroupValidator(group *walk.RadioButtonGroup, parent walk.Container) *radioButtonGroupValidator { 77 | b := new(bytes.Buffer) 78 | 79 | if gb, ok := parent.(*walk.GroupBox); ok { 80 | b.WriteString(gb.Title()) 81 | } else { 82 | for i, rb := range group.Buttons() { 83 | if i > 0 { 84 | b.WriteString(", ") 85 | } 86 | 87 | b.WriteString(rb.Text()) 88 | } 89 | } 90 | 91 | b.WriteString(": ") 92 | 93 | b.WriteString(tr("A selection is required.", "walk")) 94 | 95 | return &radioButtonGroupValidator{group: group, err: errors.New(b.String())} 96 | } 97 | 98 | func (rbgv *radioButtonGroupValidator) Validate(v interface{}) error { 99 | if rbgv.group.CheckedButton() == nil { 100 | return rbgv.err 101 | } 102 | 103 | return nil 104 | } 105 | -------------------------------------------------------------------------------- /declarative/radiobuttongroupbox.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type RadioButtonGroupBox struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Container 50 | 51 | Children []Widget 52 | DataBinder DataBinder 53 | Layout Layout 54 | 55 | // GroupBox 56 | 57 | AssignTo **walk.GroupBox 58 | Checkable bool 59 | Checked Property 60 | Title string 61 | 62 | // RadioButtonGroupBox 63 | 64 | Buttons []RadioButton 65 | DataMember string 66 | Optional bool 67 | } 68 | 69 | func (rbgb RadioButtonGroupBox) Create(builder *Builder) error { 70 | w, err := walk.NewGroupBox(builder.Parent()) 71 | if err != nil { 72 | return err 73 | } 74 | 75 | if rbgb.AssignTo != nil { 76 | *rbgb.AssignTo = w 77 | } 78 | 79 | w.SetSuspended(true) 80 | builder.Defer(func() error { 81 | w.SetSuspended(false) 82 | return nil 83 | }) 84 | 85 | return builder.InitWidget(rbgb, w, func() error { 86 | if err := w.SetTitle(rbgb.Title); err != nil { 87 | return err 88 | } 89 | 90 | w.SetCheckable(rbgb.Checkable) 91 | 92 | if err := (RadioButtonGroup{ 93 | DataMember: rbgb.DataMember, 94 | Optional: rbgb.Optional, 95 | Buttons: rbgb.Buttons, 96 | }).Create(builder); err != nil { 97 | return err 98 | } 99 | 100 | return nil 101 | }) 102 | } 103 | -------------------------------------------------------------------------------- /declarative/scrollview.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type ScrollView struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Container 50 | 51 | Children []Widget 52 | DataBinder DataBinder 53 | Layout Layout 54 | 55 | // ScrollView 56 | 57 | AssignTo **walk.ScrollView 58 | HorizontalFixed bool 59 | VerticalFixed bool 60 | } 61 | 62 | func (sv ScrollView) Create(builder *Builder) error { 63 | w, err := walk.NewScrollView(builder.Parent()) 64 | if err != nil { 65 | return err 66 | } 67 | 68 | if sv.AssignTo != nil { 69 | *sv.AssignTo = w 70 | } 71 | 72 | w.SetSuspended(true) 73 | builder.Defer(func() error { 74 | w.SetSuspended(false) 75 | return nil 76 | }) 77 | 78 | w.SetScrollbars(!sv.HorizontalFixed, !sv.VerticalFixed) 79 | 80 | return builder.InitWidget(sv, w, func() error { 81 | return nil 82 | }) 83 | } 84 | -------------------------------------------------------------------------------- /declarative/separator.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type HSeparator struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Separator 50 | 51 | AssignTo **walk.Separator 52 | } 53 | 54 | func (s HSeparator) Create(builder *Builder) error { 55 | w, err := walk.NewHSeparator(builder.Parent()) 56 | if err != nil { 57 | return err 58 | } 59 | 60 | if s.AssignTo != nil { 61 | *s.AssignTo = w 62 | } 63 | 64 | return builder.InitWidget(s, w, func() error { 65 | return nil 66 | }) 67 | } 68 | 69 | type VSeparator struct { 70 | // Window 71 | 72 | Accessibility Accessibility 73 | ContextMenuItems []MenuItem 74 | Enabled Property 75 | Font Font 76 | MaxSize Size 77 | MinSize Size 78 | Name string 79 | OnBoundsChanged walk.EventHandler 80 | OnKeyDown walk.KeyEventHandler 81 | OnKeyPress walk.KeyEventHandler 82 | OnKeyUp walk.KeyEventHandler 83 | OnMouseDown walk.MouseEventHandler 84 | OnMouseMove walk.MouseEventHandler 85 | OnMouseUp walk.MouseEventHandler 86 | OnSizeChanged walk.EventHandler 87 | Persistent bool 88 | ToolTipText Property 89 | Visible Property 90 | 91 | // Widget 92 | 93 | AlwaysConsumeSpace bool 94 | Column int 95 | ColumnSpan int 96 | Row int 97 | RowSpan int 98 | StretchFactor int 99 | 100 | // Separator 101 | 102 | AssignTo **walk.Separator 103 | } 104 | 105 | func (s VSeparator) Create(builder *Builder) error { 106 | w, err := walk.NewVSeparator(builder.Parent()) 107 | if err != nil { 108 | return err 109 | } 110 | 111 | if s.AssignTo != nil { 112 | *s.AssignTo = w 113 | } 114 | 115 | return builder.InitWidget(s, w, func() error { 116 | return nil 117 | }) 118 | } 119 | -------------------------------------------------------------------------------- /declarative/slider.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type Slider struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Slider 50 | 51 | AssignTo **walk.Slider 52 | LineSize int 53 | MaxValue int 54 | MinValue int 55 | Orientation Orientation 56 | OnValueChanged walk.EventHandler 57 | PageSize int 58 | ToolTipsHidden bool 59 | Tracking bool 60 | Value Property 61 | } 62 | 63 | func (sl Slider) Create(builder *Builder) error { 64 | w, err := walk.NewSliderWithCfg(builder.Parent(), &walk.SliderCfg{ 65 | Orientation: walk.Orientation(sl.Orientation), 66 | ToolTipsHidden: sl.ToolTipsHidden, 67 | }) 68 | if err != nil { 69 | return err 70 | } 71 | 72 | if sl.AssignTo != nil { 73 | *sl.AssignTo = w 74 | } 75 | 76 | return builder.InitWidget(sl, w, func() error { 77 | w.SetPersistent(sl.Persistent) 78 | if sl.LineSize > 0 { 79 | w.SetLineSize(sl.LineSize) 80 | } 81 | if sl.PageSize > 0 { 82 | w.SetPageSize(sl.PageSize) 83 | } 84 | w.SetTracking(sl.Tracking) 85 | 86 | if sl.MaxValue > sl.MinValue { 87 | w.SetRange(sl.MinValue, sl.MaxValue) 88 | } 89 | 90 | if sl.OnValueChanged != nil { 91 | w.ValueChanged().Attach(sl.OnValueChanged) 92 | } 93 | 94 | return nil 95 | }) 96 | } 97 | -------------------------------------------------------------------------------- /declarative/spacer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type HSpacer struct { 14 | // Window 15 | 16 | MaxSize Size 17 | MinSize Size 18 | Name string 19 | 20 | // Widget 21 | 22 | Column int 23 | ColumnSpan int 24 | Row int 25 | RowSpan int 26 | StretchFactor int 27 | 28 | // Spacer 29 | 30 | GreedyLocallyOnly bool 31 | Size int 32 | } 33 | 34 | func (hs HSpacer) Create(builder *Builder) (err error) { 35 | var flags walk.LayoutFlags 36 | if hs.Size == 0 { 37 | flags = walk.ShrinkableHorz | walk.GrowableHorz | walk.GreedyHorz 38 | } 39 | 40 | var w *walk.Spacer 41 | if w, err = walk.NewSpacerWithCfg(builder.Parent(), &walk.SpacerCfg{ 42 | LayoutFlags: flags, 43 | SizeHint: Size{Width: hs.Size}.toW(), 44 | GreedyLocallyOnly: hs.GreedyLocallyOnly, 45 | }); err != nil { 46 | return 47 | } 48 | 49 | return builder.InitWidget(hs, w, nil) 50 | } 51 | 52 | type VSpacer struct { 53 | // Window 54 | 55 | MaxSize Size 56 | MinSize Size 57 | Name string 58 | 59 | // Widget 60 | 61 | Column int 62 | ColumnSpan int 63 | Row int 64 | RowSpan int 65 | StretchFactor int 66 | 67 | // Spacer 68 | 69 | GreedyLocallyOnly bool 70 | Size int 71 | } 72 | 73 | func (vs VSpacer) Create(builder *Builder) (err error) { 74 | var flags walk.LayoutFlags 75 | if vs.Size == 0 { 76 | flags = walk.ShrinkableVert | walk.GrowableVert | walk.GreedyVert 77 | } 78 | 79 | var w *walk.Spacer 80 | if w, err = walk.NewSpacerWithCfg(builder.Parent(), &walk.SpacerCfg{ 81 | LayoutFlags: flags, 82 | SizeHint: Size{Height: vs.Size}.toW(), 83 | GreedyLocallyOnly: vs.GreedyLocallyOnly, 84 | }); err != nil { 85 | return 86 | } 87 | 88 | return builder.InitWidget(vs, w, nil) 89 | } 90 | -------------------------------------------------------------------------------- /declarative/splitbutton.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type SplitButton struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Button 50 | 51 | Image Property 52 | Text Property 53 | OnClicked walk.EventHandler 54 | 55 | // SplitButton 56 | 57 | AssignTo **walk.SplitButton 58 | ImageAboveText bool 59 | MenuItems []MenuItem 60 | } 61 | 62 | func (sb SplitButton) Create(builder *Builder) error { 63 | w, err := walk.NewSplitButton(builder.Parent()) 64 | if err != nil { 65 | return err 66 | } 67 | 68 | if sb.AssignTo != nil { 69 | *sb.AssignTo = w 70 | } 71 | 72 | builder.deferBuildMenuActions(w.Menu(), sb.MenuItems) 73 | 74 | return builder.InitWidget(sb, w, func() error { 75 | if err := w.SetImageAboveText(sb.ImageAboveText); err != nil { 76 | return err 77 | } 78 | 79 | if sb.OnClicked != nil { 80 | w.Clicked().Attach(sb.OnClicked) 81 | } 82 | 83 | return nil 84 | }) 85 | } 86 | -------------------------------------------------------------------------------- /declarative/tableviewcolumn.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type Alignment1D uint 14 | 15 | const ( 16 | AlignDefault = Alignment1D(walk.AlignDefault) 17 | AlignNear = Alignment1D(walk.AlignNear) 18 | AlignCenter = Alignment1D(walk.AlignCenter) 19 | AlignFar = Alignment1D(walk.AlignFar) 20 | ) 21 | 22 | type TableViewColumn struct { 23 | Name string 24 | DataMember string 25 | Format string 26 | Title string 27 | Alignment Alignment1D 28 | Precision int 29 | Width int 30 | Hidden bool 31 | Frozen bool 32 | StyleCell func(style *walk.CellStyle) 33 | LessFunc func(i, j int) bool 34 | FormatFunc func(value interface{}) string 35 | } 36 | 37 | func (tvc TableViewColumn) Create(tv *walk.TableView) error { 38 | w := walk.NewTableViewColumn() 39 | 40 | if err := w.SetAlignment(walk.Alignment1D(tvc.Alignment)); err != nil { 41 | return err 42 | } 43 | w.SetDataMember(tvc.DataMember) 44 | if tvc.Format != "" { 45 | if err := w.SetFormat(tvc.Format); err != nil { 46 | return err 47 | } 48 | } 49 | if err := w.SetPrecision(tvc.Precision); err != nil { 50 | return err 51 | } 52 | w.SetName(tvc.Name) 53 | if err := w.SetTitle(tvc.Title); err != nil { 54 | return err 55 | } 56 | if err := w.SetVisible(!tvc.Hidden); err != nil { 57 | return err 58 | } 59 | if err := w.SetFrozen(tvc.Frozen); err != nil { 60 | return err 61 | } 62 | if err := w.SetWidth(tvc.Width); err != nil { 63 | return err 64 | } 65 | w.SetLessFunc(tvc.LessFunc) 66 | w.SetFormatFunc(tvc.FormatFunc) 67 | 68 | return tv.Columns().Add(w) 69 | } 70 | -------------------------------------------------------------------------------- /declarative/tabpage.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type TabPage struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | AlwaysConsumeSpace bool 41 | Column int 42 | ColumnSpan int 43 | GraphicsEffects []walk.WidgetGraphicsEffect 44 | Row int 45 | RowSpan int 46 | StretchFactor int 47 | 48 | // Container 49 | 50 | Children []Widget 51 | DataBinder DataBinder 52 | Layout Layout 53 | 54 | // TabPage 55 | 56 | AssignTo **walk.TabPage 57 | Content Widget 58 | Image Property 59 | Title Property 60 | } 61 | 62 | func (tp TabPage) Create(builder *Builder) error { 63 | w, err := walk.NewTabPage() 64 | if err != nil { 65 | return err 66 | } 67 | 68 | if tp.AssignTo != nil { 69 | *tp.AssignTo = w 70 | } 71 | 72 | return builder.InitWidget(tp, w, func() error { 73 | if tp.Content != nil && len(tp.Children) == 0 { 74 | if err := tp.Content.Create(builder); err != nil { 75 | return err 76 | } 77 | } 78 | 79 | return nil 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /declarative/tabwidget.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type TabWidget struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // TabWidget 50 | 51 | AssignTo **walk.TabWidget 52 | ContentMargins Margins 53 | ContentMarginsZero bool 54 | OnCurrentIndexChanged walk.EventHandler 55 | Pages []TabPage 56 | } 57 | 58 | func (tw TabWidget) Create(builder *Builder) error { 59 | w, err := walk.NewTabWidget(builder.Parent()) 60 | if err != nil { 61 | return err 62 | } 63 | 64 | if tw.AssignTo != nil { 65 | *tw.AssignTo = w 66 | } 67 | 68 | return builder.InitWidget(tw, w, func() error { 69 | for _, tp := range tw.Pages { 70 | var wp *walk.TabPage 71 | if tp.AssignTo == nil { 72 | tp.AssignTo = &wp 73 | } 74 | 75 | if tp.Content != nil && len(tp.Children) == 0 { 76 | tp.Layout = HBox{Margins: tw.ContentMargins, MarginsZero: tw.ContentMarginsZero} 77 | } 78 | 79 | if err := tp.Create(builder); err != nil { 80 | return err 81 | } 82 | 83 | if err := w.Pages().Add(*tp.AssignTo); err != nil { 84 | return err 85 | } 86 | } 87 | 88 | if tw.OnCurrentIndexChanged != nil { 89 | w.CurrentIndexChanged().Attach(tw.OnCurrentIndexChanged) 90 | } 91 | 92 | return nil 93 | }) 94 | } 95 | -------------------------------------------------------------------------------- /declarative/textedit.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | "github.com/lxn/win" 12 | ) 13 | 14 | type TextEdit struct { 15 | // Window 16 | 17 | Accessibility Accessibility 18 | Background Brush 19 | ContextMenuItems []MenuItem 20 | DoubleBuffering bool 21 | Enabled Property 22 | Font Font 23 | MaxSize Size 24 | MinSize Size 25 | Name string 26 | OnBoundsChanged walk.EventHandler 27 | OnKeyDown walk.KeyEventHandler 28 | OnKeyPress walk.KeyEventHandler 29 | OnKeyUp walk.KeyEventHandler 30 | OnMouseDown walk.MouseEventHandler 31 | OnMouseMove walk.MouseEventHandler 32 | OnMouseUp walk.MouseEventHandler 33 | OnSizeChanged walk.EventHandler 34 | Persistent bool 35 | RightToLeftReading bool 36 | ToolTipText Property 37 | Visible Property 38 | 39 | // Widget 40 | 41 | Alignment Alignment2D 42 | AlwaysConsumeSpace bool 43 | Column int 44 | ColumnSpan int 45 | GraphicsEffects []walk.WidgetGraphicsEffect 46 | Row int 47 | RowSpan int 48 | StretchFactor int 49 | 50 | // TextEdit 51 | 52 | AssignTo **walk.TextEdit 53 | CompactHeight bool 54 | HScroll bool 55 | MaxLength int 56 | OnTextChanged walk.EventHandler 57 | ReadOnly Property 58 | Text Property 59 | TextAlignment Alignment1D 60 | TextColor walk.Color 61 | VScroll bool 62 | } 63 | 64 | func (te TextEdit) Create(builder *Builder) error { 65 | var style uint32 66 | if te.HScroll { 67 | style |= win.WS_HSCROLL 68 | } 69 | if te.VScroll { 70 | style |= win.WS_VSCROLL 71 | } 72 | 73 | w, err := walk.NewTextEditWithStyle(builder.Parent(), style) 74 | if err != nil { 75 | return err 76 | } 77 | 78 | if te.AssignTo != nil { 79 | *te.AssignTo = w 80 | } 81 | 82 | return builder.InitWidget(te, w, func() error { 83 | w.SetCompactHeight(te.CompactHeight) 84 | w.SetTextColor(te.TextColor) 85 | 86 | if err := w.SetTextAlignment(walk.Alignment1D(te.TextAlignment)); err != nil { 87 | return err 88 | } 89 | 90 | if te.MaxLength > 0 { 91 | w.SetMaxLength(te.MaxLength) 92 | } 93 | 94 | if te.OnTextChanged != nil { 95 | w.TextChanged().Attach(te.OnTextChanged) 96 | } 97 | 98 | return nil 99 | }) 100 | } 101 | -------------------------------------------------------------------------------- /declarative/textlabel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | "github.com/lxn/win" 12 | ) 13 | 14 | type Alignment2D uint 15 | 16 | const ( 17 | AlignHVDefault = Alignment2D(walk.AlignHVDefault) 18 | AlignHNearVNear = Alignment2D(walk.AlignHNearVNear) 19 | AlignHCenterVNear = Alignment2D(walk.AlignHCenterVNear) 20 | AlignHFarVNear = Alignment2D(walk.AlignHFarVNear) 21 | AlignHNearVCenter = Alignment2D(walk.AlignHNearVCenter) 22 | AlignHCenterVCenter = Alignment2D(walk.AlignHCenterVCenter) 23 | AlignHFarVCenter = Alignment2D(walk.AlignHFarVCenter) 24 | AlignHNearVFar = Alignment2D(walk.AlignHNearVFar) 25 | AlignHCenterVFar = Alignment2D(walk.AlignHCenterVFar) 26 | AlignHFarVFar = Alignment2D(walk.AlignHFarVFar) 27 | ) 28 | 29 | type TextLabel struct { 30 | // Window 31 | 32 | Accessibility Accessibility 33 | Background Brush 34 | ContextMenuItems []MenuItem 35 | DoubleBuffering bool 36 | Enabled Property 37 | Font Font 38 | MaxSize Size 39 | MinSize Size // Set MinSize.Width to a value > 0 to enable dynamic line wrapping. 40 | Name string 41 | OnBoundsChanged walk.EventHandler 42 | OnKeyDown walk.KeyEventHandler 43 | OnKeyPress walk.KeyEventHandler 44 | OnKeyUp walk.KeyEventHandler 45 | OnMouseDown walk.MouseEventHandler 46 | OnMouseMove walk.MouseEventHandler 47 | OnMouseUp walk.MouseEventHandler 48 | OnSizeChanged walk.EventHandler 49 | Persistent bool 50 | RightToLeftReading bool 51 | ToolTipText Property 52 | Visible Property 53 | 54 | // Widget 55 | 56 | Alignment Alignment2D 57 | AlwaysConsumeSpace bool 58 | Column int 59 | ColumnSpan int 60 | GraphicsEffects []walk.WidgetGraphicsEffect 61 | Row int 62 | RowSpan int 63 | StretchFactor int 64 | 65 | // static 66 | 67 | TextColor walk.Color 68 | 69 | // Text 70 | 71 | AssignTo **walk.TextLabel 72 | NoPrefix bool 73 | TextAlignment Alignment2D 74 | Text Property 75 | } 76 | 77 | func (tl TextLabel) Create(builder *Builder) error { 78 | var style uint32 79 | if tl.NoPrefix { 80 | style |= win.SS_NOPREFIX 81 | } 82 | 83 | w, err := walk.NewTextLabelWithStyle(builder.Parent(), style) 84 | if err != nil { 85 | return err 86 | } 87 | 88 | if tl.AssignTo != nil { 89 | *tl.AssignTo = w 90 | } 91 | 92 | return builder.InitWidget(tl, w, func() error { 93 | w.SetTextColor(tl.TextColor) 94 | 95 | if err := w.SetTextAlignment(walk.Alignment2D(tl.TextAlignment)); err != nil { 96 | return err 97 | } 98 | 99 | return nil 100 | }) 101 | } 102 | -------------------------------------------------------------------------------- /declarative/toolbar.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type ToolBarButtonStyle int 14 | 15 | const ( 16 | ToolBarButtonImageOnly ToolBarButtonStyle = iota 17 | ToolBarButtonTextOnly 18 | ToolBarButtonImageBeforeText 19 | ToolBarButtonImageAboveText 20 | ) 21 | 22 | type ToolBar struct { 23 | // Window 24 | 25 | Accessibility Accessibility 26 | Background Brush 27 | ContextMenuItems []MenuItem 28 | DoubleBuffering bool 29 | Enabled Property 30 | Font Font 31 | MaxSize Size 32 | MinSize Size 33 | Name string 34 | OnBoundsChanged walk.EventHandler 35 | OnKeyDown walk.KeyEventHandler 36 | OnKeyPress walk.KeyEventHandler 37 | OnKeyUp walk.KeyEventHandler 38 | OnMouseDown walk.MouseEventHandler 39 | OnMouseMove walk.MouseEventHandler 40 | OnMouseUp walk.MouseEventHandler 41 | OnSizeChanged walk.EventHandler 42 | Persistent bool 43 | RightToLeftReading bool 44 | ToolTipText Property 45 | Visible Property 46 | 47 | // Widget 48 | 49 | Alignment Alignment2D 50 | AlwaysConsumeSpace bool 51 | Column int 52 | ColumnSpan int 53 | GraphicsEffects []walk.WidgetGraphicsEffect 54 | Row int 55 | RowSpan int 56 | StretchFactor int 57 | 58 | // ToolBar 59 | 60 | Actions []*walk.Action // Deprecated, use Items instead 61 | AssignTo **walk.ToolBar 62 | ButtonStyle ToolBarButtonStyle 63 | Items []MenuItem 64 | MaxTextRows int 65 | Orientation Orientation 66 | } 67 | 68 | func (tb ToolBar) Create(builder *Builder) error { 69 | w, err := walk.NewToolBarWithOrientationAndButtonStyle(builder.Parent(), walk.Orientation(tb.Orientation), walk.ToolBarButtonStyle(tb.ButtonStyle)) 70 | if err != nil { 71 | return err 72 | } 73 | 74 | if tb.AssignTo != nil { 75 | *tb.AssignTo = w 76 | } 77 | 78 | return builder.InitWidget(tb, w, func() error { 79 | imageList, err := walk.NewImageList(walk.Size{16, 16}, 0) 80 | if err != nil { 81 | return err 82 | } 83 | w.SetImageList(imageList) 84 | 85 | mtr := tb.MaxTextRows 86 | if mtr < 1 { 87 | mtr = 1 88 | } 89 | if err := w.SetMaxTextRows(mtr); err != nil { 90 | return err 91 | } 92 | 93 | if len(tb.Items) > 0 { 94 | builder.deferBuildActions(w.Actions(), tb.Items) 95 | } else { 96 | if err := addToActionList(w.Actions(), tb.Actions); err != nil { 97 | return err 98 | } 99 | } 100 | 101 | return nil 102 | }) 103 | } 104 | -------------------------------------------------------------------------------- /declarative/toolbutton.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type ToolButton struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // Button 50 | 51 | Image Property 52 | OnClicked walk.EventHandler 53 | Text Property 54 | 55 | // ToolButton 56 | 57 | AssignTo **walk.ToolButton 58 | } 59 | 60 | func (tb ToolButton) Create(builder *Builder) error { 61 | w, err := walk.NewToolButton(builder.Parent()) 62 | if err != nil { 63 | return err 64 | } 65 | 66 | if tb.AssignTo != nil { 67 | *tb.AssignTo = w 68 | } 69 | 70 | return builder.InitWidget(tb, w, func() error { 71 | if tb.OnClicked != nil { 72 | w.Clicked().Attach(tb.OnClicked) 73 | } 74 | 75 | return nil 76 | }) 77 | } 78 | -------------------------------------------------------------------------------- /declarative/treeview.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type TreeView struct { 14 | // Window 15 | 16 | Accessibility Accessibility 17 | Background Brush 18 | ContextMenuItems []MenuItem 19 | DoubleBuffering bool 20 | Enabled Property 21 | Font Font 22 | MaxSize Size 23 | MinSize Size 24 | Name string 25 | OnBoundsChanged walk.EventHandler 26 | OnKeyDown walk.KeyEventHandler 27 | OnKeyPress walk.KeyEventHandler 28 | OnKeyUp walk.KeyEventHandler 29 | OnMouseDown walk.MouseEventHandler 30 | OnMouseMove walk.MouseEventHandler 31 | OnMouseUp walk.MouseEventHandler 32 | OnSizeChanged walk.EventHandler 33 | Persistent bool 34 | RightToLeftReading bool 35 | ToolTipText Property 36 | Visible Property 37 | 38 | // Widget 39 | 40 | Alignment Alignment2D 41 | AlwaysConsumeSpace bool 42 | Column int 43 | ColumnSpan int 44 | GraphicsEffects []walk.WidgetGraphicsEffect 45 | Row int 46 | RowSpan int 47 | StretchFactor int 48 | 49 | // TreeView 50 | 51 | AssignTo **walk.TreeView 52 | ItemHeight int 53 | Model walk.TreeModel 54 | OnCurrentItemChanged walk.EventHandler 55 | OnExpandedChanged walk.TreeItemEventHandler 56 | OnItemActivated walk.EventHandler 57 | } 58 | 59 | func (tv TreeView) Create(builder *Builder) error { 60 | w, err := walk.NewTreeView(builder.Parent()) 61 | if err != nil { 62 | return err 63 | } 64 | 65 | if tv.AssignTo != nil { 66 | *tv.AssignTo = w 67 | } 68 | 69 | return builder.InitWidget(tv, w, func() error { 70 | if tv.ItemHeight > 0 { 71 | w.SetItemHeight(w.IntFrom96DPI(tv.ItemHeight)) // VERIFY: Item height should resize on DPI change. 72 | } 73 | 74 | if err := w.SetModel(tv.Model); err != nil { 75 | return err 76 | } 77 | 78 | if tv.OnCurrentItemChanged != nil { 79 | w.CurrentItemChanged().Attach(tv.OnCurrentItemChanged) 80 | } 81 | 82 | if tv.OnExpandedChanged != nil { 83 | w.ExpandedChanged().Attach(tv.OnExpandedChanged) 84 | } 85 | 86 | if tv.OnItemActivated != nil { 87 | w.ItemActivated().Attach(tv.OnItemActivated) 88 | } 89 | 90 | return nil 91 | }) 92 | } 93 | -------------------------------------------------------------------------------- /declarative/validators.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package declarative 8 | 9 | import ( 10 | "github.com/lxn/walk" 11 | ) 12 | 13 | type ValidatorRef struct { 14 | Validator walk.Validator 15 | } 16 | 17 | func (vr ValidatorRef) Create() (walk.Validator, error) { 18 | return vr.Validator, nil 19 | } 20 | 21 | type Range struct { 22 | Min float64 23 | Max float64 24 | } 25 | 26 | func (r Range) Create() (walk.Validator, error) { 27 | return walk.NewRangeValidator(r.Min, r.Max) 28 | } 29 | 30 | type Regexp struct { 31 | Pattern string 32 | } 33 | 34 | func (re Regexp) Create() (walk.Validator, error) { 35 | return walk.NewRegexpValidator(re.Pattern) 36 | } 37 | 38 | type SelRequired struct { 39 | } 40 | 41 | func (SelRequired) Create() (walk.Validator, error) { 42 | return walk.SelectionRequiredValidator(), nil 43 | } 44 | 45 | type dMultiValidator struct { 46 | validators []Validator 47 | } 48 | 49 | func (av dMultiValidator) Create() (walk.Validator, error) { 50 | var validators []walk.Validator 51 | 52 | for _, dv := range av.validators { 53 | if wv, err := dv.Create(); err != nil { 54 | return nil, err 55 | } else { 56 | validators = append(validators, wv) 57 | } 58 | } 59 | 60 | return &wMultiValidator{validators}, nil 61 | } 62 | 63 | type wMultiValidator struct { 64 | validators []walk.Validator 65 | } 66 | 67 | func (av *wMultiValidator) Validate(v interface{}) error { 68 | for _, validator := range av.validators { 69 | if err := validator.Validate(v); err != nil { 70 | return err 71 | } 72 | } 73 | 74 | return nil 75 | } 76 | -------------------------------------------------------------------------------- /dropfilesevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "syscall" 11 | 12 | "github.com/lxn/win" 13 | ) 14 | 15 | type dropFilesEventHandlerInfo struct { 16 | handler DropFilesEventHandler 17 | once bool 18 | } 19 | 20 | type DropFilesEventHandler func([]string) 21 | 22 | type DropFilesEvent struct { 23 | hWnd win.HWND 24 | handlers []dropFilesEventHandlerInfo 25 | } 26 | 27 | func (e *DropFilesEvent) Attach(handler DropFilesEventHandler) int { 28 | if len(e.handlers) == 0 { 29 | win.DragAcceptFiles(e.hWnd, true) 30 | } 31 | 32 | handlerInfo := dropFilesEventHandlerInfo{handler, false} 33 | 34 | for i, h := range e.handlers { 35 | if h.handler == nil { 36 | e.handlers[i] = handlerInfo 37 | return i 38 | } 39 | } 40 | 41 | e.handlers = append(e.handlers, handlerInfo) 42 | 43 | return len(e.handlers) - 1 44 | } 45 | 46 | func (e *DropFilesEvent) Detach(handle int) { 47 | e.handlers[handle].handler = nil 48 | 49 | for _, h := range e.handlers { 50 | if h.handler != nil { 51 | return 52 | } 53 | } 54 | 55 | win.DragAcceptFiles(e.hWnd, false) 56 | } 57 | 58 | func (e *DropFilesEvent) Once(handler DropFilesEventHandler) { 59 | i := e.Attach(handler) 60 | e.handlers[i].once = true 61 | } 62 | 63 | type DropFilesEventPublisher struct { 64 | event DropFilesEvent 65 | } 66 | 67 | func (p *DropFilesEventPublisher) Event(hWnd win.HWND) *DropFilesEvent { 68 | p.event.hWnd = hWnd 69 | return &p.event 70 | } 71 | 72 | func (p *DropFilesEventPublisher) Publish(hDrop win.HDROP) { 73 | var files []string 74 | 75 | n := win.DragQueryFile(hDrop, 0xFFFFFFFF, nil, 0) 76 | for i := 0; i < int(n); i++ { 77 | bufSize := uint(512) 78 | buf := make([]uint16, bufSize) 79 | if win.DragQueryFile(hDrop, uint(i), &buf[0], bufSize) > 0 { 80 | files = append(files, syscall.UTF16ToString(buf)) 81 | } 82 | } 83 | win.DragFinish(hDrop) 84 | 85 | for i, h := range p.event.handlers { 86 | if h.handler != nil { 87 | h.handler(files) 88 | 89 | if h.once { 90 | p.event.Detach(i) 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /errorevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type errorEventHandlerInfo struct { 10 | handler ErrorEventHandler 11 | once bool 12 | } 13 | 14 | type ErrorEventHandler func(err error) 15 | 16 | type ErrorEvent struct { 17 | handlers []errorEventHandlerInfo 18 | } 19 | 20 | func (e *ErrorEvent) Attach(handler ErrorEventHandler) int { 21 | handlerInfo := errorEventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *ErrorEvent) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *ErrorEvent) Once(handler ErrorEventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type ErrorEventPublisher struct { 45 | event ErrorEvent 46 | } 47 | 48 | func (p *ErrorEventPublisher) Event() *ErrorEvent { 49 | return &p.event 50 | } 51 | 52 | func (p *ErrorEventPublisher) Publish(err error) { 53 | for i, h := range p.event.handlers { 54 | if h.handler != nil { 55 | h.handler(err) 56 | 57 | if h.once { 58 | p.event.Detach(i) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /event.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type eventHandlerInfo struct { 10 | handler EventHandler 11 | once bool 12 | } 13 | 14 | type EventHandler func() 15 | 16 | type Event struct { 17 | handlers []eventHandlerInfo 18 | } 19 | 20 | func (e *Event) Attach(handler EventHandler) int { 21 | handlerInfo := eventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *Event) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *Event) Once(handler EventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type EventPublisher struct { 45 | event Event 46 | } 47 | 48 | func (p *EventPublisher) Event() *Event { 49 | return &p.event 50 | } 51 | 52 | func (p *EventPublisher) Publish() { 53 | // This is a kludge to find the form that the event publisher is 54 | // affiliated with. It's only necessary because the event publisher 55 | // doesn't keep a pointer to the form on its own, and the call 56 | // to Publish isn't providing it either. 57 | if form := App().ActiveForm(); form != nil { 58 | fb := form.AsFormBase() 59 | fb.inProgressEventCount++ 60 | defer func() { 61 | fb.inProgressEventCount-- 62 | if fb.inProgressEventCount == 0 && fb.layoutScheduled { 63 | fb.layoutScheduled = false 64 | fb.startLayout() 65 | } 66 | }() 67 | } 68 | 69 | for i, h := range p.event.handlers { 70 | if h.handler != nil { 71 | h.handler() 72 | 73 | if h.once { 74 | p.event.Detach(i) 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /examples/actions/actions.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/actions/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/actions/rsrc.syso -------------------------------------------------------------------------------- /examples/clipboard/clipboard.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/clipboard/clipboard.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "log" 9 | ) 10 | 11 | import ( 12 | "github.com/lxn/walk" 13 | . "github.com/lxn/walk/declarative" 14 | ) 15 | 16 | func main() { 17 | var te *walk.TextEdit 18 | 19 | if _, err := (MainWindow{ 20 | Title: "Walk Clipboard Example", 21 | MinSize: Size{300, 200}, 22 | Layout: VBox{}, 23 | Children: []Widget{ 24 | PushButton{ 25 | Text: "Copy", 26 | OnClicked: func() { 27 | if err := walk.Clipboard().SetText(te.Text()); err != nil { 28 | log.Print("Copy: ", err) 29 | } 30 | }, 31 | }, 32 | PushButton{ 33 | Text: "Paste", 34 | OnClicked: func() { 35 | if text, err := walk.Clipboard().Text(); err != nil { 36 | log.Print("Paste: ", err) 37 | } else { 38 | te.SetText(text) 39 | } 40 | }, 41 | }, 42 | TextEdit{ 43 | AssignTo: &te, 44 | }, 45 | }, 46 | }).Run(); err != nil { 47 | log.Fatal(err) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /examples/clipboard/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/clipboard/rsrc.syso -------------------------------------------------------------------------------- /examples/databinding/databinding.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/databinding/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/databinding/rsrc.syso -------------------------------------------------------------------------------- /examples/drawing/drawing.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/drawing/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/drawing/rsrc.syso -------------------------------------------------------------------------------- /examples/dropfiles/dropfiles.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/dropfiles/dropfiles.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "strings" 9 | 10 | "github.com/lxn/walk" 11 | . "github.com/lxn/walk/declarative" 12 | ) 13 | 14 | func main() { 15 | var textEdit *walk.TextEdit 16 | MainWindow{ 17 | Title: "Walk DropFiles Example", 18 | MinSize: Size{320, 240}, 19 | Layout: VBox{}, 20 | OnDropFiles: func(files []string) { 21 | textEdit.SetText(strings.Join(files, "\r\n")) 22 | }, 23 | Children: []Widget{ 24 | TextEdit{ 25 | AssignTo: &textEdit, 26 | ReadOnly: true, 27 | Text: "Drop files here, from windows explorer...", 28 | }, 29 | }, 30 | }.Run() 31 | } 32 | -------------------------------------------------------------------------------- /examples/dropfiles/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/dropfiles/rsrc.syso -------------------------------------------------------------------------------- /examples/externalwidgets/externalwidgets.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/externalwidgets/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/externalwidgets/rsrc.syso -------------------------------------------------------------------------------- /examples/filebrowser/filebrowser.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/filebrowser/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/filebrowser/rsrc.syso -------------------------------------------------------------------------------- /examples/gradientcomposite/gradientcomposite.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/gradientcomposite/gradientcomposite.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "github.com/lxn/walk" 9 | . "github.com/lxn/walk/declarative" 10 | ) 11 | 12 | func main() { 13 | MainWindow{ 14 | Title: "Walk GradientComposite Example", 15 | MinSize: Size{400, 0}, 16 | Background: GradientBrush{ 17 | Vertexes: []walk.GradientVertex{ 18 | {X: 0, Y: 0, Color: walk.RGB(255, 255, 127)}, 19 | {X: 1, Y: 0, Color: walk.RGB(127, 191, 255)}, 20 | {X: 0.5, Y: 0.5, Color: walk.RGB(255, 255, 255)}, 21 | {X: 1, Y: 1, Color: walk.RGB(127, 255, 127)}, 22 | {X: 0, Y: 1, Color: walk.RGB(255, 127, 127)}, 23 | }, 24 | Triangles: []walk.GradientTriangle{ 25 | {0, 1, 2}, 26 | {1, 3, 2}, 27 | {3, 4, 2}, 28 | {4, 0, 2}, 29 | }, 30 | }, 31 | Layout: HBox{Margins: Margins{100, 100, 100, 100}}, 32 | Children: []Widget{ 33 | GradientComposite{ 34 | Border: true, 35 | Vertical: Bind("verticalCB.Checked"), 36 | Color1: Bind("rgb(c1RedSld.Value, c1GreenSld.Value, c1BlueSld.Value)"), 37 | Color2: Bind("rgb(c2RedSld.Value, c2GreenSld.Value, c2BlueSld.Value)"), 38 | Layout: HBox{}, 39 | Children: []Widget{ 40 | GroupBox{ 41 | Title: "Gradient Parameters", 42 | Layout: VBox{}, 43 | Children: []Widget{ 44 | CheckBox{Name: "verticalCB", Text: "Vertical", Checked: true}, 45 | GroupBox{ 46 | Title: "Color1", 47 | Layout: Grid{Columns: 2}, 48 | Children: []Widget{ 49 | Label{Text: "Red:"}, 50 | Slider{Name: "c1RedSld", Tracking: true, MaxValue: 255, Value: 95}, 51 | Label{Text: "Green:"}, 52 | Slider{Name: "c1GreenSld", Tracking: true, MaxValue: 255, Value: 191}, 53 | Label{Text: "Blue:"}, 54 | Slider{Name: "c1BlueSld", Tracking: true, MaxValue: 255, Value: 255}, 55 | }, 56 | }, 57 | GroupBox{ 58 | Title: "Color2", 59 | Layout: Grid{Columns: 2}, 60 | Children: []Widget{ 61 | Label{Text: "Red:"}, 62 | Slider{Name: "c2RedSld", Tracking: true, MaxValue: 255, Value: 239}, 63 | Label{Text: "Green:"}, 64 | Slider{Name: "c2GreenSld", Tracking: true, MaxValue: 255, Value: 63}, 65 | Label{Text: "Blue:"}, 66 | Slider{Name: "c2BlueSld", Tracking: true, MaxValue: 255, Value: 0}, 67 | }, 68 | }, 69 | }, 70 | }, 71 | }, 72 | }, 73 | }, 74 | Functions: map[string]func(args ...interface{}) (interface{}, error){ 75 | "rgb": func(args ...interface{}) (interface{}, error) { 76 | return walk.RGB(byte(args[0].(float64)), byte(args[1].(float64)), byte(args[2].(float64))), nil 77 | }, 78 | }, 79 | }.Run() 80 | } 81 | -------------------------------------------------------------------------------- /examples/gradientcomposite/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/gradientcomposite/rsrc.syso -------------------------------------------------------------------------------- /examples/imageicon/imageicon.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/imageicon/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "image" 9 | "image/color" 10 | "image/draw" 11 | "log" 12 | ) 13 | 14 | import ( 15 | "github.com/lxn/walk" 16 | . "github.com/lxn/walk/declarative" 17 | ) 18 | 19 | func main() { 20 | var mw *walk.MainWindow 21 | var windowIcon *walk.Icon 22 | counter := 0 23 | 24 | if _, err := (MainWindow{ 25 | AssignTo: &mw, 26 | Title: "Walk Image Icon Example", 27 | Layout: HBox{}, 28 | Children: []Widget{ 29 | HSpacer{}, 30 | PushButton{ 31 | Text: "Push me", 32 | OnClicked: func() { 33 | ic, err := walk.NewIconFromImage(makeDigitImage(counter)) 34 | if err != nil { 35 | return 36 | } 37 | counter++ 38 | mw.SetIcon(ic) 39 | if windowIcon != nil { 40 | windowIcon.Dispose() 41 | } 42 | windowIcon = ic 43 | }, 44 | }, 45 | HSpacer{}, 46 | }, 47 | }.Run()); err != nil { 48 | log.Fatal(err) 49 | } 50 | } 51 | 52 | // A 53 | // F B 54 | // G 55 | // E C 56 | // D 57 | var hexdigits = []int{0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71} 58 | 59 | //0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47 60 | 61 | type seg struct { 62 | sx, sy int 63 | dx, dy int 64 | } 65 | 66 | var segments = []seg{ 67 | {0, 0, 1, 0}, 68 | {1, 0, 0, 1}, 69 | {1, 1, 0, 1}, 70 | {0, 2, 1, 0}, 71 | {0, 1, 0, 1}, 72 | {0, 0, 0, 1}, 73 | {0, 1, 1, 0}, 74 | } 75 | 76 | func digit(im draw.Image, col color.Color, x, y, size, digit int) { 77 | n := hexdigits[digit] 78 | for _, s := range segments { 79 | if n&1 != 0 { 80 | xx, yy := x+s.sx*size, y+s.sy*size 81 | for i := 0; i <= size; i++ { 82 | im.Set(xx, yy, col) 83 | xx += s.dx 84 | yy += s.dy 85 | } 86 | } 87 | n >>= 1 88 | } 89 | } 90 | 91 | func makeDigitImage(n int) image.Image { 92 | im := image.NewRGBA(image.Rect(0, 0, 16, 16)) 93 | for p := 11; p >= 0; p -= 5 { 94 | digit(im, color.Black, p, 5, 3, n%10) 95 | n /= 10 96 | } 97 | return im 98 | } 99 | -------------------------------------------------------------------------------- /examples/imageicon/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/imageicon/rsrc.syso -------------------------------------------------------------------------------- /examples/imageview/imageview.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/imageview/imageview.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "github.com/lxn/walk" 9 | . "github.com/lxn/walk/declarative" 10 | ) 11 | 12 | func main() { 13 | walk.Resources.SetRootDirPath("../img") 14 | 15 | type Mode struct { 16 | Name string 17 | Value ImageViewMode 18 | } 19 | 20 | modes := []Mode{ 21 | {"ImageViewModeIdeal", ImageViewModeIdeal}, 22 | {"ImageViewModeCorner", ImageViewModeCorner}, 23 | {"ImageViewModeCenter", ImageViewModeCenter}, 24 | {"ImageViewModeShrink", ImageViewModeShrink}, 25 | {"ImageViewModeZoom", ImageViewModeZoom}, 26 | {"ImageViewModeStretch", ImageViewModeStretch}, 27 | } 28 | 29 | var widgets []Widget 30 | 31 | for _, mode := range modes { 32 | widgets = append(widgets, 33 | Label{ 34 | Text: mode.Name, 35 | }, 36 | ImageView{ 37 | Background: SolidColorBrush{Color: walk.RGB(255, 191, 0)}, 38 | Image: "open.png", 39 | Margin: 10, 40 | Mode: mode.Value, 41 | }, 42 | ) 43 | } 44 | 45 | MainWindow{ 46 | Title: "Walk ImageView Example", 47 | Size: Size{400, 600}, 48 | Layout: Grid{Columns: 2}, 49 | Children: widgets, 50 | }.Run() 51 | } 52 | -------------------------------------------------------------------------------- /examples/imageview/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/imageview/rsrc.syso -------------------------------------------------------------------------------- /examples/imageviewer/imageviewer.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/imageviewer/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/imageviewer/rsrc.syso -------------------------------------------------------------------------------- /examples/img/README: -------------------------------------------------------------------------------- 1 | Most image files in this directory are from the base icon theme of the 2 | Tango Desktop Project at http://tango.freedesktop.org. 3 | 4 | Thanks for releasing those to the Public Domain. 5 | -------------------------------------------------------------------------------- /examples/img/check.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/img/check.ico -------------------------------------------------------------------------------- /examples/img/document-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/img/document-new.png -------------------------------------------------------------------------------- /examples/img/document-properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/img/document-properties.png -------------------------------------------------------------------------------- /examples/img/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/img/open.png -------------------------------------------------------------------------------- /examples/img/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/img/plus.png -------------------------------------------------------------------------------- /examples/img/stop.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/img/stop.ico -------------------------------------------------------------------------------- /examples/img/system-shutdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/img/system-shutdown.png -------------------------------------------------------------------------------- /examples/linklabel/linklabel.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/linklabel/linklabel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "log" 9 | ) 10 | 11 | import ( 12 | "github.com/lxn/walk" 13 | . "github.com/lxn/walk/declarative" 14 | ) 15 | 16 | func main() { 17 | if _, err := (MainWindow{ 18 | Title: "Walk LinkLabel Example", 19 | MinSize: Size{300, 200}, 20 | Layout: VBox{}, 21 | Children: []Widget{ 22 | LinkLabel{ 23 | MaxSize: Size{100, 0}, 24 | Text: `I can contain multiple links like this or that one.`, 25 | OnLinkActivated: func(link *walk.LinkLabelLink) { 26 | log.Printf("id: '%s', url: '%s'\n", link.Id(), link.URL()) 27 | }, 28 | }, 29 | }, 30 | }).Run(); err != nil { 31 | log.Fatal(err) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/linklabel/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/linklabel/rsrc.syso -------------------------------------------------------------------------------- /examples/listbox/listbox.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/listbox/listbox.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "fmt" 9 | "log" 10 | "os" 11 | "strings" 12 | ) 13 | 14 | import ( 15 | "github.com/lxn/walk" 16 | . "github.com/lxn/walk/declarative" 17 | ) 18 | 19 | func main() { 20 | mw := &MyMainWindow{model: NewEnvModel()} 21 | 22 | if _, err := (MainWindow{ 23 | AssignTo: &mw.MainWindow, 24 | Title: "Walk ListBox Example", 25 | MinSize: Size{240, 320}, 26 | Size: Size{300, 400}, 27 | Layout: VBox{MarginsZero: true}, 28 | Children: []Widget{ 29 | HSplitter{ 30 | Children: []Widget{ 31 | ListBox{ 32 | AssignTo: &mw.lb, 33 | Model: mw.model, 34 | OnCurrentIndexChanged: mw.lb_CurrentIndexChanged, 35 | OnItemActivated: mw.lb_ItemActivated, 36 | }, 37 | TextEdit{ 38 | AssignTo: &mw.te, 39 | ReadOnly: true, 40 | }, 41 | }, 42 | }, 43 | }, 44 | }.Run()); err != nil { 45 | log.Fatal(err) 46 | } 47 | } 48 | 49 | type MyMainWindow struct { 50 | *walk.MainWindow 51 | model *EnvModel 52 | lb *walk.ListBox 53 | te *walk.TextEdit 54 | } 55 | 56 | func (mw *MyMainWindow) lb_CurrentIndexChanged() { 57 | i := mw.lb.CurrentIndex() 58 | item := &mw.model.items[i] 59 | 60 | mw.te.SetText(item.value) 61 | 62 | fmt.Println("CurrentIndex: ", i) 63 | fmt.Println("CurrentEnvVarName: ", item.name) 64 | } 65 | 66 | func (mw *MyMainWindow) lb_ItemActivated() { 67 | value := mw.model.items[mw.lb.CurrentIndex()].value 68 | 69 | walk.MsgBox(mw, "Value", value, walk.MsgBoxIconInformation) 70 | } 71 | 72 | type EnvItem struct { 73 | name string 74 | value string 75 | } 76 | 77 | type EnvModel struct { 78 | walk.ListModelBase 79 | items []EnvItem 80 | } 81 | 82 | func NewEnvModel() *EnvModel { 83 | env := os.Environ() 84 | 85 | m := &EnvModel{items: make([]EnvItem, len(env))} 86 | 87 | for i, e := range env { 88 | j := strings.Index(e, "=") 89 | if j == 0 { 90 | continue 91 | } 92 | 93 | name := e[0:j] 94 | value := strings.Replace(e[j+1:], ";", "\r\n", -1) 95 | 96 | m.items[i] = EnvItem{name, value} 97 | } 98 | 99 | return m 100 | } 101 | 102 | func (m *EnvModel) ItemCount() int { 103 | return len(m.items) 104 | } 105 | 106 | func (m *EnvModel) Value(index int) interface{} { 107 | return m.items[index].name 108 | } 109 | -------------------------------------------------------------------------------- /examples/listbox/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/listbox/rsrc.syso -------------------------------------------------------------------------------- /examples/listbox_ownerdrawing/listbox_ownerdrawing.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/listbox_ownerdrawing/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/listbox_ownerdrawing/rsrc.syso -------------------------------------------------------------------------------- /examples/logview/logview.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/logview/logview.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | package main 5 | 6 | import ( 7 | "errors" 8 | "syscall" 9 | "unsafe" 10 | ) 11 | 12 | import ( 13 | "github.com/lxn/walk" 14 | "github.com/lxn/win" 15 | ) 16 | 17 | type LogView struct { 18 | walk.WidgetBase 19 | logChan chan string 20 | } 21 | 22 | const ( 23 | TEM_APPENDTEXT = win.WM_USER + 6 24 | ) 25 | 26 | func NewLogView(parent walk.Container) (*LogView, error) { 27 | lc := make(chan string, 1024) 28 | lv := &LogView{logChan: lc} 29 | 30 | if err := walk.InitWidget( 31 | lv, 32 | parent, 33 | "EDIT", 34 | win.WS_TABSTOP|win.WS_VISIBLE|win.WS_VSCROLL|win.ES_MULTILINE|win.ES_WANTRETURN, 35 | win.WS_EX_CLIENTEDGE); err != nil { 36 | return nil, err 37 | } 38 | lv.setReadOnly(true) 39 | lv.SendMessage(win.EM_SETLIMITTEXT, 4294967295, 0) 40 | return lv, nil 41 | } 42 | 43 | func (*LogView) CreateLayoutItem(ctx *walk.LayoutContext) walk.LayoutItem { 44 | return walk.NewGreedyLayoutItem() 45 | } 46 | 47 | func (lv *LogView) setTextSelection(start, end int) { 48 | lv.SendMessage(win.EM_SETSEL, uintptr(start), uintptr(end)) 49 | } 50 | 51 | func (lv *LogView) textLength() int { 52 | return int(lv.SendMessage(0x000E, uintptr(0), uintptr(0))) 53 | } 54 | 55 | func (lv *LogView) AppendText(value string) { 56 | textLength := lv.textLength() 57 | lv.setTextSelection(textLength, textLength) 58 | lv.SendMessage(win.EM_REPLACESEL, 0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value)))) 59 | } 60 | 61 | func (lv *LogView) setReadOnly(readOnly bool) error { 62 | if 0 == lv.SendMessage(win.EM_SETREADONLY, uintptr(win.BoolToBOOL(readOnly)), 0) { 63 | return errors.New("fail to call EM_SETREADONLY") 64 | } 65 | 66 | return nil 67 | } 68 | 69 | func (lv *LogView) PostAppendText(value string) { 70 | lv.logChan <- value 71 | win.PostMessage(lv.Handle(), TEM_APPENDTEXT, 0, 0) 72 | } 73 | 74 | func (lv *LogView) Write(p []byte) (int, error) { 75 | lv.PostAppendText(string(p) + "\r\n") 76 | return len(p), nil 77 | } 78 | 79 | func (lv *LogView) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr { 80 | switch msg { 81 | case win.WM_GETDLGCODE: 82 | if wParam == win.VK_RETURN { 83 | return win.DLGC_WANTALLKEYS 84 | } 85 | 86 | return win.DLGC_HASSETSEL | win.DLGC_WANTARROWS | win.DLGC_WANTCHARS 87 | case TEM_APPENDTEXT: 88 | select { 89 | case value := <-lv.logChan: 90 | lv.AppendText(value) 91 | default: 92 | return 0 93 | } 94 | } 95 | 96 | return lv.WidgetBase.WndProc(hwnd, msg, wParam, lParam) 97 | } 98 | -------------------------------------------------------------------------------- /examples/logview/logviewapp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "log" 9 | "time" 10 | ) 11 | 12 | import ( 13 | "github.com/lxn/walk" 14 | . "github.com/lxn/walk/declarative" 15 | ) 16 | 17 | func main() { 18 | var mw *walk.MainWindow 19 | 20 | if err := (MainWindow{ 21 | AssignTo: &mw, 22 | Title: "Walk LogView Example", 23 | MinSize: Size{320, 240}, 24 | Size: Size{400, 600}, 25 | Layout: VBox{MarginsZero: true}, 26 | }.Create()); err != nil { 27 | log.Fatal(err) 28 | } 29 | 30 | lv, err := NewLogView(mw) 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | 35 | lv.PostAppendText("XXX") 36 | log.SetOutput(lv) 37 | 38 | go func() { 39 | for i := 0; i < 10000; i++ { 40 | time.Sleep(100 * time.Millisecond) 41 | log.Println("Text" + "\r\n") 42 | } 43 | }() 44 | 45 | mw.Run() 46 | } 47 | -------------------------------------------------------------------------------- /examples/logview/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/logview/rsrc.syso -------------------------------------------------------------------------------- /examples/multiplepages/multiplepages.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/multiplepages/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/multiplepages/rsrc.syso -------------------------------------------------------------------------------- /examples/notifyicon/notifyicon.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/notifyicon/notifyicon.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "log" 9 | ) 10 | 11 | import ( 12 | "github.com/lxn/walk" 13 | ) 14 | 15 | func main() { 16 | // We need either a walk.MainWindow or a walk.Dialog for their message loop. 17 | // We will not make it visible in this example, though. 18 | mw, err := walk.NewMainWindow() 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | 23 | // We load our icon from a file. 24 | icon, err := walk.Resources.Icon("../img/stop.ico") 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | 29 | // Create the notify icon and make sure we clean it up on exit. 30 | ni, err := walk.NewNotifyIcon(mw) 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | defer ni.Dispose() 35 | 36 | // Set the icon and a tool tip text. 37 | if err := ni.SetIcon(icon); err != nil { 38 | log.Fatal(err) 39 | } 40 | if err := ni.SetToolTip("Click for info or use the context menu to exit."); err != nil { 41 | log.Fatal(err) 42 | } 43 | 44 | // When the left mouse button is pressed, bring up our balloon. 45 | ni.MouseDown().Attach(func(x, y int, button walk.MouseButton) { 46 | if button != walk.LeftButton { 47 | return 48 | } 49 | 50 | if err := ni.ShowCustom( 51 | "Walk NotifyIcon Example", 52 | "There are multiple ShowX methods sporting different icons.", 53 | icon); err != nil { 54 | 55 | log.Fatal(err) 56 | } 57 | }) 58 | 59 | // We put an exit action into the context menu. 60 | exitAction := walk.NewAction() 61 | if err := exitAction.SetText("E&xit"); err != nil { 62 | log.Fatal(err) 63 | } 64 | exitAction.Triggered().Attach(func() { walk.App().Exit(0) }) 65 | if err := ni.ContextMenu().Actions().Add(exitAction); err != nil { 66 | log.Fatal(err) 67 | } 68 | 69 | // The notify icon is hidden initially, so we have to make it visible. 70 | if err := ni.SetVisible(true); err != nil { 71 | log.Fatal(err) 72 | } 73 | 74 | // Now that the icon is visible, we can bring up an info balloon. 75 | if err := ni.ShowInfo("Walk NotifyIcon Example", "Click the icon to show again."); err != nil { 76 | log.Fatal(err) 77 | } 78 | 79 | // Run the message loop. 80 | mw.Run() 81 | } 82 | -------------------------------------------------------------------------------- /examples/notifyicon/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/notifyicon/rsrc.syso -------------------------------------------------------------------------------- /examples/progressindicator/pi.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "fmt" 9 | "log" 10 | "time" 11 | ) 12 | 13 | import ( 14 | "github.com/lxn/walk" 15 | ) 16 | 17 | func main() { 18 | if _, err := RunMyDialog(nil); err != nil { 19 | log.Fatal(err) 20 | } 21 | } 22 | 23 | type MyDialog struct { 24 | *walk.Dialog 25 | ui myDialogUI 26 | } 27 | 28 | func (dlg *MyDialog) setState(state walk.PIState) { 29 | if err := dlg.ProgressIndicator().SetState(state); err != nil { 30 | log.Print(err) 31 | } 32 | } 33 | 34 | func RunMyDialog(owner walk.Form) (int, error) { 35 | dlg := new(MyDialog) 36 | if err := dlg.init(owner); err != nil { 37 | return 0, err 38 | } 39 | 40 | dlg.ui.indeterminateBtn.Clicked().Attach(func() { 41 | fmt.Println("SetState indeterminate") 42 | dlg.setState(walk.PIIndeterminate) 43 | }) 44 | dlg.ui.noProgressBtn.Clicked().Attach(func() { 45 | fmt.Println("SetState noprogress") 46 | dlg.setState(walk.PINoProgress) 47 | }) 48 | 49 | dlg.ui.normalBtn.Clicked().Attach(func() { 50 | fmt.Println("SetState normal") 51 | dlg.setState(walk.PINormal) 52 | }) 53 | 54 | dlg.ui.errBtn.Clicked().Attach(func() { 55 | fmt.Println("SetState error") 56 | dlg.setState(walk.PIError) 57 | }) 58 | 59 | dlg.ui.pausedBtn.Clicked().Attach(func() { 60 | fmt.Println("SetState paused") 61 | dlg.setState(walk.PIPaused) 62 | }) 63 | 64 | dlg.ui.startBtn.Clicked().Attach(func() { 65 | go func() { 66 | dlg.ProgressIndicator().SetTotal(100) 67 | var i uint32 68 | for i = 0; i < 100; i++ { 69 | fmt.Println("SetProgress", i) 70 | time.Sleep(100 * time.Millisecond) 71 | if err := dlg.ProgressIndicator().SetCompleted(i); err != nil { 72 | log.Print(err) 73 | } 74 | } 75 | }() 76 | }) 77 | 78 | return dlg.Run(), nil 79 | } 80 | -------------------------------------------------------------------------------- /examples/progressindicator/progressindicator.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/progressindicator/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/progressindicator/rsrc.syso -------------------------------------------------------------------------------- /examples/radiobutton/radiobutton.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/radiobutton/radiobutton.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "fmt" 9 | ) 10 | 11 | import ( 12 | . "github.com/lxn/walk/declarative" 13 | ) 14 | 15 | type Foo struct { 16 | Bar string 17 | Baz int 18 | } 19 | 20 | func main() { 21 | foo := &Foo{"b", 0} 22 | 23 | MainWindow{ 24 | Title: "Walk RadioButton Example", 25 | MinSize: Size{320, 240}, 26 | Layout: VBox{}, 27 | DataBinder: DataBinder{ 28 | DataSource: foo, 29 | AutoSubmit: true, 30 | OnSubmitted: func() { 31 | fmt.Println(foo) 32 | }, 33 | }, 34 | Children: []Widget{ 35 | // RadioButtonGroup is needed for data binding only. 36 | RadioButtonGroup{ 37 | DataMember: "Bar", 38 | Buttons: []RadioButton{ 39 | RadioButton{ 40 | Name: "aRB", 41 | Text: "A", 42 | Value: "a", 43 | }, 44 | RadioButton{ 45 | Name: "bRB", 46 | Text: "B", 47 | Value: "b", 48 | }, 49 | RadioButton{ 50 | Name: "cRB", 51 | Text: "C", 52 | Value: "c", 53 | }, 54 | }, 55 | }, 56 | Label{ 57 | Text: "A", 58 | Enabled: Bind("aRB.Checked"), 59 | }, 60 | Label{ 61 | Text: "B", 62 | Enabled: Bind("bRB.Checked"), 63 | }, 64 | Label{ 65 | Text: "C", 66 | Enabled: Bind("cRB.Checked"), 67 | }, 68 | RadioButtonGroup{ 69 | DataMember: "Baz", 70 | Buttons: []RadioButton{ 71 | RadioButton{ 72 | Name: "oneRB", 73 | Text: "1", 74 | Value: 1, 75 | }, 76 | RadioButton{ 77 | Name: "twoRB", 78 | Text: "2", 79 | Value: 2, 80 | }, 81 | RadioButton{ 82 | Name: "threeRB", 83 | Text: "3", 84 | Value: 3, 85 | }, 86 | }, 87 | }, 88 | Label{ 89 | Text: "1", 90 | Enabled: Bind("oneRB.Checked"), 91 | }, 92 | Label{ 93 | Text: "2", 94 | Enabled: Bind("twoRB.Checked"), 95 | }, 96 | Label{ 97 | Text: "3", 98 | Enabled: Bind("threeRB.Checked"), 99 | }, 100 | }, 101 | }.Run() 102 | } 103 | -------------------------------------------------------------------------------- /examples/radiobutton/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/radiobutton/rsrc.syso -------------------------------------------------------------------------------- /examples/settings/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/settings/rsrc.syso -------------------------------------------------------------------------------- /examples/settings/settings.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/settings/settings.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "log" 9 | "math/rand" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | import ( 15 | "github.com/lxn/walk" 16 | . "github.com/lxn/walk/declarative" 17 | ) 18 | 19 | func main() { 20 | app := walk.App() 21 | 22 | // These specify the app data sub directory for the settings file. 23 | app.SetOrganizationName("The Walk Authors") 24 | app.SetProductName("Walk Settings Example") 25 | 26 | // Settings file name. 27 | settings := walk.NewIniFileSettings("settings.ini") 28 | 29 | // All settings marked as expiring will expire after this duration w/o use. 30 | // This applies to all widgets settings. 31 | settings.SetExpireDuration(time.Hour * 24 * 30 * 3) 32 | 33 | if err := settings.Load(); err != nil { 34 | log.Fatal(err) 35 | } 36 | 37 | app.SetSettings(settings) 38 | 39 | if err := RunMainWindow(); err != nil { 40 | log.Fatal(err) 41 | } 42 | 43 | if err := settings.Save(); err != nil { 44 | log.Fatal(err) 45 | } 46 | } 47 | 48 | func RunMainWindow() error { 49 | if _, err := (MainWindow{ 50 | Name: "mainWindow", // Name is needed for settings persistence 51 | Title: "Walk Settings Example", 52 | MinSize: Size{800, 600}, 53 | Layout: VBox{MarginsZero: true}, 54 | Children: []Widget{ 55 | TableView{ 56 | Name: "tableView", // Name is needed for settings persistence 57 | AlternatingRowBG: true, 58 | ColumnsOrderable: true, 59 | Columns: []TableViewColumn{ 60 | // Name is needed for settings persistence 61 | {Name: "#", DataMember: "Index"}, // Use DataMember, if names differ 62 | {Name: "Bar"}, 63 | {Name: "Baz", Format: "%.2f", Alignment: AlignFar}, 64 | {Name: "Quux", Format: "2006-01-02 15:04:05", Width: 150}, 65 | }, 66 | Model: NewFooModel(), 67 | }}, 68 | }.Run()); err != nil { 69 | return err 70 | } 71 | 72 | return nil 73 | } 74 | 75 | func NewFooModel() *FooModel { 76 | now := time.Now() 77 | 78 | rand.Seed(now.UnixNano()) 79 | 80 | m := &FooModel{items: make([]*Foo, 1000)} 81 | 82 | for i := range m.items { 83 | m.items[i] = &Foo{ 84 | Index: i, 85 | Bar: strings.Repeat("*", rand.Intn(5)+1), 86 | Baz: rand.Float64() * 1000, 87 | Quux: time.Unix(rand.Int63n(now.Unix()), 0), 88 | } 89 | } 90 | 91 | return m 92 | } 93 | 94 | type FooModel struct { 95 | walk.SortedReflectTableModelBase 96 | items []*Foo 97 | } 98 | 99 | func (m *FooModel) Items() interface{} { 100 | return m.items 101 | } 102 | 103 | type Foo struct { 104 | Index int 105 | Bar string 106 | Baz float64 107 | Quux time.Time 108 | } 109 | -------------------------------------------------------------------------------- /examples/slider/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/slider/rsrc.syso -------------------------------------------------------------------------------- /examples/slider/slider.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/slider/slider.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "log" 9 | 10 | "github.com/lxn/walk" 11 | . "github.com/lxn/walk/declarative" 12 | ) 13 | 14 | func main() { 15 | var slv, slh *walk.Slider 16 | var maxEdit, minEdit, valueEdit *walk.NumberEdit 17 | 18 | data := struct{ Min, Max, Value int }{0, 100, 30} 19 | 20 | MainWindow{ 21 | Title: "Walk Slider Example", 22 | MinSize: Size{320, 240}, 23 | Layout: HBox{}, 24 | Children: []Widget{ 25 | Slider{ 26 | AssignTo: &slv, 27 | MinValue: data.Min, 28 | MaxValue: data.Max, 29 | Value: data.Value, 30 | Orientation: Vertical, 31 | OnValueChanged: func() { 32 | data.Value = slv.Value() 33 | valueEdit.SetValue(float64(data.Value)) 34 | 35 | }, 36 | }, 37 | Composite{ 38 | Layout: Grid{Columns: 3}, 39 | StretchFactor: 4, 40 | Children: []Widget{ 41 | Label{Text: "Min value"}, 42 | Label{Text: "Value"}, 43 | Label{Text: "Max value"}, 44 | NumberEdit{ 45 | AssignTo: &minEdit, 46 | Value: float64(data.Min), 47 | OnValueChanged: func() { 48 | data.Min = int(minEdit.Value()) 49 | slh.SetRange(data.Min, data.Max) 50 | slv.SetRange(data.Min, data.Max) 51 | }, 52 | }, 53 | NumberEdit{ 54 | AssignTo: &valueEdit, 55 | Value: float64(data.Value), 56 | OnValueChanged: func() { 57 | data.Value = int(valueEdit.Value()) 58 | slh.SetValue(data.Value) 59 | slv.SetValue(data.Value) 60 | }, 61 | }, 62 | NumberEdit{ 63 | AssignTo: &maxEdit, 64 | Value: float64(data.Max), 65 | OnValueChanged: func() { 66 | data.Max = int(maxEdit.Value()) 67 | slh.SetRange(data.Min, data.Max) 68 | slv.SetRange(data.Min, data.Max) 69 | }, 70 | }, 71 | Slider{ 72 | ColumnSpan: 3, 73 | AssignTo: &slh, 74 | MinValue: data.Min, 75 | MaxValue: data.Max, 76 | Value: data.Value, 77 | OnValueChanged: func() { 78 | data.Value = slh.Value() 79 | valueEdit.SetValue(float64(data.Value)) 80 | }, 81 | }, 82 | VSpacer{}, 83 | PushButton{ 84 | ColumnSpan: 3, 85 | Text: "Print state", 86 | OnClicked: func() { 87 | log.Printf("H: < %d | %d | %d >\n", slh.MinValue(), slh.Value(), slh.MaxValue()) 88 | log.Printf("V: < %d | %d | %d >\n", slv.MinValue(), slv.Value(), slv.MaxValue()) 89 | }, 90 | }, 91 | }, 92 | }, 93 | }, 94 | }.Run() 95 | } 96 | -------------------------------------------------------------------------------- /examples/statusbar/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/statusbar/rsrc.syso -------------------------------------------------------------------------------- /examples/statusbar/statusbar.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/statusbar/statusbar.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This example demonstrates the status bar, including a size gripper 6 | // attached to the bottom of the main window. 7 | // The status bar has two items, one is dynamically updated and one includes an icon. 8 | package main 9 | 10 | import ( 11 | "log" 12 | 13 | "github.com/lxn/walk" 14 | . "github.com/lxn/walk/declarative" 15 | ) 16 | 17 | func main() { 18 | icon1, err := walk.NewIconFromFile("../img/check.ico") 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | icon2, err := walk.NewIconFromFile("../img/stop.ico") 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | 27 | var sbi *walk.StatusBarItem 28 | 29 | MainWindow{ 30 | Title: "Walk Statusbar Example", 31 | MinSize: Size{600, 200}, 32 | Layout: VBox{MarginsZero: true}, 33 | StatusBarItems: []StatusBarItem{ 34 | StatusBarItem{ 35 | AssignTo: &sbi, 36 | Icon: icon1, 37 | Text: "click", 38 | Width: 80, 39 | OnClicked: func() { 40 | if sbi.Text() == "click" { 41 | sbi.SetText("again") 42 | sbi.SetIcon(icon2) 43 | } else { 44 | sbi.SetText("click") 45 | sbi.SetIcon(icon1) 46 | } 47 | }, 48 | }, 49 | StatusBarItem{ 50 | Text: "left", 51 | ToolTipText: "no tooltip for me", 52 | }, 53 | StatusBarItem{ 54 | Text: "\tcenter", 55 | }, 56 | StatusBarItem{ 57 | Text: "\t\tright", 58 | }, 59 | StatusBarItem{ 60 | Icon: icon1, 61 | ToolTipText: "An icon with a tooltip", 62 | }, 63 | }, 64 | }.Run() 65 | } 66 | -------------------------------------------------------------------------------- /examples/tableview/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/tableview/rsrc.syso -------------------------------------------------------------------------------- /examples/tableview/tableview.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/webview/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/webview/rsrc.syso -------------------------------------------------------------------------------- /examples/webview/webview.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/webview/webview.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "strings" 9 | 10 | "github.com/lxn/walk" 11 | . "github.com/lxn/walk/declarative" 12 | ) 13 | 14 | func main() { 15 | var le *walk.LineEdit 16 | var wv *walk.WebView 17 | 18 | MainWindow{ 19 | Icon: Bind("'../img/' + icon(wv.URL) + '.ico'"), 20 | Title: "Walk WebView Example'", 21 | MinSize: Size{800, 600}, 22 | Layout: VBox{MarginsZero: true}, 23 | Children: []Widget{ 24 | LineEdit{ 25 | AssignTo: &le, 26 | Text: Bind("wv.URL"), 27 | OnKeyDown: func(key walk.Key) { 28 | if key == walk.KeyReturn { 29 | wv.SetURL(le.Text()) 30 | } 31 | }, 32 | }, 33 | WebView{ 34 | AssignTo: &wv, 35 | Name: "wv", 36 | URL: "https://github.com/lxn/walk", 37 | }, 38 | }, 39 | Functions: map[string]func(args ...interface{}) (interface{}, error){ 40 | "icon": func(args ...interface{}) (interface{}, error) { 41 | if strings.HasPrefix(args[0].(string), "https") { 42 | return "check", nil 43 | } 44 | 45 | return "stop", nil 46 | }, 47 | }, 48 | }.Run() 49 | } 50 | -------------------------------------------------------------------------------- /examples/webview_events/rsrc.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lxn/walk/c389da54e794a411ec9c9bfda01f2a0eb1b5a9b4/examples/webview_events/rsrc.syso -------------------------------------------------------------------------------- /examples/webview_events/webview_events.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /expression.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "log" 11 | "reflect" 12 | ) 13 | 14 | import _ "gopkg.in/Knetic/govaluate.v3" 15 | 16 | type Expression interface { 17 | Value() interface{} 18 | Changed() *Event 19 | } 20 | 21 | type reflectExpression struct { 22 | root Expression 23 | path string 24 | } 25 | 26 | func NewReflectExpression(root Expression, path string) Expression { 27 | return &reflectExpression{root: root, path: path} 28 | } 29 | 30 | func (re *reflectExpression) Value() interface{} { 31 | rootVal := re.root.Value() 32 | if rootVal == nil { 33 | return nil 34 | } 35 | 36 | _, val, err := reflectValueFromPath(reflect.ValueOf(rootVal), re.path) 37 | if err != nil { 38 | log.Print("walk - reflectExpression.Value - Error: ", err.Error()) 39 | } 40 | 41 | if !val.IsValid() { 42 | return nil 43 | } 44 | 45 | return val.Interface() 46 | } 47 | 48 | func (re *reflectExpression) Changed() *Event { 49 | return re.root.Changed() 50 | } 51 | -------------------------------------------------------------------------------- /fontresource.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | "syscall" 12 | ) 13 | 14 | // FontMemResource represents a font resource loaded into memory from 15 | // the application's resources. 16 | type FontMemResource struct { 17 | hFontResource win.HANDLE 18 | } 19 | 20 | func newFontMemResource(resourceName *uint16) (*FontMemResource, error) { 21 | hModule := win.HMODULE(win.GetModuleHandle(nil)) 22 | if hModule == win.HMODULE(0) { 23 | return nil, lastError("GetModuleHandle") 24 | } 25 | 26 | hres := win.FindResource(hModule, resourceName, win.MAKEINTRESOURCE(8) /*RT_FONT*/) 27 | if hres == win.HRSRC(0) { 28 | return nil, lastError("FindResource") 29 | } 30 | 31 | size := win.SizeofResource(hModule, hres) 32 | if size == 0 { 33 | return nil, lastError("SizeofResource") 34 | } 35 | 36 | hResLoad := win.LoadResource(hModule, hres) 37 | if hResLoad == win.HGLOBAL(0) { 38 | return nil, lastError("LoadResource") 39 | } 40 | 41 | ptr := win.LockResource(hResLoad) 42 | if ptr == 0 { 43 | return nil, lastError("LockResource") 44 | } 45 | 46 | numFonts := uint32(0) 47 | hFontResource := win.AddFontMemResourceEx(ptr, size, nil, &numFonts) 48 | 49 | if hFontResource == win.HANDLE(0) || numFonts == 0 { 50 | return nil, lastError("AddFontMemResource") 51 | } 52 | 53 | return &FontMemResource{hFontResource: hFontResource}, nil 54 | } 55 | 56 | // NewFontMemResourceByName function loads a font resource from the executable's resources 57 | // using the resource name. 58 | // The font must be embedded into resources using corresponding operator in the 59 | // application's RC script. 60 | func NewFontMemResourceByName(name string) (*FontMemResource, error) { 61 | lpstr, err := syscall.UTF16PtrFromString(name) 62 | if err != nil { 63 | return nil, err 64 | } 65 | 66 | return newFontMemResource(lpstr) 67 | } 68 | 69 | // NewFontMemResourceById function loads a font resource from the executable's resources 70 | // using the resource ID. 71 | // The font must be embedded into resources using corresponding operator in the 72 | // application's RC script. 73 | func NewFontMemResourceById(id int) (*FontMemResource, error) { 74 | return newFontMemResource(win.MAKEINTRESOURCE(uintptr(id))) 75 | } 76 | 77 | // Dispose removes the font resource from memory 78 | func (fmr *FontMemResource) Dispose() { 79 | if fmr.hFontResource != 0 { 80 | win.RemoveFontMemResourceEx(fmr.hFontResource) 81 | fmr.hFontResource = 0 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /iconcache.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | var iconCache *IconCache 10 | 11 | func init() { 12 | AppendToWalkInit(func() { 13 | iconCache = NewIconCache() 14 | }) 15 | } 16 | 17 | type IconCache struct { 18 | imageAndDPI2Bitmap map[imageAndDPI]*Bitmap 19 | imageAndDPI2Icon map[imageAndDPI]*Icon 20 | } 21 | 22 | type imageAndDPI struct { 23 | image Image 24 | dpi int 25 | } 26 | 27 | func NewIconCache() *IconCache { 28 | return &IconCache{ 29 | imageAndDPI2Bitmap: make(map[imageAndDPI]*Bitmap), 30 | imageAndDPI2Icon: make(map[imageAndDPI]*Icon), 31 | } 32 | } 33 | 34 | func (ic *IconCache) Clear() { 35 | for key, bmp := range ic.imageAndDPI2Bitmap { 36 | bmp.Dispose() 37 | delete(ic.imageAndDPI2Bitmap, key) 38 | } 39 | for key, ico := range ic.imageAndDPI2Icon { 40 | ico.Dispose() 41 | delete(ic.imageAndDPI2Icon, key) 42 | } 43 | } 44 | 45 | func (ic *IconCache) Dispose() { 46 | ic.Clear() 47 | } 48 | 49 | func (ic *IconCache) Bitmap(image Image, dpi int) (*Bitmap, error) { 50 | key := imageAndDPI{image, dpi} 51 | 52 | if bmp, ok := ic.imageAndDPI2Bitmap[key]; ok { 53 | return bmp, nil 54 | } 55 | 56 | size := SizeFrom96DPI(image.Size(), dpi) 57 | 58 | bmp, err := NewBitmapFromImageWithSize(image, size) 59 | if err != nil { 60 | return nil, err 61 | } 62 | 63 | ic.imageAndDPI2Bitmap[key] = bmp 64 | 65 | return bmp, nil 66 | } 67 | 68 | func (ic *IconCache) Icon(image Image, dpi int) (*Icon, error) { 69 | key := imageAndDPI{image, dpi} 70 | 71 | if ico, ok := ic.imageAndDPI2Icon[key]; ok { 72 | return ico, nil 73 | } 74 | 75 | if ico, ok := image.(*Icon); ok { 76 | if ico.handleForDPI(dpi) != 0 { 77 | ic.imageAndDPI2Icon[key] = ico 78 | return ico, nil 79 | } 80 | } 81 | 82 | ico, err := newIconFromImageForDPI(image, dpi) 83 | if err != nil { 84 | return nil, err 85 | } 86 | 87 | ic.imageAndDPI2Icon[key] = ico 88 | 89 | return ico, nil 90 | } 91 | -------------------------------------------------------------------------------- /intevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type intEventHandlerInfo struct { 10 | handler IntEventHandler 11 | once bool 12 | } 13 | 14 | type IntEventHandler func(n int) 15 | 16 | type IntEvent struct { 17 | handlers []intEventHandlerInfo 18 | } 19 | 20 | func (e *IntEvent) Attach(handler IntEventHandler) int { 21 | handlerInfo := intEventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *IntEvent) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *IntEvent) Once(handler IntEventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type IntEventPublisher struct { 45 | event IntEvent 46 | } 47 | 48 | func (p *IntEventPublisher) Event() *IntEvent { 49 | return &p.event 50 | } 51 | 52 | func (p *IntEventPublisher) Publish(n int) { 53 | for i, h := range p.event.handlers { 54 | if h.handler != nil { 55 | h.handler(n) 56 | 57 | if h.once { 58 | p.event.Detach(i) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /intrangeevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type intRangeEventHandlerInfo struct { 10 | handler IntRangeEventHandler 11 | once bool 12 | } 13 | 14 | type IntRangeEventHandler func(from, to int) 15 | 16 | type IntRangeEvent struct { 17 | handlers []intRangeEventHandlerInfo 18 | } 19 | 20 | func (e *IntRangeEvent) Attach(handler IntRangeEventHandler) int { 21 | handlerInfo := intRangeEventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *IntRangeEvent) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *IntRangeEvent) Once(handler IntRangeEventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type IntRangeEventPublisher struct { 45 | event IntRangeEvent 46 | } 47 | 48 | func (p *IntRangeEventPublisher) Event() *IntRangeEvent { 49 | return &p.event 50 | } 51 | 52 | func (p *IntRangeEventPublisher) Publish(from, to int) { 53 | for i, h := range p.event.handlers { 54 | if h.handler != nil { 55 | h.handler(from, to) 56 | 57 | if h.once { 58 | p.event.Detach(i) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /keyevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type keyEventHandlerInfo struct { 10 | handler KeyEventHandler 11 | once bool 12 | } 13 | 14 | type KeyEventHandler func(key Key) 15 | 16 | type KeyEvent struct { 17 | handlers []keyEventHandlerInfo 18 | } 19 | 20 | func (e *KeyEvent) Attach(handler KeyEventHandler) int { 21 | handlerInfo := keyEventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *KeyEvent) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *KeyEvent) Once(handler KeyEventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type KeyEventPublisher struct { 45 | event KeyEvent 46 | } 47 | 48 | func (p *KeyEventPublisher) Event() *KeyEvent { 49 | return &p.event 50 | } 51 | 52 | func (p *KeyEventPublisher) Publish(key Key) { 53 | for i, h := range p.event.handlers { 54 | if h.handler != nil { 55 | h.handler(key) 56 | 57 | if h.once { 58 | p.event.Detach(i) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /l10n/update.bat: -------------------------------------------------------------------------------- 1 | polyglot -name="walk" -dir=".." -locales="de,fr,ko" 2 | -------------------------------------------------------------------------------- /l10n/walk-de.tr: -------------------------------------------------------------------------------- 1 | {"Messages":[{"Locations":[{"File":"../validators.go","Line":"148"}],"Source":"Please select one of the provided options.","Context":["walk"],"Translation":"Bitte wählen Sie eine der angebotenen Optionen."},{"Locations":[{"File":"../declarative/radiobuttongroup.go","Line":"93"}],"Source":"A selection is required.","Context":["walk"],"Translation":"Eine Auswahl wird benötigt."},{"Locations":[{"File":"../tooltiperrorpresenter.go","Line":"107"}],"Source":"Invalid Input","Context":null,"Translation":"Ungültige Eingabe"},{"Locations":[{"File":"../validators.go","Line":"80"}],"Source":"Please enter a number from %.f to %.f.","Context":["walk"],"Translation":"Bitte geben Sie eine Zahl von %.f bis %.f ein."},{"Locations":[{"File":"../validators.go","Line":"83"}],"Source":"Please enter a number from %s to %s.","Context":["walk"],"Translation":"Bitte geben Sie eine Zahl von %s bis %s ein."},{"Locations":[{"File":"../validators.go","Line":"87"}],"Source":"Number out of allowed range","Context":["walk"],"Translation":"Zahl außerhalb des gültigen Bereichs"},{"Locations":[{"File":"../validators.go","Line":"128"}],"Source":"The text does not match the required pattern.","Context":["walk"],"Translation":"Der Text entspricht nicht dem erforderlichen Muster."},{"Locations":[{"File":"../validators.go","Line":"147"}],"Source":"Selection Required","Context":["walk"],"Translation":"Auswahl benötigt"}]} 2 | -------------------------------------------------------------------------------- /l10n/walk-ko.tr: -------------------------------------------------------------------------------- 1 | {"Messages":[{"Locations":[{"File":"../validators.go","Line":"87"}],"Source":"Number out of allowed range","Context":["walk"],"Translation":"허용 범위 초과"},{"Locations":[{"File":"../validators.go","Line":"128"}],"Source":"The text does not match the required pattern.","Context":["walk"],"Translation":"문자열이 요구되는 형식에 맞지 않습니다."},{"Locations":[{"File":"../validators.go","Line":"147"}],"Source":"Selection Required","Context":["walk"],"Translation":"선택 필요"},{"Locations":[{"File":"../validators.go","Line":"148"}],"Source":"Please select one of the provided options.","Context":["walk"],"Translation":"옵션 중 하나를 선택하십시오"},{"Locations":[{"File":"../tooltiperrorpresenter.go","Line":"107"}],"Source":"Invalid Input","Context":null,"Translation":"잘못된 입력"},{"Locations":[{"File":"../declarative/radiobuttongroup.go","Line":"93"}],"Source":"A selection is required.","Context":["walk"],"Translation":"항목 선택이 필요합니다."},{"Locations":[{"File":"../validators.go","Line":"80"}],"Source":"Please enter a number from %.f to %.f.","Context":["walk"],"Translation":"%.f에서 %.f 사이의 숫자를 입력하십시오."},{"Locations":[{"File":"../validators.go","Line":"83"}],"Source":"Please enter a number from %s to %s.","Context":["walk"],"Translation":"%s에서 %s 사이의 숫자를 입력하십시오."}]} -------------------------------------------------------------------------------- /label.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import "github.com/lxn/win" 10 | 11 | type EllipsisMode int 12 | 13 | const ( 14 | EllipsisNone EllipsisMode = 0 15 | EllipsisEnd = EllipsisMode(win.SS_ENDELLIPSIS) 16 | EllipsisPath = EllipsisMode(win.SS_PATHELLIPSIS) 17 | ) 18 | 19 | type Label struct { 20 | static 21 | textChangedPublisher EventPublisher 22 | } 23 | 24 | func NewLabel(parent Container) (*Label, error) { 25 | return NewLabelWithStyle(parent, 0) 26 | } 27 | 28 | func NewLabelWithStyle(parent Container, style uint32) (*Label, error) { 29 | l := new(Label) 30 | 31 | if err := l.init(l, parent, style); err != nil { 32 | return nil, err 33 | } 34 | 35 | l.SetTextAlignment(AlignNear) 36 | 37 | l.MustRegisterProperty("Text", NewProperty( 38 | func() interface{} { 39 | return l.Text() 40 | }, 41 | func(v interface{}) error { 42 | return l.SetText(assertStringOr(v, "")) 43 | }, 44 | l.textChangedPublisher.Event())) 45 | 46 | return l, nil 47 | } 48 | 49 | func (l *Label) asStatic() *static { 50 | return &l.static 51 | } 52 | 53 | func (l *Label) EllipsisMode() EllipsisMode { 54 | return EllipsisMode(win.GetWindowLong(l.hwndStatic, win.GWL_STYLE) & (win.SS_ENDELLIPSIS | win.SS_PATHELLIPSIS)) 55 | } 56 | 57 | func (l *Label) SetEllipsisMode(mode EllipsisMode) error { 58 | oldMode := l.EllipsisMode() 59 | 60 | if mode == oldMode { 61 | return nil 62 | } 63 | 64 | if err := setAndClearWindowLongBits(l.hwndStatic, win.GWL_STYLE, uint32(mode), uint32(oldMode)); err != nil { 65 | return err 66 | } 67 | 68 | l.RequestLayout() 69 | 70 | return nil 71 | } 72 | 73 | func (l *Label) TextAlignment() Alignment1D { 74 | return l.textAlignment1D() 75 | } 76 | 77 | func (l *Label) SetTextAlignment(alignment Alignment1D) error { 78 | if alignment == AlignDefault { 79 | alignment = AlignNear 80 | } 81 | 82 | return l.setTextAlignment1D(alignment) 83 | } 84 | 85 | func (l *Label) Text() string { 86 | return l.text() 87 | } 88 | 89 | func (l *Label) SetText(text string) error { 90 | if changed, err := l.setText(text); err != nil { 91 | return err 92 | } else if !changed { 93 | return nil 94 | } 95 | 96 | l.textChangedPublisher.Publish() 97 | 98 | return nil 99 | } 100 | -------------------------------------------------------------------------------- /mainloop_cgo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows,walk_use_cgo 6 | 7 | package walk 8 | 9 | import ( 10 | "unsafe" 11 | 12 | "github.com/lxn/win" 13 | ) 14 | 15 | // #include 16 | // 17 | // extern void shimRunSynchronized(uintptr_t fb); 18 | // extern unsigned char shimHandleKeyDown(uintptr_t fb, uintptr_t m); 19 | // 20 | // static int mainloop(uintptr_t handle_ptr, uintptr_t fb_ptr) 21 | // { 22 | // HANDLE *hwnd = (HANDLE *)handle_ptr; 23 | // MSG m; 24 | // int r; 25 | // 26 | // while (*hwnd) { 27 | // r = GetMessage(&m, NULL, 0, 0); 28 | // if (!r) 29 | // return m.wParam; 30 | // else if (r < 0) 31 | // return -1; 32 | // if (m.message == WM_KEYDOWN && shimHandleKeyDown(fb_ptr, (uintptr_t)&m)) 33 | // continue; 34 | // if (!IsDialogMessage(*hwnd, &m)) { 35 | // TranslateMessage(&m); 36 | // DispatchMessage(&m); 37 | // } 38 | // shimRunSynchronized(fb_ptr); 39 | // } 40 | // return 0; 41 | // } 42 | import "C" 43 | 44 | //export shimHandleKeyDown 45 | func shimHandleKeyDown(fb uintptr, msg uintptr) bool { 46 | return (*FormBase)(unsafe.Pointer(fb)).handleKeyDown((*win.MSG)(unsafe.Pointer(msg))) 47 | } 48 | 49 | //export shimRunSynchronized 50 | func shimRunSynchronized(fb uintptr) { 51 | (*FormBase)(unsafe.Pointer(fb)).group.RunSynchronized() 52 | } 53 | 54 | func (fb *FormBase) mainLoop() int { 55 | return int(C.mainloop(C.uintptr_t(uintptr(unsafe.Pointer(&fb.hWnd))), C.uintptr_t(uintptr(unsafe.Pointer(fb))))) 56 | } 57 | -------------------------------------------------------------------------------- /mainloop_default.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows,!walk_use_cgo 6 | 7 | package walk 8 | 9 | import ( 10 | "unsafe" 11 | 12 | "github.com/lxn/win" 13 | ) 14 | 15 | func (fb *FormBase) mainLoop() int { 16 | msg := (*win.MSG)(unsafe.Pointer(win.GlobalAlloc(0, unsafe.Sizeof(win.MSG{})))) 17 | defer win.GlobalFree(win.HGLOBAL(unsafe.Pointer(msg))) 18 | 19 | for fb.hWnd != 0 { 20 | switch win.GetMessage(msg, 0, 0, 0) { 21 | case 0: 22 | return int(msg.WParam) 23 | 24 | case -1: 25 | return -1 26 | } 27 | 28 | switch msg.Message { 29 | case win.WM_KEYDOWN: 30 | if fb.handleKeyDown(msg) { 31 | continue 32 | } 33 | } 34 | 35 | if !win.IsDialogMessage(fb.hWnd, msg) { 36 | win.TranslateMessage(msg) 37 | win.DispatchMessage(msg) 38 | } 39 | 40 | fb.group.RunSynchronized() 41 | } 42 | 43 | return 0 44 | } 45 | -------------------------------------------------------------------------------- /maptablemodel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "sort" 11 | ) 12 | 13 | type mapTableModel struct { 14 | TableModelBase 15 | SorterBase 16 | dataMembers []string 17 | dataSource interface{} 18 | items []map[string]interface{} 19 | } 20 | 21 | func newMapTableModel(dataSource interface{}) (TableModel, error) { 22 | items, ok := dataSource.([]map[string]interface{}) 23 | if !ok { 24 | return nil, newError("dataSource must be assignable to []map[string]interface{}") 25 | } 26 | 27 | return &mapTableModel{dataSource: dataSource, items: items}, nil 28 | } 29 | 30 | func (m *mapTableModel) setDataMembers(dataMembers []string) { 31 | m.dataMembers = dataMembers 32 | } 33 | 34 | func (m *mapTableModel) RowCount() int { 35 | return len(m.items) 36 | } 37 | 38 | func (m *mapTableModel) Value(row, col int) interface{} { 39 | if m.items[row] == nil { 40 | if populator, ok := m.dataSource.(Populator); ok { 41 | if err := populator.Populate(row); err != nil { 42 | return err 43 | } 44 | } 45 | 46 | if m.items[row] == nil { 47 | return nil 48 | } 49 | } 50 | 51 | return m.items[row][m.dataMembers[col]] 52 | } 53 | 54 | func (m *mapTableModel) Sort(col int, order SortOrder) error { 55 | m.col, m.order = col, order 56 | 57 | sort.Stable(m) 58 | 59 | m.changedPublisher.Publish() 60 | 61 | return nil 62 | } 63 | 64 | func (m *mapTableModel) Len() int { 65 | return m.RowCount() 66 | } 67 | 68 | func (m *mapTableModel) Less(i, j int) bool { 69 | col := m.SortedColumn() 70 | 71 | return less(m.Value(i, col), m.Value(j, col), m.SortOrder()) 72 | } 73 | 74 | func (m *mapTableModel) Swap(i, j int) { 75 | m.items[i], m.items[j] = m.items[j], m.items[i] 76 | } 77 | -------------------------------------------------------------------------------- /messagebox.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "strings" 11 | "syscall" 12 | ) 13 | 14 | import ( 15 | "github.com/lxn/win" 16 | ) 17 | 18 | type MsgBoxStyle uint 19 | 20 | const ( 21 | MsgBoxOK MsgBoxStyle = win.MB_OK 22 | MsgBoxOKCancel MsgBoxStyle = win.MB_OKCANCEL 23 | MsgBoxAbortRetryIgnore MsgBoxStyle = win.MB_ABORTRETRYIGNORE 24 | MsgBoxYesNoCancel MsgBoxStyle = win.MB_YESNOCANCEL 25 | MsgBoxYesNo MsgBoxStyle = win.MB_YESNO 26 | MsgBoxRetryCancel MsgBoxStyle = win.MB_RETRYCANCEL 27 | MsgBoxCancelTryContinue MsgBoxStyle = win.MB_CANCELTRYCONTINUE 28 | MsgBoxIconHand MsgBoxStyle = win.MB_ICONHAND 29 | MsgBoxIconQuestion MsgBoxStyle = win.MB_ICONQUESTION 30 | MsgBoxIconExclamation MsgBoxStyle = win.MB_ICONEXCLAMATION 31 | MsgBoxIconAsterisk MsgBoxStyle = win.MB_ICONASTERISK 32 | MsgBoxUserIcon MsgBoxStyle = win.MB_USERICON 33 | MsgBoxIconWarning MsgBoxStyle = win.MB_ICONWARNING 34 | MsgBoxIconError MsgBoxStyle = win.MB_ICONERROR 35 | MsgBoxIconInformation MsgBoxStyle = win.MB_ICONINFORMATION 36 | MsgBoxIconStop MsgBoxStyle = win.MB_ICONSTOP 37 | MsgBoxDefButton1 MsgBoxStyle = win.MB_DEFBUTTON1 38 | MsgBoxDefButton2 MsgBoxStyle = win.MB_DEFBUTTON2 39 | MsgBoxDefButton3 MsgBoxStyle = win.MB_DEFBUTTON3 40 | MsgBoxDefButton4 MsgBoxStyle = win.MB_DEFBUTTON4 41 | MsgBoxApplModal MsgBoxStyle = win.MB_APPLMODAL 42 | MsgBoxSystemModal MsgBoxStyle = win.MB_SYSTEMMODAL 43 | MsgBoxTaskModal MsgBoxStyle = win.MB_TASKMODAL 44 | MsgBoxHelp MsgBoxStyle = win.MB_HELP 45 | MsgBoxSetForeground MsgBoxStyle = win.MB_SETFOREGROUND 46 | MsgBoxDefaultDesktopOnly MsgBoxStyle = win.MB_DEFAULT_DESKTOP_ONLY 47 | MsgBoxTopMost MsgBoxStyle = win.MB_TOPMOST 48 | MsgBoxRight MsgBoxStyle = win.MB_RIGHT 49 | MsgBoxRTLReading MsgBoxStyle = win.MB_RTLREADING 50 | MsgBoxServiceNotification MsgBoxStyle = win.MB_SERVICE_NOTIFICATION 51 | ) 52 | 53 | func MsgBox(owner Form, title, message string, style MsgBoxStyle) int { 54 | var ownerHWnd win.HWND 55 | 56 | if owner != nil { 57 | ownerHWnd = owner.Handle() 58 | } 59 | 60 | return int(win.MessageBox( 61 | ownerHWnd, 62 | syscall.StringToUTF16Ptr(strings.ReplaceAll(message, "\x00", "␀")), 63 | syscall.StringToUTF16Ptr(strings.ReplaceAll(title, "\x00", "␀")), 64 | uint32(style))) 65 | } 66 | -------------------------------------------------------------------------------- /mouseevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | ) 12 | 13 | type MouseButton int 14 | 15 | const ( 16 | LeftButton MouseButton = win.MK_LBUTTON 17 | RightButton MouseButton = win.MK_RBUTTON 18 | MiddleButton MouseButton = win.MK_MBUTTON 19 | ) 20 | 21 | type mouseEventHandlerInfo struct { 22 | handler MouseEventHandler 23 | once bool 24 | } 25 | 26 | // MouseEventHandler is called for mouse events. x and y are measured in native pixels. 27 | type MouseEventHandler func(x, y int, button MouseButton) 28 | 29 | type MouseEvent struct { 30 | handlers []mouseEventHandlerInfo 31 | } 32 | 33 | func (e *MouseEvent) Attach(handler MouseEventHandler) int { 34 | handlerInfo := mouseEventHandlerInfo{handler, false} 35 | 36 | for i, h := range e.handlers { 37 | if h.handler == nil { 38 | e.handlers[i] = handlerInfo 39 | return i 40 | } 41 | } 42 | 43 | e.handlers = append(e.handlers, handlerInfo) 44 | 45 | return len(e.handlers) - 1 46 | } 47 | 48 | func (e *MouseEvent) Detach(handle int) { 49 | e.handlers[handle].handler = nil 50 | } 51 | 52 | func (e *MouseEvent) Once(handler MouseEventHandler) { 53 | i := e.Attach(handler) 54 | e.handlers[i].once = true 55 | } 56 | 57 | type MouseEventPublisher struct { 58 | event MouseEvent 59 | } 60 | 61 | func (p *MouseEventPublisher) Event() *MouseEvent { 62 | return &p.event 63 | } 64 | 65 | // Publish publishes mouse event. x and y are measured in native pixels. 66 | func (p *MouseEventPublisher) Publish(x, y int, button MouseButton) { 67 | for i, h := range p.event.handlers { 68 | if h.handler != nil { 69 | h.handler(x, y, button) 70 | 71 | if h.once { 72 | p.event.Detach(i) 73 | } 74 | } 75 | } 76 | } 77 | 78 | func MouseWheelEventDelta(button MouseButton) int { 79 | return int(int32(button) >> 16) 80 | } 81 | 82 | func MouseWheelEventKeyState(button MouseButton) int { 83 | return int(int32(button) & 0xFFFF) 84 | } 85 | -------------------------------------------------------------------------------- /path.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "syscall" 11 | 12 | "github.com/lxn/win" 13 | ) 14 | 15 | func knownFolderPath(id win.CSIDL) (string, error) { 16 | var buf [win.MAX_PATH]uint16 17 | 18 | if !win.SHGetSpecialFolderPath(0, &buf[0], id, false) { 19 | return "", newError("SHGetSpecialFolderPath failed") 20 | } 21 | 22 | return syscall.UTF16ToString(buf[0:]), nil 23 | } 24 | 25 | func AppDataPath() (string, error) { 26 | return knownFolderPath(win.CSIDL_APPDATA) 27 | } 28 | 29 | func CommonAppDataPath() (string, error) { 30 | return knownFolderPath(win.CSIDL_COMMON_APPDATA) 31 | } 32 | 33 | func LocalAppDataPath() (string, error) { 34 | return knownFolderPath(win.CSIDL_LOCAL_APPDATA) 35 | } 36 | 37 | func PersonalPath() (string, error) { 38 | return knownFolderPath(win.CSIDL_PERSONAL) 39 | } 40 | 41 | func SystemPath() (string, error) { 42 | return knownFolderPath(win.CSIDL_SYSTEM) 43 | } 44 | 45 | func DriveNames() ([]string, error) { 46 | bufLen := win.GetLogicalDriveStrings(0, nil) 47 | if bufLen == 0 { 48 | return nil, lastError("GetLogicalDriveStrings") 49 | } 50 | buf := make([]uint16, bufLen+1) 51 | 52 | bufLen = win.GetLogicalDriveStrings(bufLen+1, &buf[0]) 53 | if bufLen == 0 { 54 | return nil, lastError("GetLogicalDriveStrings") 55 | } 56 | 57 | var names []string 58 | 59 | for i := 0; i < len(buf)-2; { 60 | name := syscall.UTF16ToString(buf[i:]) 61 | names = append(names, name) 62 | i += len(name) + 1 63 | } 64 | 65 | return names, nil 66 | } 67 | -------------------------------------------------------------------------------- /point.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import "github.com/lxn/win" 10 | 11 | // Point defines 2D coordinate in 1/96" units ot native pixels. 12 | type Point struct { 13 | X, Y int 14 | } 15 | 16 | func (p Point) toPOINT() win.POINT { 17 | return win.POINT{ 18 | X: int32(p.X), 19 | Y: int32(p.Y), 20 | } 21 | } 22 | 23 | func pointPixelsFromPOINT(p win.POINT) Point { 24 | return Point{ 25 | X: int(p.X), 26 | Y: int(p.Y), 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /progressbar.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | ) 12 | 13 | type ProgressBar struct { 14 | WidgetBase 15 | } 16 | 17 | func NewProgressBar(parent Container) (*ProgressBar, error) { 18 | pb := new(ProgressBar) 19 | 20 | if err := InitWidget( 21 | pb, 22 | parent, 23 | "msctls_progress32", 24 | win.WS_VISIBLE, 25 | 0); err != nil { 26 | return nil, err 27 | } 28 | 29 | return pb, nil 30 | } 31 | 32 | func (pb *ProgressBar) MinValue() int { 33 | return int(pb.SendMessage(win.PBM_GETRANGE, 1, 0)) 34 | } 35 | 36 | func (pb *ProgressBar) MaxValue() int { 37 | return int(pb.SendMessage(win.PBM_GETRANGE, 0, 0)) 38 | } 39 | 40 | func (pb *ProgressBar) SetRange(min, max int) { 41 | pb.SendMessage(win.PBM_SETRANGE32, uintptr(min), uintptr(max)) 42 | } 43 | 44 | func (pb *ProgressBar) Value() int { 45 | return int(pb.SendMessage(win.PBM_GETPOS, 0, 0)) 46 | } 47 | 48 | func (pb *ProgressBar) SetValue(value int) { 49 | pb.SendMessage(win.PBM_SETPOS, uintptr(value), 0) 50 | } 51 | 52 | func (pb *ProgressBar) MarqueeMode() bool { 53 | return pb.hasStyleBits(win.PBS_MARQUEE) 54 | } 55 | 56 | func (pb *ProgressBar) SetMarqueeMode(marqueeMode bool) error { 57 | if err := pb.ensureStyleBits(win.PBS_MARQUEE, marqueeMode); err != nil { 58 | return err 59 | } 60 | 61 | pb.SendMessage(win.PBM_SETMARQUEE, uintptr(win.BoolToBOOL(marqueeMode)), 0) 62 | 63 | return nil 64 | } 65 | 66 | func (pb *ProgressBar) CreateLayoutItem(ctx *LayoutContext) LayoutItem { 67 | return &progressBarLayoutItem{ 68 | idealSize: pb.dialogBaseUnitsToPixels(Size{50, 14}), 69 | minSize: pb.dialogBaseUnitsToPixels(Size{10, 14}), 70 | } 71 | } 72 | 73 | type progressBarLayoutItem struct { 74 | LayoutItemBase 75 | idealSize Size // in native pixels 76 | minSize Size // in native pixels 77 | } 78 | 79 | func (*progressBarLayoutItem) LayoutFlags() LayoutFlags { 80 | return ShrinkableHorz | GrowableHorz | GreedyHorz 81 | } 82 | 83 | func (li *progressBarLayoutItem) IdealSize() Size { 84 | return li.idealSize 85 | } 86 | 87 | func (li *progressBarLayoutItem) MinSize() Size { 88 | return li.minSize 89 | } 90 | -------------------------------------------------------------------------------- /rectangle.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | ) 12 | 13 | // Rectangle defines upper left corner with width and height region in 1/96" units, or native 14 | // pixels, or grid rows and columns. 15 | type Rectangle struct { 16 | X, Y, Width, Height int 17 | } 18 | 19 | func (r Rectangle) IsZero() bool { 20 | return r.X == 0 && r.Y == 0 && r.Width == 0 && r.Height == 0 21 | } 22 | 23 | func rectangleFromRECT(r win.RECT) Rectangle { 24 | return Rectangle{ 25 | X: int(r.Left), 26 | Y: int(r.Top), 27 | Width: int(r.Right - r.Left), 28 | Height: int(r.Bottom - r.Top), 29 | } 30 | } 31 | 32 | func (r Rectangle) Left() int { 33 | return r.X 34 | } 35 | 36 | func (r Rectangle) Top() int { 37 | return r.Y 38 | } 39 | 40 | func (r Rectangle) Right() int { 41 | return r.X + r.Width - 1 42 | } 43 | 44 | func (r Rectangle) Bottom() int { 45 | return r.Y + r.Height - 1 46 | } 47 | 48 | func (r Rectangle) Location() Point { 49 | return Point{r.X, r.Y} 50 | } 51 | 52 | func (r *Rectangle) SetLocation(p Point) Rectangle { 53 | r.X = p.X 54 | r.Y = p.Y 55 | 56 | return *r 57 | } 58 | 59 | func (r Rectangle) Size() Size { 60 | return Size{r.Width, r.Height} 61 | } 62 | 63 | func (r *Rectangle) SetSize(s Size) Rectangle { 64 | r.Width = s.Width 65 | r.Height = s.Height 66 | 67 | return *r 68 | } 69 | 70 | func (r Rectangle) toRECT() win.RECT { 71 | return win.RECT{ 72 | int32(r.X), 73 | int32(r.Y), 74 | int32(r.X + r.Width), 75 | int32(r.Y + r.Height), 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /registry.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | import ( 15 | "github.com/lxn/win" 16 | ) 17 | 18 | type RegistryKey struct { 19 | hKey win.HKEY 20 | } 21 | 22 | func ClassesRootKey() *RegistryKey { 23 | return &RegistryKey{win.HKEY_CLASSES_ROOT} 24 | } 25 | 26 | func CurrentUserKey() *RegistryKey { 27 | return &RegistryKey{win.HKEY_CURRENT_USER} 28 | } 29 | 30 | func LocalMachineKey() *RegistryKey { 31 | return &RegistryKey{win.HKEY_LOCAL_MACHINE} 32 | } 33 | 34 | func RegistryKeyString(rootKey *RegistryKey, subKeyPath, valueName string) (value string, err error) { 35 | var hKey win.HKEY 36 | if win.RegOpenKeyEx( 37 | rootKey.hKey, 38 | syscall.StringToUTF16Ptr(subKeyPath), 39 | 0, 40 | win.KEY_READ, 41 | &hKey) != win.ERROR_SUCCESS { 42 | 43 | return "", newError("RegistryKeyString: Failed to open subkey.") 44 | } 45 | defer win.RegCloseKey(hKey) 46 | 47 | var typ uint32 48 | var data []uint16 49 | var bufSize uint32 50 | 51 | if win.ERROR_SUCCESS != win.RegQueryValueEx( 52 | hKey, 53 | syscall.StringToUTF16Ptr(valueName), 54 | nil, 55 | &typ, 56 | nil, 57 | &bufSize) { 58 | 59 | return "", newError("RegQueryValueEx #1") 60 | } 61 | 62 | data = make([]uint16, bufSize/2+1) 63 | 64 | if win.ERROR_SUCCESS != win.RegQueryValueEx( 65 | hKey, 66 | syscall.StringToUTF16Ptr(valueName), 67 | nil, 68 | &typ, 69 | (*byte)(unsafe.Pointer(&data[0])), 70 | &bufSize) { 71 | 72 | return "", newError("RegQueryValueEx #2") 73 | } 74 | 75 | return syscall.UTF16ToString(data), nil 76 | } 77 | 78 | func RegistryKeyUint32(rootKey *RegistryKey, subKeyPath, valueName string) (value uint32, err error) { 79 | var hKey win.HKEY 80 | if win.RegOpenKeyEx( 81 | rootKey.hKey, 82 | syscall.StringToUTF16Ptr(subKeyPath), 83 | 0, 84 | win.KEY_READ, 85 | &hKey) != win.ERROR_SUCCESS { 86 | 87 | return 0, newError("RegistryKeyUint32: Failed to open subkey.") 88 | } 89 | defer win.RegCloseKey(hKey) 90 | 91 | bufSize := uint32(4) 92 | 93 | if win.ERROR_SUCCESS != win.RegQueryValueEx( 94 | hKey, 95 | syscall.StringToUTF16Ptr(valueName), 96 | nil, 97 | nil, 98 | (*byte)(unsafe.Pointer(&value)), 99 | &bufSize) { 100 | 101 | return 0, newError("RegQueryValueEx") 102 | } 103 | 104 | return 105 | } 106 | -------------------------------------------------------------------------------- /separator.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | ) 12 | 13 | type Separator struct { 14 | WidgetBase 15 | vertical bool 16 | } 17 | 18 | func NewHSeparator(parent Container) (*Separator, error) { 19 | return newSeparator(parent, false) 20 | } 21 | 22 | func NewVSeparator(parent Container) (*Separator, error) { 23 | return newSeparator(parent, true) 24 | } 25 | 26 | func newSeparator(parent Container, vertical bool) (*Separator, error) { 27 | s := &Separator{vertical: vertical} 28 | 29 | if err := InitWidget( 30 | s, 31 | parent, 32 | "STATIC", 33 | win.WS_VISIBLE|win.SS_ETCHEDHORZ, 34 | 0); err != nil { 35 | return nil, err 36 | } 37 | 38 | return s, nil 39 | } 40 | 41 | func (s *Separator) CreateLayoutItem(ctx *LayoutContext) LayoutItem { 42 | var layoutFlags LayoutFlags 43 | if s.vertical { 44 | layoutFlags = GrowableHorz | GreedyHorz 45 | } else { 46 | layoutFlags = GrowableVert | GreedyVert 47 | } 48 | 49 | return &separatorLayoutItem{ 50 | layoutFlags: layoutFlags, 51 | } 52 | } 53 | 54 | type separatorLayoutItem struct { 55 | LayoutItemBase 56 | layoutFlags LayoutFlags 57 | } 58 | 59 | func (li *separatorLayoutItem) LayoutFlags() LayoutFlags { 60 | return li.layoutFlags 61 | } 62 | 63 | func (li *separatorLayoutItem) IdealSize() Size { 64 | return li.MinSize() 65 | } 66 | 67 | func (li *separatorLayoutItem) MinSize() Size { 68 | return SizeFrom96DPI(Size{2, 2}, li.ctx.dpi) 69 | } 70 | -------------------------------------------------------------------------------- /simpletypes.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type Alignment1D uint 10 | 11 | const ( 12 | AlignDefault Alignment1D = iota 13 | AlignNear 14 | AlignCenter 15 | AlignFar 16 | ) 17 | 18 | type Alignment2D uint 19 | 20 | const ( 21 | AlignHVDefault Alignment2D = iota 22 | AlignHNearVNear 23 | AlignHCenterVNear 24 | AlignHFarVNear 25 | AlignHNearVCenter 26 | AlignHCenterVCenter 27 | AlignHFarVCenter 28 | AlignHNearVFar 29 | AlignHCenterVFar 30 | AlignHFarVFar 31 | ) 32 | -------------------------------------------------------------------------------- /size.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import "github.com/lxn/win" 10 | 11 | // Size defines width and height in 1/96" units or native pixels, or dialog base units. 12 | // 13 | // When Size is used for DPI metrics, it defines a 1"x1" rectangle in native pixels. 14 | type Size struct { 15 | Width, Height int 16 | } 17 | 18 | func (s Size) IsZero() bool { 19 | return s.Width == 0 && s.Height == 0 20 | } 21 | 22 | func (s Size) toSIZE() win.SIZE { 23 | return win.SIZE{ 24 | CX: int32(s.Width), 25 | CY: int32(s.Height), 26 | } 27 | } 28 | 29 | func minSize(a, b Size) Size { 30 | var s Size 31 | 32 | if a.Width < b.Width { 33 | s.Width = a.Width 34 | } else { 35 | s.Width = b.Width 36 | } 37 | 38 | if a.Height < b.Height { 39 | s.Height = a.Height 40 | } else { 41 | s.Height = b.Height 42 | } 43 | 44 | return s 45 | } 46 | 47 | func maxSize(a, b Size) Size { 48 | var s Size 49 | 50 | if a.Width > b.Width { 51 | s.Width = a.Width 52 | } else { 53 | s.Width = b.Width 54 | } 55 | 56 | if a.Height > b.Height { 57 | s.Height = a.Height 58 | } else { 59 | s.Height = b.Height 60 | } 61 | 62 | return s 63 | } 64 | 65 | func sizeFromSIZE(s win.SIZE) Size { 66 | return Size{ 67 | Width: int(s.CX), 68 | Height: int(s.CY), 69 | } 70 | } 71 | 72 | func sizeFromRECT(r win.RECT) Size { 73 | return Size{ 74 | Width: int(r.Right - r.Left), 75 | Height: int(r.Bottom - r.Top), 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /spacer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | const spacerWindowClass = `\o/ Walk_Spacer_Class \o/` 10 | 11 | func init() { 12 | AppendToWalkInit(func() { 13 | MustRegisterWindowClass(spacerWindowClass) 14 | }) 15 | } 16 | 17 | type Spacer struct { 18 | WidgetBase 19 | sizeHint96dpi Size 20 | layoutFlags LayoutFlags 21 | greedyLocallyOnly bool 22 | } 23 | 24 | type SpacerCfg struct { 25 | LayoutFlags LayoutFlags 26 | SizeHint Size // in 1/96" units 27 | GreedyLocallyOnly bool 28 | } 29 | 30 | func NewSpacerWithCfg(parent Container, cfg *SpacerCfg) (*Spacer, error) { 31 | return newSpacer(parent, cfg.LayoutFlags, cfg.SizeHint, cfg.GreedyLocallyOnly) 32 | } 33 | 34 | func newSpacer(parent Container, layoutFlags LayoutFlags, sizeHint96dpi Size, greedyLocallyOnly bool) (*Spacer, error) { 35 | s := &Spacer{ 36 | layoutFlags: layoutFlags, 37 | sizeHint96dpi: sizeHint96dpi, 38 | greedyLocallyOnly: greedyLocallyOnly, 39 | } 40 | 41 | if err := InitWidget( 42 | s, 43 | parent, 44 | spacerWindowClass, 45 | 0, 46 | 0); err != nil { 47 | return nil, err 48 | } 49 | 50 | return s, nil 51 | } 52 | 53 | func NewHSpacer(parent Container) (*Spacer, error) { 54 | return newSpacer(parent, ShrinkableHorz|ShrinkableVert|GrowableHorz|GreedyHorz, Size{}, false) 55 | } 56 | 57 | func NewHSpacerFixed(parent Container, width int) (*Spacer, error) { 58 | return newSpacer(parent, 0, Size{width, 0}, false) 59 | } 60 | 61 | func NewVSpacer(parent Container) (*Spacer, error) { 62 | return newSpacer(parent, ShrinkableHorz|ShrinkableVert|GrowableVert|GreedyVert, Size{}, false) 63 | } 64 | 65 | func NewVSpacerFixed(parent Container, height int) (*Spacer, error) { 66 | return newSpacer(parent, 0, Size{0, height}, false) 67 | } 68 | 69 | func (s *Spacer) CreateLayoutItem(ctx *LayoutContext) LayoutItem { 70 | return &spacerLayoutItem{ 71 | idealSize96dpi: s.sizeHint96dpi, 72 | layoutFlags: s.layoutFlags, 73 | greedyLocallyOnly: s.greedyLocallyOnly, 74 | } 75 | } 76 | 77 | type spacerLayoutItem struct { 78 | LayoutItemBase 79 | idealSize96dpi Size 80 | layoutFlags LayoutFlags 81 | greedyLocallyOnly bool 82 | } 83 | 84 | func (li *spacerLayoutItem) LayoutFlags() LayoutFlags { 85 | return li.layoutFlags 86 | } 87 | 88 | func (li *spacerLayoutItem) IdealSize() Size { 89 | return SizeFrom96DPI(li.idealSize96dpi, li.ctx.dpi) 90 | } 91 | 92 | func (li *spacerLayoutItem) MinSize() Size { 93 | return SizeFrom96DPI(li.idealSize96dpi, li.ctx.dpi) 94 | } 95 | -------------------------------------------------------------------------------- /splitbutton.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "unsafe" 11 | ) 12 | 13 | import ( 14 | "github.com/lxn/win" 15 | ) 16 | 17 | type SplitButton struct { 18 | Button 19 | menu *Menu 20 | } 21 | 22 | func NewSplitButton(parent Container) (*SplitButton, error) { 23 | sb := new(SplitButton) 24 | 25 | var disposables Disposables 26 | defer disposables.Treat() 27 | 28 | if err := InitWidget( 29 | sb, 30 | parent, 31 | "BUTTON", 32 | win.WS_TABSTOP|win.WS_VISIBLE|win.BS_SPLITBUTTON, 33 | 0); err != nil { 34 | return nil, err 35 | } 36 | disposables.Add(sb) 37 | 38 | sb.Button.init() 39 | 40 | menu, err := NewMenu() 41 | if err != nil { 42 | return nil, err 43 | } 44 | disposables.Add(menu) 45 | menu.window = sb 46 | sb.menu = menu 47 | 48 | sb.GraphicsEffects().Add(InteractionEffect) 49 | sb.GraphicsEffects().Add(FocusEffect) 50 | 51 | disposables.Spare() 52 | 53 | return sb, nil 54 | } 55 | 56 | func (sb *SplitButton) Dispose() { 57 | sb.Button.Dispose() 58 | 59 | sb.menu.Dispose() 60 | } 61 | 62 | func (sb *SplitButton) ImageAboveText() bool { 63 | return sb.hasStyleBits(win.BS_TOP) 64 | } 65 | 66 | func (sb *SplitButton) SetImageAboveText(value bool) error { 67 | if err := sb.ensureStyleBits(win.BS_TOP, value); err != nil { 68 | return err 69 | } 70 | 71 | // We need to set the image again, or Windows will fail to calculate the 72 | // button control size correctly. 73 | return sb.SetImage(sb.image) 74 | } 75 | 76 | func (sb *SplitButton) Menu() *Menu { 77 | return sb.menu 78 | } 79 | 80 | func (sb *SplitButton) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr { 81 | switch msg { 82 | case win.WM_NOTIFY: 83 | switch ((*win.NMHDR)(unsafe.Pointer(lParam))).Code { 84 | case win.BCN_DROPDOWN: 85 | dd := (*win.NMBCDROPDOWN)(unsafe.Pointer(lParam)) 86 | 87 | p := win.POINT{dd.RcButton.Left, dd.RcButton.Bottom} 88 | 89 | win.ClientToScreen(sb.hWnd, &p) 90 | 91 | win.TrackPopupMenuEx( 92 | sb.menu.hMenu, 93 | win.TPM_NOANIMATION, 94 | p.X, 95 | p.Y, 96 | sb.hWnd, 97 | nil) 98 | return 0 99 | } 100 | } 101 | 102 | return sb.Button.WndProc(hwnd, msg, wParam, lParam) 103 | } 104 | -------------------------------------------------------------------------------- /splitterhandle.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | ) 12 | 13 | const splitterHandleWindowClass = `\o/ Walk_SplitterHandle_Class \o/` 14 | 15 | func init() { 16 | AppendToWalkInit(func() { 17 | MustRegisterWindowClass(splitterHandleWindowClass) 18 | }) 19 | } 20 | 21 | type splitterHandle struct { 22 | WidgetBase 23 | } 24 | 25 | func newSplitterHandle(splitter *Splitter) (*splitterHandle, error) { 26 | if splitter == nil { 27 | return nil, newError("splitter cannot be nil") 28 | } 29 | 30 | sh := new(splitterHandle) 31 | sh.parent = splitter 32 | 33 | if err := InitWindow( 34 | sh, 35 | splitter, 36 | splitterHandleWindowClass, 37 | win.WS_CHILD|win.WS_VISIBLE, 38 | 0); err != nil { 39 | return nil, err 40 | } 41 | 42 | sh.SetBackground(NullBrush()) 43 | 44 | if err := sh.setAndClearStyleBits(0, win.WS_CLIPSIBLINGS); err != nil { 45 | return nil, err 46 | } 47 | 48 | return sh, nil 49 | } 50 | 51 | func (sh *splitterHandle) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr { 52 | switch msg { 53 | case win.WM_ERASEBKGND: 54 | if sh.Background() == nullBrushSingleton { 55 | return 1 56 | } 57 | 58 | case win.WM_PAINT: 59 | if sh.Background() == nullBrushSingleton { 60 | var ps win.PAINTSTRUCT 61 | 62 | win.BeginPaint(hwnd, &ps) 63 | defer win.EndPaint(hwnd, &ps) 64 | 65 | return 0 66 | } 67 | } 68 | 69 | return sh.WidgetBase.WndProc(hwnd, msg, wParam, lParam) 70 | } 71 | 72 | func (sh *splitterHandle) CreateLayoutItem(ctx *LayoutContext) LayoutItem { 73 | var orientation Orientation 74 | var handleWidth int 75 | 76 | if splitter, ok := sh.Parent().(*Splitter); ok { 77 | orientation = splitter.Orientation() 78 | handleWidth = splitter.HandleWidth() 79 | } 80 | 81 | return &splitterHandleLayoutItem{ 82 | orientation: orientation, 83 | handleWidth: handleWidth, 84 | } 85 | } 86 | 87 | type splitterHandleLayoutItem struct { 88 | LayoutItemBase 89 | orientation Orientation 90 | handleWidth int 91 | } 92 | 93 | func (li *splitterHandleLayoutItem) LayoutFlags() LayoutFlags { 94 | if li.orientation == Horizontal { 95 | return ShrinkableVert | GrowableVert | GreedyVert 96 | } 97 | 98 | return ShrinkableHorz | GrowableHorz | GreedyHorz 99 | } 100 | 101 | func (li *splitterHandleLayoutItem) IdealSize() Size { 102 | var size Size 103 | dpi := int(win.GetDpiForWindow(li.handle)) 104 | 105 | if li.orientation == Horizontal { 106 | size.Width = IntFrom96DPI(li.handleWidth, dpi) 107 | } else { 108 | size.Height = IntFrom96DPI(li.handleWidth, dpi) 109 | } 110 | 111 | return size 112 | } 113 | 114 | func (li *splitterHandleLayoutItem) MinSize() Size { 115 | return li.IdealSize() 116 | } 117 | -------------------------------------------------------------------------------- /stringevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type stringEventHandlerInfo struct { 10 | handler StringEventHandler 11 | once bool 12 | } 13 | 14 | type StringEventHandler func(s string) 15 | 16 | type StringEvent struct { 17 | handlers []stringEventHandlerInfo 18 | } 19 | 20 | func (e *StringEvent) Attach(handler StringEventHandler) int { 21 | handlerInfo := stringEventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *StringEvent) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *StringEvent) Once(handler StringEventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type StringEventPublisher struct { 45 | event StringEvent 46 | } 47 | 48 | func (p *StringEventPublisher) Event() *StringEvent { 49 | return &p.event 50 | } 51 | 52 | func (p *StringEventPublisher) Publish(s string) { 53 | for i, h := range p.event.handlers { 54 | if h.handler != nil { 55 | h.handler(s) 56 | 57 | if h.once { 58 | p.event.Detach(i) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tabpage.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | ) 12 | 13 | const tabPageWindowClass = `\o/ Walk_TabPage_Class \o/` 14 | 15 | var tabPageBackgroundBrush Brush 16 | 17 | func init() { 18 | AppendToWalkInit(func() { 19 | MustRegisterWindowClass(tabPageWindowClass) 20 | 21 | tabPageBackgroundBrush, _ = NewSystemColorBrush(win.COLOR_WINDOW) 22 | }) 23 | } 24 | 25 | type TabPage struct { 26 | ContainerBase 27 | image Image 28 | title string 29 | tabWidget *TabWidget 30 | titleChangedPublisher EventPublisher 31 | imageChangedPublisher EventPublisher 32 | } 33 | 34 | func NewTabPage() (*TabPage, error) { 35 | tp := new(TabPage) 36 | 37 | if err := InitWindow( 38 | tp, 39 | nil, 40 | tabPageWindowClass, 41 | win.WS_POPUP, 42 | win.WS_EX_CONTROLPARENT); err != nil { 43 | return nil, err 44 | } 45 | 46 | tp.children = newWidgetList(tp) 47 | 48 | tp.MustRegisterProperty("Title", NewProperty( 49 | func() interface{} { 50 | return tp.Title() 51 | }, 52 | func(v interface{}) error { 53 | return tp.SetTitle(assertStringOr(v, "")) 54 | }, 55 | tp.titleChangedPublisher.Event())) 56 | 57 | tp.MustRegisterProperty("Image", NewProperty( 58 | func() interface{} { 59 | return tp.Image() 60 | }, 61 | func(v interface{}) error { 62 | img, err := ImageFrom(v) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | return tp.SetImage(img) 68 | }, 69 | tp.imageChangedPublisher.Event())) 70 | 71 | return tp, nil 72 | } 73 | 74 | func (tp *TabPage) Enabled() bool { 75 | if tp.tabWidget != nil { 76 | return tp.tabWidget.Enabled() && tp.enabled 77 | } 78 | 79 | return tp.enabled 80 | } 81 | 82 | func (tp *TabPage) Background() Brush { 83 | if tp.background != nil { 84 | return tp.background 85 | } else if tp.tabWidget != nil && tp.tabWidget.background == nullBrushSingleton { 86 | return nullBrushSingleton 87 | } 88 | 89 | if win.IsAppThemed() { 90 | return tabPageBackgroundBrush 91 | } 92 | 93 | return nil 94 | } 95 | 96 | func (tp *TabPage) Font() *Font { 97 | if tp.font != nil { 98 | return tp.font 99 | } else if tp.tabWidget != nil { 100 | return tp.tabWidget.Font() 101 | } 102 | 103 | return defaultFont 104 | } 105 | 106 | func (tp *TabPage) Image() Image { 107 | return tp.image 108 | } 109 | 110 | func (tp *TabPage) SetImage(value Image) error { 111 | tp.image = value 112 | 113 | if tp.tabWidget == nil { 114 | return nil 115 | } 116 | 117 | return tp.tabWidget.onPageChanged(tp) 118 | } 119 | 120 | func (tp *TabPage) Title() string { 121 | return tp.title 122 | } 123 | 124 | func (tp *TabPage) SetTitle(value string) error { 125 | tp.title = value 126 | 127 | tp.titleChangedPublisher.Publish() 128 | 129 | if tp.tabWidget == nil { 130 | return nil 131 | } 132 | 133 | return tp.tabWidget.onPageChanged(tp) 134 | } 135 | -------------------------------------------------------------------------------- /textlabel.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "sync" 11 | ) 12 | 13 | type TextLabel struct { 14 | static 15 | textChangedPublisher EventPublisher 16 | } 17 | 18 | func NewTextLabel(parent Container) (*TextLabel, error) { 19 | return NewTextLabelWithStyle(parent, 0) 20 | } 21 | 22 | func NewTextLabelWithStyle(parent Container, style uint32) (*TextLabel, error) { 23 | tl := new(TextLabel) 24 | 25 | if err := tl.init(tl, parent, style); err != nil { 26 | return nil, err 27 | } 28 | 29 | tl.textAlignment = AlignHNearVNear 30 | 31 | tl.MustRegisterProperty("Text", NewProperty( 32 | func() interface{} { 33 | return tl.Text() 34 | }, 35 | func(v interface{}) error { 36 | return tl.SetText(assertStringOr(v, "")) 37 | }, 38 | tl.textChangedPublisher.Event())) 39 | 40 | return tl, nil 41 | } 42 | 43 | func (tl *TextLabel) asStatic() *static { 44 | return &tl.static 45 | } 46 | 47 | func (tl *TextLabel) TextAlignment() Alignment2D { 48 | return tl.textAlignment 49 | } 50 | 51 | func (tl *TextLabel) SetTextAlignment(alignment Alignment2D) error { 52 | if alignment == AlignHVDefault { 53 | alignment = AlignHNearVNear 54 | } 55 | 56 | return tl.setTextAlignment(alignment) 57 | } 58 | 59 | func (tl *TextLabel) Text() string { 60 | return tl.text() 61 | } 62 | 63 | func (tl *TextLabel) SetText(text string) error { 64 | if changed, err := tl.setText(text); err != nil { 65 | return err 66 | } else if !changed { 67 | return nil 68 | } 69 | 70 | tl.textChangedPublisher.Publish() 71 | 72 | return nil 73 | } 74 | 75 | func (tl *TextLabel) CreateLayoutItem(ctx *LayoutContext) LayoutItem { 76 | return &textLabelLayoutItem{ 77 | width2Height: make(map[int]int), 78 | text: tl.Text(), 79 | font: tl.Font(), 80 | minWidth: tl.MinSizePixels().Width, 81 | } 82 | } 83 | 84 | type textLabelLayoutItem struct { 85 | LayoutItemBase 86 | mutex sync.Mutex 87 | width2Height map[int]int // in native pixels 88 | text string 89 | font *Font 90 | minWidth int // in native pixels 91 | } 92 | 93 | func (*textLabelLayoutItem) LayoutFlags() LayoutFlags { 94 | return GrowableHorz | GrowableVert 95 | } 96 | 97 | func (li *textLabelLayoutItem) IdealSize() Size { 98 | return li.MinSize() 99 | } 100 | 101 | func (li *textLabelLayoutItem) MinSize() Size { 102 | return calculateTextSize(li.text, li.font, li.ctx.dpi, li.minWidth, li.handle) 103 | } 104 | 105 | func (li *textLabelLayoutItem) HasHeightForWidth() bool { 106 | return true 107 | } 108 | 109 | func (li *textLabelLayoutItem) HeightForWidth(width int) int { 110 | li.mutex.Lock() 111 | defer li.mutex.Unlock() 112 | 113 | if height, ok := li.width2Height[width]; ok { 114 | return height 115 | } 116 | 117 | size := calculateTextSize(li.text, li.font, li.ctx.dpi, width, li.handle) 118 | 119 | li.width2Height[width] = size.Height 120 | 121 | return size.Height 122 | } 123 | -------------------------------------------------------------------------------- /toolbutton.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "github.com/lxn/win" 11 | ) 12 | 13 | type ToolButton struct { 14 | Button 15 | } 16 | 17 | func NewToolButton(parent Container) (*ToolButton, error) { 18 | tb := new(ToolButton) 19 | 20 | if err := InitWidget( 21 | tb, 22 | parent, 23 | "BUTTON", 24 | win.WS_TABSTOP|win.WS_VISIBLE|win.BS_BITMAP|win.BS_PUSHBUTTON, 25 | 0); err != nil { 26 | return nil, err 27 | } 28 | 29 | tb.Button.init() 30 | 31 | tb.GraphicsEffects().Add(InteractionEffect) 32 | tb.GraphicsEffects().Add(FocusEffect) 33 | 34 | return tb, nil 35 | } 36 | 37 | func (tb *ToolButton) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr { 38 | switch msg { 39 | case win.WM_GETDLGCODE: 40 | return win.DLGC_BUTTON 41 | } 42 | 43 | return tb.Button.WndProc(hwnd, msg, wParam, lParam) 44 | } 45 | 46 | func (tb *ToolButton) CreateLayoutItem(ctx *LayoutContext) LayoutItem { 47 | return &toolButtonLayoutItem{ 48 | idealSize: tb.dialogBaseUnitsToPixels(Size{16, 12}), 49 | } 50 | } 51 | 52 | type toolButtonLayoutItem struct { 53 | LayoutItemBase 54 | idealSize Size // in native pixels 55 | } 56 | 57 | func (*toolButtonLayoutItem) LayoutFlags() LayoutFlags { 58 | return 0 59 | } 60 | 61 | func (tb *toolButtonLayoutItem) IdealSize() Size { 62 | return tb.idealSize 63 | } 64 | 65 | func (tb *toolButtonLayoutItem) MinSize() Size { 66 | return tb.idealSize 67 | } 68 | -------------------------------------------------------------------------------- /treeitemevent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | type treeItemEventHandlerInfo struct { 10 | handler TreeItemEventHandler 11 | once bool 12 | } 13 | 14 | type TreeItemEventHandler func(item TreeItem) 15 | 16 | type TreeItemEvent struct { 17 | handlers []treeItemEventHandlerInfo 18 | } 19 | 20 | func (e *TreeItemEvent) Attach(handler TreeItemEventHandler) int { 21 | handlerInfo := treeItemEventHandlerInfo{handler, false} 22 | 23 | for i, h := range e.handlers { 24 | if h.handler == nil { 25 | e.handlers[i] = handlerInfo 26 | return i 27 | } 28 | } 29 | 30 | e.handlers = append(e.handlers, handlerInfo) 31 | 32 | return len(e.handlers) - 1 33 | } 34 | 35 | func (e *TreeItemEvent) Detach(handle int) { 36 | e.handlers[handle].handler = nil 37 | } 38 | 39 | func (e *TreeItemEvent) Once(handler TreeItemEventHandler) { 40 | i := e.Attach(handler) 41 | e.handlers[i].once = true 42 | } 43 | 44 | type TreeItemEventPublisher struct { 45 | event TreeItemEvent 46 | } 47 | 48 | func (p *TreeItemEventPublisher) Event() *TreeItemEvent { 49 | return &p.event 50 | } 51 | 52 | func (p *TreeItemEventPublisher) Publish(item TreeItem) { 53 | for i, h := range p.event.handlers { 54 | if h.handler != nil { 55 | h.handler(item) 56 | 57 | if h.once { 58 | p.event.Detach(i) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /walk.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Walk Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | package walk 8 | 9 | import ( 10 | "errors" 11 | ) 12 | 13 | var ( 14 | ErrInvalidType = errors.New("invalid type") 15 | ) 16 | 17 | func LogErrors() bool { 18 | return logErrors 19 | } 20 | 21 | func SetLogErrors(v bool) { 22 | logErrors = v 23 | } 24 | 25 | func PanicOnError() bool { 26 | return panicOnError 27 | } 28 | 29 | func SetPanicOnError(v bool) { 30 | panicOnError = v 31 | } 32 | 33 | func TranslationFunc() TranslationFunction { 34 | return translation 35 | } 36 | 37 | func SetTranslationFunc(f TranslationFunction) { 38 | translation = f 39 | } 40 | 41 | type TranslationFunction func(source string, context ...string) string 42 | 43 | var translation TranslationFunction 44 | 45 | func tr(source string, context ...string) string { 46 | if translation == nil { 47 | return source 48 | } 49 | 50 | return translation(source, context...) 51 | } 52 | 53 | type Disposable interface { 54 | Dispose() 55 | } 56 | 57 | type Disposables struct { 58 | items []Disposable 59 | done bool 60 | } 61 | 62 | func (d *Disposables) Add(item Disposable) { 63 | d.items = append(d.items, item) 64 | } 65 | 66 | func (d *Disposables) Spare() { 67 | d.done = true 68 | } 69 | 70 | func (d *Disposables) Treat() { 71 | if d.done { 72 | return 73 | } 74 | 75 | for _, item := range d.items { 76 | item.Dispose() 77 | } 78 | 79 | d.done = true 80 | } 81 | --------------------------------------------------------------------------------