<commit_before>// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package walk

import (
	"fmt"
	"math/big"
	"syscall"
	"time"
	"unsafe"
)

import . "github.com/lxn/go-winapi"

type ComboBox struct {
	WidgetBase
	bindingValueProvider         BindingValueProvider
	model                        ListModel
	providedModel                interface{}
	bindingMember                string
	displayMember                string
	format                       string
	precision                    int
	itemsResetHandlerHandle      int
	itemChangedHandlerHandle     int
	maxItemTextWidth             int
	prevCurIndex                 int
	selChangeIndex               int
	currentIndexChangedPublisher EventPublisher
	editOrigWndProcPtr           uintptr
}

var comboBoxEditWndProcPtr = syscall.NewCallback(comboBoxEditWndProc)

func comboBoxEditWndProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
	cb := (*ComboBox)(unsafe.Pointer(GetWindowLongPtr(hwnd, GWLP_USERDATA)))

	switch msg {
	case WM_GETDLGCODE:
		if root := rootWidget(cb); root != nil {
			if dlg, ok := root.(dialogish); ok {
				if dlg.DefaultButton() != nil {
					// If the ComboBox lives in a Dialog that has a
					// DefaultButton, we won't swallow the return key.
					break
				}
			}
		}

		if wParam == VK_RETURN {
			return DLGC_WANTALLKEYS
		}

	case WM_KEYDOWN:
		if wParam != VK_RETURN || 0 == cb.SendMessage(CB_GETDROPPEDSTATE, 0, 0) {
			cb.handleKeyDown(wParam, lParam)
		}

	case WM_KEYUP:
		if wParam != VK_RETURN || 0 == cb.SendMessage(CB_GETDROPPEDSTATE, 0, 0) {
			cb.handleKeyUp(wParam, lParam)
		}
	}

	return CallWindowProc(cb.editOrigWndProcPtr, hwnd, msg, wParam, lParam)
}

func NewComboBox(parent Container) (*ComboBox, error) {
	cb, err := newComboBoxWithStyle(parent, CBS_DROPDOWN)
	if err != nil {
		return nil, err
	}

	editHwnd := GetWindow(cb.hWnd, GW_CHILD)

	SetWindowLongPtr(editHwnd, GWLP_USERDATA, uintptr(unsafe.Pointer(cb)))
	cb.editOrigWndProcPtr = SetWindowLongPtr(editHwnd, GWLP_WNDPROC, comboBoxEditWndProcPtr)

	return cb, nil
}

func NewDropDownBox(parent Container) (*ComboBox, error) {
	return newComboBoxWithStyle(parent, CBS_DROPDOWNLIST)
}

func newComboBoxWithStyle(parent Container, style uint32) (*ComboBox, error) {
	cb := &ComboBox{prevCurIndex: -1, selChangeIndex: -1, precision: 2}

	if err := InitChildWidget(
		cb,
		parent,
		"COMBOBOX",
		WS_TABSTOP|WS_VISIBLE|WS_VSCROLL|style,
		0); err != nil {
		return nil, err
	}

	cb.MustRegisterProperty("CurrentIndex", NewProperty(
		func() interface{} {
			return cb.CurrentIndex()
		},
		func(v interface{}) error {
			return cb.SetCurrentIndex(v.(int))
		},
		cb.CurrentIndexChanged()))

	cb.MustRegisterProperty("Value", NewProperty(
		func() interface{} {
			if cb.Editable() {
				return cb.Text()
			}

			index := cb.CurrentIndex()

			if cb.bindingValueProvider == nil || index == -1 {
				return nil
			}

			return cb.bindingValueProvider.BindingValue(index)
		},
		func(v interface{}) error {
			if cb.Editable() {
				return cb.SetText(v.(string))
			}

			if cb.bindingValueProvider == nil {
				return newError("Data binding is only supported using a model that implements BindingValueProvider.")
			}

			index := -1
<commit_msg>ComboBox: Add Text property<commit_after>// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package walk

import (
	"fmt"
	"math/big"
	"syscall"
	"time"
	"unsafe"
)

import . "github.com/lxn/go-winapi"

type ComboBox struct {
	WidgetBase
	bindingValueProvider         BindingValueProvider
	model                        ListModel
	providedModel                interface{}
	bindingMember                string
	displayMember                string
	format                       string
	precision                    int
	itemsResetHandlerHandle      int
	itemChangedHandlerHandle     int
	maxItemTextWidth             int
	prevCurIndex                 int
	selChangeIndex               int
	currentIndexChangedPublisher EventPublisher
	editOrigWndProcPtr           uintptr
}

var comboBoxEditWndProcPtr = syscall.NewCallback(comboBoxEditWndProc)

func comboBoxEditWndProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
	cb := (*ComboBox)(unsafe.Pointer(GetWindowLongPtr(hwnd, GWLP_USERDATA)))

	switch msg {
	case WM_GETDLGCODE:
		if root := rootWidget(cb); root != nil {
			if dlg, ok := root.(dialogish); ok {
				if dlg.DefaultButton() != nil {
					// If the ComboBox lives in a Dialog that has a
					// DefaultButton, we won't swallow the return key.
					break
				}
			}
		}

		if wParam == VK_RETURN {
			return DLGC_WANTALLKEYS
		}

	case WM_KEYDOWN:
		if wParam != VK_RETURN || 0 == cb.SendMessage(CB_GETDROPPEDSTATE, 0, 0) {
			cb.handleKeyDown(wParam, lParam)
		}

	case WM_KEYUP:
		if wParam != VK_RETURN || 0 == cb.SendMessage(CB_GETDROPPEDSTATE, 0, 0) {
			cb.handleKeyUp(wParam, lParam)
		}
	}

	return CallWindowProc(cb.editOrigWndProcPtr, hwnd, msg, wParam, lParam)
}

func NewComboBox(parent Container) (*ComboBox, error) {
	cb, err := newComboBoxWithStyle(parent, CBS_DROPDOWN)
	if err != nil {
		return nil, err
	}

	editHwnd := GetWindow(cb.hWnd, GW_CHILD)

	SetWindowLongPtr(editHwnd, GWLP_USERDATA, uintptr(unsafe.Pointer(cb)))
	cb.editOrigWndProcPtr = SetWindowLongPtr(editHwnd, GWLP_WNDPROC, comboBoxEditWndProcPtr)

	return cb, nil
}

func NewDropDownBox(parent Container) (*ComboBox, error) {
	return newComboBoxWithStyle(parent, CBS_DROPDOWNLIST)
}

func newComboBoxWithStyle(parent Container, style uint32) (*ComboBox, error) {
	cb := &ComboBox{prevCurIndex: -1, selChangeIndex: -1, precision: 2}

	if err := InitChildWidget(
		cb,
		parent,
		"COMBOBOX",
		WS_TABSTOP|WS_VISIBLE|WS_VSCROLL|style,
		0); err != nil {
		return nil, err
	}

	cb.MustRegisterProperty("CurrentIndex", NewProperty(
		func() interface{} {
			return cb.CurrentIndex()
		},
		func(v interface{}) error {
			return cb.SetCurrentIndex(v.(int))
		},
		cb.CurrentIndexChanged()))

	cb.MustRegisterProperty("Text", NewProperty(
		func() interface{} {
			return cb.Text()
		},
		func(v interface{}) error {
			return cb.SetText(v.(string))
		},
		cb.CurrentIndexChanged()))

	cb.MustRegisterProperty("Value", NewProperty(
		func() interface{} {
			if cb.Editable() {
				return cb.Text()
			}

			index := cb.CurrentIndex()

			if cb.bindingValueProvider == nil || index == -1 {
				return nil
			}

			return cb.bindingValueProvider.BindingValue(index)
		},
		func(v interface{}) error {
			if cb.Editable() {
				return cb.SetText(v.(string))
			}

			if cb.bindingValueProvider == nil {
				return newError("Data binding is only supported using a model that implements BindingValueProvider.")
			}

			index := -1

{'fraction_non_alphanumeric': 0.10332264645875838, 'fraction_numerical': 0.005829204313611192, 'mean_word_length': 3.270690728064717, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7336105', 'n_tokens_mistral': 2552, 'n_tokens_neox': 2229, 'n_words': 557}