Merge pull request #1 from wxWidgets/master

Pull upstream branch
This commit is contained in:
Reece Wilson 2020-10-12 04:50:08 +01:00 committed by GitHub
commit d329a01a0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
116 changed files with 3905 additions and 729 deletions

View File

@ -41,3 +41,28 @@ jobs:
- name: Run codespell
run: |
CODESPELL=$HOME/.local/bin/codespell ./misc/scripts/spellcheck
check-whitespace:
runs-on: ubuntu-20.04
name: Check Whitespace
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Check for trailing whitespace and TABs
run: |
git fetch --depth=1 origin master
git -c core.whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol,tab-in-indent \
diff --check origin/master \
':!Makefile.in' \
':!config.guess' \
':!config.sub' \
':!configure' \
':!descrip.mms' \
':!install-sh' \
':!**/*akefile*' \
':!**/*.sln' \
':!**/*.vcproj' \
':!**/*.xpm'

View File

@ -949,8 +949,8 @@ MONODLL_CFLAGS = $(__monodll_PCH_INC) $(__INC_TIFF_BUILD_p) $(__INC_TIFF_p) \
-I$(top_srcdir)/src/stc/scintilla/include \
-I$(top_srcdir)/src/stc/scintilla/lexlib \
-I$(top_srcdir)/src/stc/scintilla/src -D__WX__ -DSCI_LEXER -DNO_CXX11_REGEX \
-DLINK_LEXERS -DwxUSE_BASE=1 -DWXMAKINGDLL $(__webviewdll_ext_dir_define_p) \
$(PIC_FLAG) $(WX_CFLAGS) $(CPPFLAGS) $(CFLAGS)
-DLINK_LEXERS -DwxUSE_BASE=1 -DWXMAKINGDLL $(PIC_FLAG) $(WX_CFLAGS) \
$(CPPFLAGS) $(CFLAGS)
MONODLL_CXXFLAGS = $(__monodll_PCH_INC) $(__INC_TIFF_BUILD_p) $(__INC_TIFF_p) \
$(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) $(__INC_REGEX_p) \
$(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
@ -959,8 +959,8 @@ MONODLL_CXXFLAGS = $(__monodll_PCH_INC) $(__INC_TIFF_BUILD_p) $(__INC_TIFF_p) \
-I$(top_srcdir)/src/stc/scintilla/include \
-I$(top_srcdir)/src/stc/scintilla/lexlib \
-I$(top_srcdir)/src/stc/scintilla/src -D__WX__ -DSCI_LEXER -DNO_CXX11_REGEX \
-DLINK_LEXERS -DwxUSE_BASE=1 -DWXMAKINGDLL $(__webviewdll_ext_dir_define_p) \
$(PIC_FLAG) $(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS)
-DLINK_LEXERS -DwxUSE_BASE=1 -DWXMAKINGDLL $(PIC_FLAG) $(WX_CXXFLAGS) \
$(CPPFLAGS) $(CXXFLAGS)
MONODLL_OBJCXXFLAGS = $(__monodll_PCH_INC) $(__INC_TIFF_BUILD_p) \
$(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \
$(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \
@ -969,8 +969,8 @@ MONODLL_OBJCXXFLAGS = $(__monodll_PCH_INC) $(__INC_TIFF_BUILD_p) \
-I$(top_srcdir)/src/stc/scintilla/include \
-I$(top_srcdir)/src/stc/scintilla/lexlib \
-I$(top_srcdir)/src/stc/scintilla/src -D__WX__ -DSCI_LEXER -DNO_CXX11_REGEX \
-DLINK_LEXERS -DwxUSE_BASE=1 -DWXMAKINGDLL $(__webviewdll_ext_dir_define_p) \
$(PIC_FLAG) $(CPPFLAGS) $(OBJCXXFLAGS)
-DLINK_LEXERS -DwxUSE_BASE=1 -DWXMAKINGDLL $(PIC_FLAG) $(CPPFLAGS) \
$(OBJCXXFLAGS)
MONODLL_OBJECTS = \
monodll_any.o \
monodll_appbase.o \
@ -1092,8 +1092,7 @@ MONOLIB_CFLAGS = $(__monolib_PCH_INC) $(__INC_TIFF_BUILD_p) $(__INC_TIFF_p) \
-I$(top_srcdir)/src/stc/scintilla/include \
-I$(top_srcdir)/src/stc/scintilla/lexlib \
-I$(top_srcdir)/src/stc/scintilla/src -D__WX__ -DSCI_LEXER -DNO_CXX11_REGEX \
-DLINK_LEXERS -DwxUSE_BASE=1 $(__webviewdll_ext_dir_define_p) $(WX_CFLAGS) \
$(CPPFLAGS) $(CFLAGS)
-DLINK_LEXERS -DwxUSE_BASE=1 $(WX_CFLAGS) $(CPPFLAGS) $(CFLAGS)
MONOLIB_CXXFLAGS = $(__monolib_PCH_INC) $(__INC_TIFF_BUILD_p) $(__INC_TIFF_p) \
$(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) $(__INC_REGEX_p) \
$(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
@ -1102,8 +1101,7 @@ MONOLIB_CXXFLAGS = $(__monolib_PCH_INC) $(__INC_TIFF_BUILD_p) $(__INC_TIFF_p) \
-I$(top_srcdir)/src/stc/scintilla/include \
-I$(top_srcdir)/src/stc/scintilla/lexlib \
-I$(top_srcdir)/src/stc/scintilla/src -D__WX__ -DSCI_LEXER -DNO_CXX11_REGEX \
-DLINK_LEXERS -DwxUSE_BASE=1 $(__webviewdll_ext_dir_define_p) \
$(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS)
-DLINK_LEXERS -DwxUSE_BASE=1 $(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS)
MONOLIB_OBJCXXFLAGS = $(__monolib_PCH_INC) $(__INC_TIFF_BUILD_p) \
$(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \
$(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \
@ -1112,8 +1110,7 @@ MONOLIB_OBJCXXFLAGS = $(__monolib_PCH_INC) $(__INC_TIFF_BUILD_p) \
-I$(top_srcdir)/src/stc/scintilla/include \
-I$(top_srcdir)/src/stc/scintilla/lexlib \
-I$(top_srcdir)/src/stc/scintilla/src -D__WX__ -DSCI_LEXER -DNO_CXX11_REGEX \
-DLINK_LEXERS -DwxUSE_BASE=1 $(__webviewdll_ext_dir_define_p) $(CPPFLAGS) \
$(OBJCXXFLAGS)
-DLINK_LEXERS -DwxUSE_BASE=1 $(CPPFLAGS) $(OBJCXXFLAGS)
MONOLIB_OBJECTS = \
monolib_any.o \
monolib_appbase.o \
@ -1669,16 +1666,15 @@ WEBVIEWDLL_CXXFLAGS = $(__webviewdll_PCH_INC) $(__INC_TIFF_BUILD_p) \
$(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \
$(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \
$(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) -DWXBUILDING -DWXUSINGDLL \
-DWXMAKINGDLL_WEBVIEW $(__webviewdll_ext_dir_define_p) \
$(__webview_additional_include_p) $(PIC_FLAG) $(WX_CXXFLAGS) $(CPPFLAGS) \
$(CXXFLAGS)
-DWXMAKINGDLL_WEBVIEW $(__webview_additional_include_p) $(PIC_FLAG) \
$(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS)
WEBVIEWDLL_OBJCXXFLAGS = $(__webviewdll_PCH_INC) $(__INC_TIFF_BUILD_p) \
$(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \
$(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \
$(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \
$(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) -DWXBUILDING -DWXUSINGDLL \
-DWXMAKINGDLL_WEBVIEW $(__webviewdll_ext_dir_define_p) \
$(__webview_additional_include_p) $(PIC_FLAG) $(CPPFLAGS) $(OBJCXXFLAGS)
-DWXMAKINGDLL_WEBVIEW $(__webview_additional_include_p) $(PIC_FLAG) \
$(CPPFLAGS) $(OBJCXXFLAGS)
WEBVIEWDLL_OBJECTS = \
$(__WEBVIEW_SRC_PLATFORM_OBJECTS_2) \
webviewdll_webview.o \
@ -1691,15 +1687,13 @@ WEBVIEWLIB_CXXFLAGS = $(__webviewlib_PCH_INC) $(__INC_TIFF_BUILD_p) \
$(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \
$(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \
$(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) -DWXBUILDING \
$(__webviewdll_ext_dir_define_p) $(__webview_additional_include_p) \
$(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS)
$(__webview_additional_include_p) $(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS)
WEBVIEWLIB_OBJCXXFLAGS = $(__webviewlib_PCH_INC) $(__INC_TIFF_BUILD_p) \
$(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \
$(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \
$(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \
$(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) -DWXBUILDING \
$(__webviewdll_ext_dir_define_p) $(__webview_additional_include_p) \
$(CPPFLAGS) $(OBJCXXFLAGS)
$(__webview_additional_include_p) $(CPPFLAGS) $(OBJCXXFLAGS)
WEBVIEWLIB_OBJECTS = \
$(__WEBVIEW_SRC_PLATFORM_OBJECTS_3) \
webviewlib_webview.o \
@ -13341,9 +13335,6 @@ COND_PLATFORM_MACOSX_1___OSX_LOWLEVEL_SRC_OBJECTS = \
monodll_core_timer.o \
monodll_utilsexc_cf.o
@COND_PLATFORM_MACOSX_1@__OSX_LOWLEVEL_SRC_OBJECTS = $(COND_PLATFORM_MACOSX_1___OSX_LOWLEVEL_SRC_OBJECTS)
COND_USE_WEBVIEW_WEBKIT2_1___webviewdll_ext_dir_define_p_0 = --define \
WX_WEB_EXTENSIONS_DIRECTORY=\"$(PLUGINS_INST_DIR)/web-extensions\"
@COND_USE_WEBVIEW_WEBKIT2_1@__webviewdll_ext_dir_define_p_0 = $(COND_USE_WEBVIEW_WEBKIT2_1___webviewdll_ext_dir_define_p_0)
@COND_PLATFORM_MACOSX_1@__PLATFORM_SRC_OBJECTS_0 = monolib_unix_apptraits.o
@COND_PLATFORM_UNIX_1@__PLATFORM_SRC_OBJECTS_0 = monolib_unix_apptraits.o
COND_PLATFORM_MACOSX_1___OSX_COMMON_SRC_OBJECTS_0 = \
@ -13758,9 +13749,6 @@ COND_PLATFORM_MACOSX_1___OSX_LOWLEVEL_SRC_OBJECTS_1_4 = \
corelib_core_timer.o \
corelib_utilsexc_cf.o
@COND_PLATFORM_MACOSX_1@__OSX_LOWLEVEL_SRC_OBJECTS_1_4 = $(COND_PLATFORM_MACOSX_1___OSX_LOWLEVEL_SRC_OBJECTS_1_4)
@COND_USE_WEBVIEW_WEBKIT2_1@__webviewdll_ext_dir_define_p \
@COND_USE_WEBVIEW_WEBKIT2_1@ = \
@COND_USE_WEBVIEW_WEBKIT2_1@ -DWX_WEB_EXTENSIONS_DIRECTORY=\"$(PLUGINS_INST_DIR)/web-extensions\"
@COND_TOOLKIT_MSW@__webview_additional_include_p = \
@COND_TOOLKIT_MSW@ -I$(top_srcdir)/3rdparty/webview2/build/native/include
@COND_MONOLITHIC_0_SHARED_1_USE_GUI_1_USE_HTML_1@__htmldll_library_link_DEP \
@ -20872,7 +20860,7 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP)
@COND_PLATFORM_MACOSX_1_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/html/chm.cpp
monodll_version_rc.o: $(srcdir)/src/msw/version.rc $(MONODLL_ODEP)
$(WINDRES) -i$< -o$@ $(__INC_TIFF_BUILD_p_54) $(__INC_TIFF_p_54) $(__INC_JPEG_p_54) $(__INC_PNG_p_53) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include --include-dir $(top_srcdir)/src/stc/scintilla/include --include-dir $(top_srcdir)/src/stc/scintilla/lexlib --include-dir $(top_srcdir)/src/stc/scintilla/src --define __WX__ --define SCI_LEXER --define NO_CXX11_REGEX --define LINK_LEXERS --define wxUSE_BASE=1 --define WXMAKINGDLL $(__webviewdll_ext_dir_define_p_0)
$(WINDRES) -i$< -o$@ $(__INC_TIFF_BUILD_p_54) $(__INC_TIFF_p_54) $(__INC_JPEG_p_54) $(__INC_PNG_p_53) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include --include-dir $(top_srcdir)/src/stc/scintilla/include --include-dir $(top_srcdir)/src/stc/scintilla/lexlib --include-dir $(top_srcdir)/src/stc/scintilla/src --define __WX__ --define SCI_LEXER --define NO_CXX11_REGEX --define LINK_LEXERS --define wxUSE_BASE=1 --define WXMAKINGDLL
monolib_any.o: $(srcdir)/src/common/any.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/any.cpp
@ -36010,7 +35998,7 @@ webviewdll_webviewfshandler.o: $(srcdir)/src/common/webviewfshandler.cpp $(WEBVI
$(CXXC) -c -o $@ $(WEBVIEWDLL_CXXFLAGS) $(srcdir)/src/common/webviewfshandler.cpp
webviewdll_version_rc.o: $(srcdir)/src/msw/version.rc $(WEBVIEWDLL_ODEP)
$(WINDRES) -i$< -o$@ $(__INC_TIFF_BUILD_p_54) $(__INC_TIFF_p_54) $(__INC_JPEG_p_54) $(__INC_PNG_p_53) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_webview$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include --define WXUSINGDLL --define WXMAKINGDLL_WEBVIEW $(__webviewdll_ext_dir_define_p_0) $(__webview_additional_include_p_1)
$(WINDRES) -i$< -o$@ $(__INC_TIFF_BUILD_p_54) $(__INC_TIFF_p_54) $(__INC_JPEG_p_54) $(__INC_PNG_p_53) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_webview$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include --define WXUSINGDLL --define WXMAKINGDLL_WEBVIEW $(__webview_additional_include_p_1)
webviewlib_webview_ie.o: $(srcdir)/src/msw/webview_ie.cpp $(WEBVIEWLIB_ODEP)
$(CXXC) -c -o $@ $(WEBVIEWLIB_CXXFLAGS) $(srcdir)/src/msw/webview_ie.cpp

View File

@ -12,6 +12,7 @@ skip_commits:
- misc/
- include/wx/osx/
- src/osx/
- .github/workflows/
- .travis.yml
- build/tools/travis-ci.sh
- build/tools/before_install.sh

View File

@ -980,7 +980,7 @@ dnl ### begin block 20_COND_USE_THREADS_1[../../demos/bombs/bombs.bkl,../../demo
COND_USE_THREADS_1=""
fi
AC_SUBST(COND_USE_THREADS_1)
dnl ### begin block 20_COND_USE_WEBVIEW_WEBKIT2_1[../../demos/bombs/bombs.bkl,../../demos/forty/forty.bkl,../../demos/fractal/fractal.bkl,../../demos/life/life.bkl,../../demos/poem/poem.bkl,../../samples/access/access.bkl,../../samples/animate/anitest.bkl,../../samples/archive/archive.bkl,../../samples/artprov/artprov.bkl,../../samples/aui/auidemo.bkl,../../samples/calendar/calendar.bkl,../../samples/caret/caret.bkl,../../samples/clipboard/clipboard.bkl,../../samples/collpane/collpane.bkl,../../samples/combo/combo.bkl,../../samples/config/config.bkl,../../samples/console/console.bkl,../../samples/dataview/dataview.bkl,../../samples/debugrpt/debugrpt.bkl,../../samples/dialogs/dialogs.bkl,../../samples/dialup/dialup.bkl,../../samples/display/display.bkl,../../samples/dll/dll.bkl,../../samples/dnd/dnd.bkl,../../samples/docview/docview.bkl,../../samples/dragimag/dragimag.bkl,../../samples/drawing/drawing.bkl,../../samples/erase/erase.bkl,../../samples/event/event.bkl,../../samples/except/except.bkl,../../samples/exec/exec.bkl,../../samples/font/font.bkl,../../samples/fswatcher/fswatcher.bkl,../../samples/grid/grid.bkl,../../samples/help/help.bkl,../../samples/htlbox/htlbox.bkl,../../samples/html/about/about.bkl,../../samples/html/help/help.bkl,../../samples/html/helpview/helpview.bkl,../../samples/html/htmlctrl/htmlctrl.bkl,../../samples/html/printing/printing.bkl,../../samples/html/test/test.bkl,../../samples/html/virtual/virtual.bkl,../../samples/html/widget/widget.bkl,../../samples/html/zip/zip.bkl,../../samples/image/image.bkl,../../samples/internat/internat.bkl,../../samples/ipc/ipc.bkl,../../samples/joytest/joytest.bkl,../../samples/keyboard/keyboard.bkl,../../samples/layout/layout.bkl,../../samples/listctrl/listctrl.bkl,../../samples/mdi/mdi.bkl,../../samples/mediaplayer/mediaplayer.bkl,../../samples/memcheck/memcheck.bkl,../../samples/menu/menu.bkl,../../samples/minimal/minimal.bkl,../../samples/nativdlg/nativdlg.bkl,../../samples/notebook/notebook.bkl,../../samples/oleauto/oleauto.bkl,../../samples/opengl/cube/cube.bkl,../../samples/opengl/isosurf/isosurf.bkl,../../samples/opengl/penguin/penguin.bkl,../../samples/opengl/pyramid/pyramid.bkl,../../samples/ownerdrw/ownerdrw.bkl,../../samples/popup/popup.bkl,../../samples/power/power.bkl,../../samples/preferences/preferences.bkl,../../samples/printing/printing.bkl,../../samples/propgrid/propgrid.bkl,../../samples/regtest/regtest.bkl,../../samples/render/render.bkl,../../samples/ribbon/ribbon.bkl,../../samples/richtext/richtext.bkl,../../samples/sashtest/sashtest.bkl,../../samples/scroll/scroll.bkl,../../samples/secretstore/secretstore.bkl,../../samples/shaped/shaped.bkl,../../samples/sockets/sockets.bkl,../../samples/sound/sound.bkl,../../samples/splash/splash.bkl,../../samples/splitter/splitter.bkl,../../samples/statbar/statbar.bkl,../../samples/stc/stctest.bkl,../../samples/svg/svgtest.bkl,../../samples/taborder/taborder.bkl,../../samples/taskbar/taskbar.bkl,../../samples/taskbarbutton/taskbarbutton.bkl,../../samples/text/text.bkl,../../samples/thread/thread.bkl,../../samples/toolbar/toolbar.bkl,../../samples/treectrl/treectrl.bkl,../../samples/treelist/treelist.bkl,../../samples/typetest/typetest.bkl,../../samples/uiaction/uiaction.bkl,../../samples/validate/validate.bkl,../../samples/vscroll/vscroll.bkl,../../samples/webview/webview.bkl,../../samples/widgets/widgets.bkl,../../samples/wizard/wizard.bkl,../../samples/wrapsizer/wrapsizer.bkl,../../samples/xrc/xrcdemo.bkl,../../samples/xti/xti.bkl,../../tests/benchmarks/bench.bkl,../../tests/test.bkl,../../utils/emulator/src/emulator.bkl,../../utils/execmon/execmon.bkl,../../utils/helpview/src/helpview.bkl,../../utils/hhp2cached/hhp2cached.bkl,../../utils/ifacecheck/src/ifacecheck.bkl,../../utils/screenshotgen/src/screenshotgen.bkl,../../utils/wxrc/wxrc.bkl,wx.bkl] ###
dnl ### begin block 20_COND_USE_WEBVIEW_WEBKIT2_1[wx.bkl] ###
COND_USE_WEBVIEW_WEBKIT2_1="#"
if test "x$USE_WEBVIEW_WEBKIT2" = "x1" ; then
COND_USE_WEBVIEW_WEBKIT2_1=""

View File

@ -56,7 +56,6 @@ ACLOCAL_SOURCES = \
build/aclocal/ax_func_which_gethostbyname_r.m4 \
build/aclocal/bakefile-lang.m4 \
build/aclocal/bakefile.m4 \
build/aclocal/cppunit.m4 \
build/aclocal/gst-element-check.m4 \
build/aclocal/gtk-2.0.m4 \
build/aclocal/gtk.m4 \

View File

@ -897,9 +897,4 @@ $(TAB)cl /EP /nologo "$(DOLLAR)(InputPath)" > "$(SETUPHDIR)\wx\msw\rcdefs.h"
<set var="VARS_DONT_ELIMINATE" append="1">top_srcdir</set>
<set var="webviewdll_ext_dir_define">
<if cond="FORMAT=='autoconf' and USE_WEBVIEW_WEBKIT2=='1'">WX_WEB_EXTENSIONS_DIRECTORY=\"$(PLUGINS_INST_DIR)/web-extensions\"</if>
</set>
</makefile>

View File

@ -28,7 +28,6 @@
<dll id="monodll" template="wx_dll,wx_monolib_or_dll"
cond="SHARED=='1' and MONOLITHIC=='1'">
<define>WXMAKINGDLL</define>
<define>$(webviewdll_ext_dir_define)</define>
<ldlibs>$(EXTRALIBS_XML)</ldlibs>
<ldlibs>$(EXTRALIBS_HTML)</ldlibs>
<ldlibs>$(EXTRALIBS_MEDIA)</ldlibs>
@ -40,7 +39,6 @@
<lib id="monolib" template="wx_lib,wx_monolib_or_dll"
cond="SHARED=='0' and MONOLITHIC=='1'">
<define>$(webviewdll_ext_dir_define)</define>
<if cond="FORMAT=='watcom'">
<set var="LIB_PAGESIZE" overwrite="1">8192</set>
</if>

View File

@ -184,7 +184,6 @@
cond="SHARED=='1' and USE_GUI=='1' and USE_WEBVIEW=='1' and MONOLITHIC=='0'">
<define>WXUSINGDLL</define>
<define>WXMAKINGDLL_WEBVIEW</define>
<define>$(webviewdll_ext_dir_define)</define>
<sources>$(WEBVIEW_SRC)</sources>
<library>coredll</library>
<library>basedll</library>
@ -195,7 +194,6 @@
<lib id="webviewlib" template="wx_lib"
cond="SHARED=='0' and USE_GUI=='1' and USE_WEBVIEW=='1' and MONOLITHIC=='0'">
<define>$(webviewdll_ext_dir_define)</define>
<sources>$(WEBVIEW_SRC)</sources>
<msvc-headers>$(WEBVIEW_HDR)</msvc-headers>
<include>$(webview_additional_include)</include>

View File

@ -33,7 +33,12 @@ macro(wx_get_dependencies var lib)
get_target_property(deps wx${lib} LINK_LIBRARIES)
foreach(dep IN LISTS deps)
if(TARGET ${dep})
get_target_property(dep_name ${dep} OUTPUT_NAME)
get_target_property(dep_type ${dep} TYPE)
if (dep_type STREQUAL "INTERFACE_LIBRARY")
get_target_property(dep_name ${dep} INTERFACE_OUTPUT_NAME)
else()
get_target_property(dep_name ${dep} OUTPUT_NAME)
endif()
set(dep_name "-l${dep_name}")
else()
get_filename_component(dep_name ${dep} NAME)

View File

@ -26,10 +26,11 @@ endif()
wx_add_library(wxwebview ${WEBVIEW_FILES})
if(WXGTK AND wxUSE_WEBVIEW_WEBKIT2)
set(WX_WEB_EXTENSIONS_DIRECTORY "lib/wx/${wxMAJOR_VERSION}.${wxMINOR_VERSION}/web-extensions")
wx_lib_compile_definitions(wxwebview PRIVATE
-DWX_WEB_EXTENSIONS_DIRECTORY="${CMAKE_INSTALL_PREFIX}/${WX_WEB_EXTENSIONS_DIRECTORY}"
)
if(wxVERSION_IS_DEV)
set(WX_WEB_EXTENSIONS_DIRECTORY "lib/wx/${wxMAJOR_VERSION}.${wxMINOR_VERSION}.${wxRELEASE_NUMBER}/web-extensions")
else()
set(WX_WEB_EXTENSIONS_DIRECTORY "lib/wx/${wxMAJOR_VERSION}.${wxMINOR_VERSION}/web-extensions")
endif()
endif()
if(APPLE)

View File

@ -22,9 +22,11 @@ set(TEST_GUI_SRC
graphics/affinematrix.cpp
graphics/boundingbox.cpp
graphics/clippingbox.cpp
graphics/coords.cpp
graphics/graphmatrix.cpp
graphics/graphpath.cpp
config/config.cpp
controls/auitest.cpp
controls/bitmapcomboboxtest.cpp
controls/bitmaptogglebuttontest.cpp
controls/bookctrlbasetest.cpp
@ -102,11 +104,13 @@ set(TEST_GUI_SRC
net/socket.cpp
persistence/tlw.cpp
persistence/dataview.cpp
rowheightcache/rowheightcachetest.cpp
sizers/boxsizer.cpp
sizers/gridsizer.cpp
sizers/wrapsizer.cpp
toplevel/toplevel.cpp
validators/valnum.cpp
validators/valtext.cpp
window/clientsize.cpp
window/setsize.cpp
xml/xrctest.cpp
@ -169,6 +173,9 @@ wx_add_test(test_gui ${TEST_GUI_SRC}
RES ../samples/sample.rc
)
wx_exe_link_libraries(test_gui wxcore)
if(wxUSE_AUI)
wx_exe_link_libraries(test_gui wxaui)
endif()
if(wxUSE_RICHTEXT)
wx_exe_link_libraries(test_gui wxrichtext)
endif()

View File

@ -105,6 +105,8 @@ Changes in behaviour not resulting in compilation errors
- wxFileDialog::GetPath() and wxFileDialog::GetFilename() now assert and return
an empty string if called on dialogs with the wxFD_MULTIPLE style.
- wxGetInstallPrefix() now returns wxString.
Changes in behaviour which may result in build errors
-----------------------------------------------------

View File

@ -384,6 +384,7 @@ GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
TOC_INCLUDE_HEADINGS = 3
#---------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -99,5 +99,6 @@ topics related to building applications with wxWidgets.
@li @subpage overview_windowdeletion
@li @subpage overview_envvars
@li @subpage overview_customwidgets
@li @subpage overview_high_dpi
*/

View File

@ -0,0 +1,149 @@
High DPI Support in wxWidgets {#overview_high_dpi}
=============================
[TOC]
Introduction
============
Many modern displays have way more pixels on the same surface than used to be
the norm, resulting in much higher values of DPI (dots, i.e. pixels, per inch)
than the traditionally used values. This allows to render texts, or geometric
shapes in general much more smoothly.
As an illustration here are two scaled up views of the same text in 11 pt
Helvetica using up the same space on screen. First on an original Mac display
at 72 dpi, then on a High DPI Display, called "Retina" by Apple with twice as
many pixels in both dimensions (144 dpi), thus 4 times the number of pixels on
the same surface. Using these the contours are much more detailed.
![11 pt Helvetica at 72 DPI](overview_highdpi_text_72.png)
![11 pt Helvetica at 144 DPI](overview_highdpi_text_144.png)
To the user the DPI is typically expressed using a scaling factor, by which the
baseline DPI value is multiplied. For example, MSW systems may use 125% or 150%
scaling, meaning that they use DPI of 120 or 144 respectively, as baseline DPI
value is 96. Similarly, Linux systems may use "2x" scaling, resulting in DPI
value of 192. Macs are slightly different, as even they also may use "2x"
scaling, as in the example above, the effective DPI corresponding to it is 144,
as the baseline value on this platform is 72.
The Problem with High DPI Displays
----------------------------------
If high DPI displays were treated in the same way as normal ones, existing
applications would look tiny of them. For example, a square window 500 pixels
in size would take half of a standard 1920×1080 ("Full HD") display vertically,
but only a quarter on a 3840×2160 ("4K UHD") display. To prevent this from
happening, most platforms automatically scale the windows by the scaling
factor, defined above, when displaying them on high DPI displays. In this
example, scaling factor is 2 and so the actual size of the window on screen
would become 1000 when automatic scaling is in effect.
Automatic scaling is convenient, but doesn't really allow the application to
use the extra pixels available on the display. Visually, this means that the
scaled application appears blurry, in contrast to sharper applications using
the full display resolution, so a better solution for interpreting pixel values
on high DPI displays is needed: one which allows to scale some pixel values
(e.g. the total window size), but not some other ones (e.g. those used for
drawing, which should remain unscaled to use the full available resolution).
Pixel Values in wxWidgets
=========================
Logical and Device-Independent Pixels
-------------------------------------
Some systems like eg Apple's OSes automatically scale all the coordinates by
the DPI scaling factor, however not all systems supported by wxWidgets do it --
notably, MSW does not. This means that **logical pixels**, in which all
coordinates and sizes are expressed in wxWidgets API, do _not_ have the same
meaning on all platforms when using high DPI displays. So while on macOS you
can always pass in a size of (500,500) to create the window from the previous
paragraph, whatever the resolution of the display is, you would have to
increase this to (1000,1000) on MSW when working on a 200% display. To hide
this difference from the application, wxWidgets provides **device-independent
pixels**, abbreviated as "DIP", that are always of the same size on all
displays and all platforms.
Thus, the first thing do when preparing your application for high DPI support
is to stop using raw pixel values. Actually, using any pixel values is not
recommended and replacing them with the values based on the text metrics, i.e.
obtained using wxWindow::GetTextExtent(), or expressing them in dialog units
(see wxWindow::ConvertDialogToPixels()) is preferable. However the simplest
change is to just replace the pixel values with the values in DIP: for this,
just use wxWindow::FromDIP() to convert from one to the other.
For example, if you have the existing code:
```cpp
myFrame->SetClientSize(wxSize(400, 300));
```
you can just replace it with
```cpp
myFrame->SetClientSize(myFrame->FromDIP(wxSize(400, 300)));
```
Physical Pixels
---------------
In addition to (logical) pixels and DIPs discussed above, you may also need to
work in physical pixel coordinates, corresponding to the actual display pixels.
Physical pixels are never scaled, on any platform, and must be used when
drawing graphics elements to ensure that the best possible resolution is used.
For example, all operations on wxGLCanvas use physical pixels.
To convert between logical and physical pixels, you can use
wxWindow::GetContentScaleFactor(): this is a value greater than or equal to 1,
so a value in logical pixels needs to be multiplied by it in order to obtain
the value in physical pixels.
For example, in a wxGLCanvas created with the size of 100 (logical) pixels, the
rightmost physical pixel coordinate will be `100*GetContentScaleFactor()`.
High-Resolution Images and Artwork
==================================
In order to benefit from the increased detail on High DPI devices you might want
to provide the images or artwork your application uses in higher resolutions as
well. Note that it is not recommended to just provide a high-resolution version
and let the system scale that down on 1x displays. Apart from performance
consideration also the quality might suffer, contours become more blurry.
You can use vector based graphics like SVG or you can add the same image at different
sizes / resolutions.
[comment]: # (TODO: API and Use Cases)
Platform-Specific Build Issues
==============================
Generally speaking, all systems handle applications not specifically marked as
being "DPI-aware" by emulating low-resolution display for them and scaling them
up, resulting in blurry graphics and fonts, but globally preserving the
application appearance. For the best results, the application needs to be
explicitly marked as DPI-aware in a platform-dependent way.
MSW
---
The behaviour of the application when running on a high-DPI display depends on
the values in its [manifest][1]. If your application include `wx/msw/wx.rc`
from its resource file, you need to predefine `wxUSE_DPI_AWARE_MANIFEST` to
opt-in into [high DPI support][2]: define it as `1` for minimal DPI awareness and
`2` for full, per-monitor DPI awareness supported by Windows 10 version 1703 or
later.
[1]: https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests
[2]: https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
macOS
-----
DPI-aware applications must set their `NSPrincipalClass` to `wxNSApplication`
(or at least `NSApplication`) in their `Info.plist` file. Also see Apple [high
resolution guidelines][2] for more information.
[2]: https://developer.apple.com/library/archive/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html

View File

@ -153,6 +153,7 @@ protected:
m_window = window;
m_width = width;
m_height = height;
DoSize();
return true;
}

View File

@ -78,6 +78,8 @@ public:
virtual size_t GetMBNulLen() const wxOVERRIDE { return m_conv->GetMBNulLen(); }
virtual bool IsUTF8() const wxOVERRIDE { return m_conv && m_conv->IsUTF8(); }
virtual wxMBConv *Clone() const wxOVERRIDE { return new wxConvAuto(*this); }
// return the BOM type of this buffer
@ -91,6 +93,14 @@ public:
return m_bomType;
}
wxFontEncoding GetEncoding() const;
// Return true if the fall-back encoding is used
bool IsUsingFallbackEncoding() const
{
return m_ownsConv && m_bomType == wxBOM_None;
}
private:
// common part of all ctors
void Init()

View File

@ -325,6 +325,8 @@ public:
// coordinates conversions and transforms
virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const;
virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const;
virtual wxSize DeviceToLogicalRel(int x, int y) const;
virtual wxSize LogicalToDeviceRel(int x, int y) const;
// bounding box
@ -1012,6 +1014,14 @@ public:
{ return m_pimpl->DeviceToLogicalXRel(x); }
wxCoord DeviceToLogicalYRel(wxCoord y) const
{ return m_pimpl->DeviceToLogicalYRel(y); }
wxPoint DeviceToLogical(const wxPoint& pt) const
{ return m_pimpl->DeviceToLogical(pt.x, pt.y); }
wxPoint DeviceToLogical(wxCoord x, wxCoord y) const
{ return m_pimpl->DeviceToLogical(x, y); }
wxSize DeviceToLogicalRel(const wxSize& dim) const
{ return m_pimpl->DeviceToLogicalRel(dim.x, dim.y); }
wxSize DeviceToLogicalRel(int x, int y) const
{ return m_pimpl->DeviceToLogicalRel(x, y); }
wxCoord LogicalToDeviceX(wxCoord x) const
{ return m_pimpl->LogicalToDeviceX(x); }
wxCoord LogicalToDeviceY(wxCoord y) const
@ -1020,6 +1030,14 @@ public:
{ return m_pimpl->LogicalToDeviceXRel(x); }
wxCoord LogicalToDeviceYRel(wxCoord y) const
{ return m_pimpl->LogicalToDeviceYRel(y); }
wxPoint LogicalToDevice(const wxPoint& pt) const
{ return m_pimpl->LogicalToDevice(pt.x, pt.y); }
wxPoint LogicalToDevice(wxCoord x, wxCoord y) const
{ return m_pimpl->LogicalToDevice(x, y); }
wxSize LogicalToDeviceRel(const wxSize& dim) const
{ return m_pimpl->LogicalToDeviceRel(dim.x, dim.y); }
wxSize LogicalToDeviceRel(int x, int y) const
{ return m_pimpl->LogicalToDeviceRel(x, y); }
void SetMapMode(wxMappingMode mode)
{ m_pimpl->SetMapMode(mode); }

View File

@ -124,6 +124,8 @@ public:
// coordinates conversions and transforms
virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const wxOVERRIDE;
virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const wxOVERRIDE;
virtual wxSize DeviceToLogicalRel(int x, int y) const wxOVERRIDE;
virtual wxSize LogicalToDeviceRel(int x, int y) const wxOVERRIDE;
// the true implementations
virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,

View File

@ -84,6 +84,8 @@ public:
virtual ~wxBitmapComboBox();
virtual wxString GetStringSelection() const wxOVERRIDE;
// Adds item with image to the end of the combo box.
int Append(const wxString& item, const wxBitmap& bitmap = wxNullBitmap);
int Append(const wxString& item, const wxBitmap& bitmap, void *clientData);

View File

@ -519,14 +519,26 @@ public:
// all these functions only do something if the line is currently visible
// Make sure that _line_ is the only item highlighted in the control.
// _oldLine_ is the old focused item.
void HighlightOnly( size_t line, size_t oldLine = (size_t)-1 );
// In multiple selection mode, instead of sending one notification per item
// (which is too slow if a lot of items are selected) we send only one notification
// for all of them which is the wxMSW behaviour. Currently done for virtual
// list controls and for deselection only.
enum SendEvent { SendEvent_None, SendEvent_Normal };
// change the line "selected" state, return true if it really changed
bool HighlightLine( size_t line, bool highlight = true);
bool HighlightLine( size_t line, bool highlight = true,
SendEvent sendEvent = SendEvent_Normal );
// as HighlightLine() but do it for the range of lines: this is incredibly
// more efficient for virtual list controls!
//
// NB: unlike HighlightLine() this one does refresh the lines on screen
void HighlightLines( size_t lineFrom, size_t lineTo, bool on = true );
void HighlightLines( size_t lineFrom, size_t lineTo, bool on = true,
SendEvent sendEvent = SendEvent_Normal );
// toggle the line state and refresh it
void ReverseHighlight( size_t line )
@ -753,6 +765,16 @@ public:
return m_hasFocus;
}
void UpdateSelectionCount(bool selected)
{
wxASSERT_MSG( !IsVirtual(), "Can be called for non virtual lists only" );
if ( IsSingleSel() )
return;
selected ? ++m_selCount : --m_selCount;
}
protected:
// the array of all line objects for a non virtual list control (for the
// virtual list control we only ever use m_lines[0])
@ -803,11 +825,18 @@ protected:
m_lineBeforeLastClicked,
m_lineSelectSingleOnUp;
// Multiple selection extends from the anchor. Not used in single-selection mode.
size_t m_anchor;
bool m_hasCheckBoxes;
protected:
wxWindow *GetMainWindowOfCompositeControl() wxOVERRIDE { return GetParent(); }
// the total count of items selected in a non virtual list control with
// multiple selections (always 0 otherwise)
size_t m_selCount;
// the total count of items in a virtual list control
size_t m_countVirt;
@ -858,6 +887,24 @@ private:
// initialize the current item if needed
void UpdateCurrent();
// change the current (== focused) item, without sending any event
// return true if m_current really changed.
bool ChangeCurrentWithoutEvent(size_t current);
// Trying to activate the current item from keyboard is only possible
// if it is actually selected. We don't send wxEVT_LIST_ITEM_ACTIVATED
// event if it is not, and wxEVT_LIST_KEY_DOWN event should carry -1
// in this case, as the wxMSW implementation does.
bool ShouldSendEventForCurrent() const
{
return HasCurrent() && IsHighlighted(m_current);
}
// For multiple selection mode.
// Change the selected range from [anchor, oldCurrent] to [anchor, newCurrent]
// without generating unnecessary wxEVT_LIST_ITEM_{DE}SELECTED events.
void ExtendSelection(size_t oldCurrent, size_t newCurrent);
// delete all items but don't refresh: called from dtor
void DoDeleteAllItems();

View File

@ -13,7 +13,7 @@
// wxRadioButton
//-----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxRadioButton: public wxControl
class WXDLLIMPEXP_CORE wxRadioButton: public wxRadioButtonBase
{
public:
wxRadioButton() { }
@ -39,8 +39,8 @@ public:
const wxString& name = wxASCII_STR(wxRadioButtonNameStr) );
virtual void SetLabel(const wxString& label) wxOVERRIDE;
virtual void SetValue(bool val);
virtual bool GetValue() const;
virtual void SetValue(bool val) wxOVERRIDE;
virtual bool GetValue() const wxOVERRIDE;
static wxVisualAttributes
GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);

View File

@ -143,6 +143,7 @@ public:
GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
void GTKOnTextChanged() wxOVERRIDE;
void GTKAfterLayout();
protected:
// overridden wxWindow virtual methods
@ -216,8 +217,9 @@ private:
// a dummy one when frozen
GtkTextBuffer *m_buffer;
GtkTextMark* m_showPositionOnThaw;
GtkTextMark* m_showPositionDefer;
GSList* m_anonymousMarkList;
unsigned m_afterLayoutId;
// For wxTE_AUTO_URL
void OnUrlMouseEvent(wxMouseEvent&);

View File

@ -162,6 +162,7 @@ private:
#if wxUSE_WEBVIEW_WEBKIT2
bool CanExecuteEditingCommand(const gchar* command) const;
void SetupWebExtensionServer();
GDBusProxy *GetExtensionProxy() const;
bool RunScriptSync(const wxString& javascript, wxString* output = NULL);
#endif

View File

@ -13,7 +13,7 @@
// wxRadioButton
//-----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxRadioButton: public wxControl
class WXDLLIMPEXP_CORE wxRadioButton: public wxRadioButtonBase
{
public:
wxRadioButton() { }

View File

@ -80,7 +80,7 @@ class WXDLLIMPEXP_HTML wxHtmlHelpWindow : public wxWindow
public:
wxHtmlHelpWindow(wxHtmlHelpData* data = NULL) { Init(data); }
wxHtmlHelpWindow(wxWindow* parent, wxWindowID wxWindowID,
wxHtmlHelpWindow(wxWindow* parent, wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
int style = wxTAB_TRAVERSAL|wxNO_BORDER,

View File

@ -73,6 +73,16 @@ enum wxImageResizeQuality
wxIMAGE_QUALITY_HIGH = 4
};
// Constants for wxImage::Paste() for specifying alpha blending option.
enum wxImageAlphaBlendMode
{
// Overwrite the original alpha values with the ones being pasted.
wxIMAGE_ALPHA_BLEND_OVER = 0,
// Compose the original alpha values with the ones being pasted.
wxIMAGE_ALPHA_BLEND_COMPOSE = 1
};
// alpha channel values: fully transparent, default threshold separating
// transparent pixels from opaque for a few functions dealing with alpha and
// fully opaque
@ -348,9 +358,12 @@ public:
wxImage Size( const wxSize& size, const wxPoint& pos,
int r = -1, int g = -1, int b = -1 ) const;
// pastes image into this instance and takes care of
// the mask colour and out of bounds problems
void Paste( const wxImage &image, int x, int y );
// Copy the data of the given image to the specified position of this one
// taking care of the out of bounds problems. Mask is respected, but alpha
// is simply replaced by default, use wxIMAGE_ALPHA_BLEND_COMPOSE to
// combine it with the original image alpha values if needed.
void Paste(const wxImage& image, int x, int y,
wxImageAlphaBlendMode alphaBlend = wxIMAGE_ALPHA_BLEND_OVER);
// return the new image with size width*height
wxImage Scale( int width, int height,

View File

@ -68,7 +68,7 @@
wxASSERT_MSG(x > (double)INT_MIN - 0.5 && x < (double)INT_MAX + 0.5,
wxT("argument out of supported range"));
return std::lround(x);
return (int)std::lround(x);
}
#else /* C++98 */

View File

@ -11,7 +11,7 @@
#ifndef _WX_RADIOBUT_H_
#define _WX_RADIOBUT_H_
class WXDLLIMPEXP_CORE wxRadioButton: public wxControl
class WXDLLIMPEXP_CORE wxRadioButton: public wxRadioButtonBase
{
wxDECLARE_DYNAMIC_CLASS(wxRadioButton);
public:

View File

@ -88,6 +88,8 @@ public:
virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const wxOVERRIDE;
virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const wxOVERRIDE;
virtual wxSize DeviceToLogicalRel(int x, int y) const wxOVERRIDE;
virtual wxSize LogicalToDeviceRel(int x, int y) const wxOVERRIDE;
#if wxUSE_DC_TRANSFORM_MATRIX
virtual bool CanUseTransformMatrix() const wxOVERRIDE;

View File

@ -13,7 +13,7 @@
#include "wx/msw/ownerdrawnbutton.h"
class WXDLLIMPEXP_CORE wxRadioButton : public wxMSWOwnerDrawnButton<wxControl>
class WXDLLIMPEXP_CORE wxRadioButton : public wxMSWOwnerDrawnButton<wxRadioButtonBase>
{
public:
// ctors and creation functions
@ -43,8 +43,8 @@ public:
const wxString& name = wxASCII_STR(wxRadioButtonNameStr));
// implement the radio button interface
virtual void SetValue(bool value);
virtual bool GetValue() const;
virtual void SetValue(bool value) wxOVERRIDE;
virtual bool GetValue() const wxOVERRIDE;
// implementation only from now on
virtual bool MSWCommand(WXUINT param, WXWORD id) wxOVERRIDE;

View File

@ -11,7 +11,7 @@
#ifndef _WX_RADIOBUT_H_
#define _WX_RADIOBUT_H_
class WXDLLIMPEXP_CORE wxRadioButton: public wxControl
class WXDLLIMPEXP_CORE wxRadioButton: public wxRadioButtonBase
{
wxDECLARE_DYNAMIC_CLASS(wxRadioButton);
@ -35,8 +35,8 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxRadioButtonNameStr));
virtual void SetValue(bool val);
virtual bool GetValue() const ;
virtual void SetValue(bool val) wxOVERRIDE;
virtual bool GetValue() const wxOVERRIDE;
// implementation

View File

@ -0,0 +1,16 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/private/unicode.h
// Purpose: Unicode private declsrations
// Author: Pavel Tyunin
// Created: 2020-10-06
// Copyright: (c) 2020 Pavel Tyunin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PRIVATE_UNICODEH__
#define _WX_PRIVATE_UNICODEH__
// this table gives the length of the UTF-8 encoding from its first character:
extern const unsigned char tableUtf8Lengths[256];
#endif // _WX_PRIVATE_UNICODEH__

View File

@ -1591,11 +1591,12 @@ protected:
// 0 = not dragging, 1 = drag just started, 2 = drag in progress
unsigned char m_dragStatus;
#if WXWIN_COMPATIBILITY_3_0
// Unused variable.
// 0 = margin, 1 = label, 2 = value.
unsigned char m_mouseSide;
// True when editor control is focused.
#if WXWIN_COMPATIBILITY_3_0
unsigned char m_editorFocused;
#else
bool m_editorFocused;
@ -1634,8 +1635,8 @@ protected:
int m_clearThisMany;
#endif
// Mouse is hovering over this column (index)
unsigned int m_colHover;
// Mouse is hovering over this column (index), -1 for margin
int m_colHover;
// pointer to property that has mouse hovering
wxPGProperty* m_propHover;

View File

@ -10,7 +10,7 @@
class QRadioButton;
class WXDLLIMPEXP_CORE wxRadioButton : public wxControl
class WXDLLIMPEXP_CORE wxRadioButton : public wxRadioButtonBase
{
public:
wxRadioButton();
@ -32,8 +32,8 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxRadioButtonNameStr) );
virtual void SetValue(bool value);
virtual bool GetValue() const;
virtual void SetValue(bool value) wxOVERRIDE;
virtual bool GetValue() const wxOVERRIDE;
virtual QWidget *GetHandle() const wxOVERRIDE;

View File

@ -15,23 +15,42 @@
#if wxUSE_RADIOBTN
/*
There is no wxRadioButtonBase class as wxRadioButton interface is the same
as wxCheckBox(Base), but under some platforms wxRadioButton really
derives from wxCheckBox and on the others it doesn't.
The pseudo-declaration of wxRadioButtonBase would look like this:
class wxRadioButtonBase : public ...
{
public:
virtual void SetValue(bool value);
virtual bool GetValue() const;
};
*/
#include "wx/control.h"
class WXDLLIMPEXP_FWD_CORE wxRadioButton;
// TODO: In wxUniv, wxRadioButton must derive from wxCheckBox as it reuses
// much of its code. This should be fixed by refactoring wxCheckBox to allow
// this class to reuse its functionality without inheriting from it, but for
// now use this hack to allow the existing code to compile.
#ifdef __WXUNIVERSAL__
#include "wx/checkbox.h"
typedef wxCheckBox wxRadioButtonBaseBase;
#else
typedef wxControl wxRadioButtonBaseBase;
#endif
class WXDLLIMPEXP_CORE wxRadioButtonBase : public wxRadioButtonBaseBase
{
public:
wxRadioButtonBase() { }
// Methods to be implemented by the derived classes:
virtual void SetValue(bool value) = 0;
virtual bool GetValue() const = 0;
// Methods implemented by this class itself.
wxRadioButton* GetFirstInGroup() const;
wxRadioButton* GetLastInGroup() const;
wxRadioButton* GetPreviousInGroup() const;
wxRadioButton* GetNextInGroup() const;
private:
wxDECLARE_NO_COPY_CLASS(wxRadioButtonBase);
};
extern WXDLLIMPEXP_DATA_CORE(const char) wxRadioButtonNameStr[];
#if defined(__WXUNIVERSAL__)

View File

@ -94,15 +94,15 @@ struct WXDLLIMPEXP_BASE wxStringOperationsUtf8
return (c <= 0x7F) || (c >= 0xC2 && c <= 0xF4);
}
// table of offsets to skip forward when iterating over UTF-8 sequence
static const unsigned char ms_utf8IterTable[256];
// returns offset to skip forward when iterating over UTF-8 sequence
static unsigned char GetUTF8IterOffset(unsigned char c);
template<typename Iterator>
static void IncIter(Iterator& i)
{
wxASSERT( IsValidUtf8LeadByte(*i) );
i += ms_utf8IterTable[(unsigned char)*i];
i += GetUTF8IterOffset(*i);
}
template<typename Iterator>
@ -178,7 +178,7 @@ struct WXDLLIMPEXP_BASE wxStringOperationsUtf8
static size_t GetUtf8CharLength(char c)
{
wxASSERT( IsValidUtf8LeadByte(c) );
return ms_utf8IterTable[(unsigned char)c];
return GetUTF8IterOffset(c);
}
// decodes single UTF-8 character from UTF-8 string

View File

@ -295,10 +295,10 @@ public:
wxItemKind kind = wxITEM_NORMAL,
const wxString& shortHelp = wxEmptyString,
const wxString& longHelp = wxEmptyString,
wxObject *data = NULL)
wxObject *clientData = NULL)
{
return DoAddTool(toolid, label, bitmap, bmpDisabled, kind,
shortHelp, longHelp, data);
shortHelp, longHelp, clientData);
}
// the most common AddTool() version
@ -318,10 +318,10 @@ public:
const wxBitmap& bmpDisabled = wxNullBitmap,
const wxString& shortHelp = wxEmptyString,
const wxString& longHelp = wxEmptyString,
wxObject *data = NULL)
wxObject *clientData = NULL)
{
return AddTool(toolid, label, bitmap, bmpDisabled, wxITEM_CHECK,
shortHelp, longHelp, data);
shortHelp, longHelp, clientData);
}
// add a radio tool, i.e. a tool which can be toggled and releases any
@ -332,10 +332,10 @@ public:
const wxBitmap& bmpDisabled = wxNullBitmap,
const wxString& shortHelp = wxEmptyString,
const wxString& longHelp = wxEmptyString,
wxObject *data = NULL)
wxObject *clientData = NULL)
{
return AddTool(toolid, label, bitmap, bmpDisabled, wxITEM_RADIO,
shortHelp, longHelp, data);
shortHelp, longHelp, clientData);
}

View File

@ -11,13 +11,11 @@
#ifndef _WX_UNIV_RADIOBUT_H_
#define _WX_UNIV_RADIOBUT_H_
#include "wx/checkbox.h"
// ----------------------------------------------------------------------------
// wxRadioButton
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxRadioButton : public wxCheckBox
class WXDLLIMPEXP_CORE wxRadioButton : public wxRadioButtonBase
{
public:
// constructors
@ -46,6 +44,10 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxRadioButtonNameStr));
// (re)implement pure virtuals from wxRadioButtonBase
virtual void SetValue(bool value) wxOVERRIDE { return wxCheckBox::SetValue(value); }
virtual bool GetValue() const wxOVERRIDE { return wxCheckBox::GetValue(); }
// override some base class methods
virtual void ChangeValue(bool value) wxOVERRIDE;

View File

@ -162,7 +162,7 @@ WXDLLIMPEXP_BASE wxLinuxDistributionInfo wxGetLinuxDistributionInfo();
WXDLLIMPEXP_BASE wxString wxNow();
// Return path where wxWidgets is installed (mostly useful in Unices)
WXDLLIMPEXP_BASE const wxChar *wxGetInstallPrefix();
WXDLLIMPEXP_BASE wxString wxGetInstallPrefix();
// Return path to wxWin data (/usr/share/wx/%{version}) (Unices)
WXDLLIMPEXP_BASE wxString wxGetDataDir();

View File

@ -241,10 +241,12 @@ class WXDLLIMPEXP_XML wxXmlDoctype
{
public:
explicit
wxXmlDoctype(const wxString& name = wxString(),
const wxString& sysid = wxString(),
const wxString& pubid = wxString())
: m_rootName(name), m_systemId(sysid), m_publicId(pubid)
wxXmlDoctype(const wxString& rootName = wxString(),
const wxString& systemId = wxString(),
const wxString& publicId = wxString())
: m_rootName(rootName),
m_systemId(systemId),
m_publicId(publicId)
{}
// Default copy ctor and assignment operators are ok.

View File

@ -57,7 +57,7 @@
the end-user's machine. In order for the clipboard data to persist after
the window closes, a clipboard manager must be installed. Some clipboard
managers will automatically flush the clipboard after each new piece of
data is added, while others will not. The @Flush() function will force
data is added, while others will not. The Flush() function will force
the clipboard manager to flush the data.
@library{wxcore}

View File

@ -146,6 +146,22 @@ public:
*/
wxBOM GetBOM() const;
/**
Return the detected encoding
Returns @c wxFONTENCODING_MAX if called before the first use.
@since 3.1.5
*/
wxBOM GetEncoding() const;
/**
Check if the fall-back encoding is used.
@since 3.1.5
*/
bool IsUsingFallbackEncoding() const;
/**
Return a pointer to the characters that makes up this BOM.

View File

@ -73,9 +73,10 @@
associating the model with a control like this:
@code
wxDataViewCtrl *musicCtrl = new wxDataViewCtrl( this, wxID_ANY );
wxDataViewCtrl *musicCtrl = new wxDataViewCtrl(this, wxID_ANY);
wxDataViewModel *musicModel = new MyMusicModel;
m_musicCtrl->AssociateModel( musicModel );
musicCtrl->AssociateModel(musicModel);
musicModel->DecRef(); // avoid memory leak !!
// add columns now
@ -84,11 +85,10 @@
A potentially better way to avoid memory leaks is to use wxObjectDataPtr
@code
wxObjectDataPtr<MyMusicModel> musicModel;
wxDataViewCtrl *musicCtrl = new wxDataViewCtrl( this, wxID_ANY );
musicModel = new MyMusicModel;
m_musicCtrl->AssociateModel( musicModel.get() );
wxDataViewCtrl *musicCtrl = new wxDataViewCtrl(this, wxID_ANY);
wxObjectDataPtr<wxDataViewModel> musicModel(new MyMusicModel);
musicCtrl->AssociateModel(musicModel.get());
// add columns now
@endcode

View File

@ -206,55 +206,151 @@ public:
/**
Convert @e device X coordinate to logical coordinate, using the current
mapping mode, user scale factor, device origin and axis orientation.
@note Affine transformation applied to the coordinate system
with SetTransformMatrix() is not taken into account.
*/
wxCoord DeviceToLogicalX(wxCoord x) const;
/**
Convert @e device X coordinate to relative logical coordinate, using the
current mapping mode and user scale factor but ignoring the
axis orientation. Use this for converting a width, for example.
axis orientation. Use this for converting a horizontal distance like
for example a width.
@note Affine transformation applied to the coordinate system
with SetTransformMatrix() is not taken into account.
*/
wxCoord DeviceToLogicalXRel(wxCoord x) const;
/**
Converts @e device Y coordinate to logical coordinate, using the current
mapping mode, user scale factor, device origin and axis orientation.
@note Affine transformation applied to the coordinate system
with SetTransformMatrix() is not taken into account.
*/
wxCoord DeviceToLogicalY(wxCoord y) const;
/**
Convert @e device Y coordinate to relative logical coordinate, using the
current mapping mode and user scale factor but ignoring the
axis orientation. Use this for converting a height, for example.
axis orientation. Use this for converting a vertical distance like
for example a height.
@note Affine transformation applied to the coordinate system
with SetTransformMatrix() is not taken into account.
*/
wxCoord DeviceToLogicalYRel(wxCoord y) const;
/**
Converts logical X coordinate to device coordinate, using the current
mapping mode, user scale factor, device origin and axis orientation.
@note Affine transformation applied to the coordinate system
with SetTransformMatrix() is not taken into account.
*/
wxCoord LogicalToDeviceX(wxCoord x) const;
/**
Converts logical X coordinate to relative device coordinate, using the
current mapping mode and user scale factor but ignoring the
axis orientation. Use this for converting a width, for example.
axis orientation. Use this for converting a horizontal distance like
for example a width.
@note Affine transformation applied to the coordinate system
with SetTransformMatrix() is not taken into account.
*/
wxCoord LogicalToDeviceXRel(wxCoord x) const;
/**
Converts logical Y coordinate to device coordinate, using the current
mapping mode, user scale factor, device origin and axis orientation.
@note Affine transformation applied to the coordinate system
with SetTransformMatrix() is not taken into account.
*/
wxCoord LogicalToDeviceY(wxCoord y) const;
/**
Converts logical Y coordinate to relative device coordinate, using the
current mapping mode and user scale factor but ignoring the
axis orientation. Use this for converting a height, for example.
axis orientation. Use this for converting a vertical distance like
for example a height.
@note Affine transformation applied to the coordinate system
with SetTransformMatrix() is not taken into account.
*/
wxCoord LogicalToDeviceYRel(wxCoord y) const;
/**
Converts device (@a x, @a y) coordinates to logical coordinates
taking into account all applied transformations like the current
mapping mode, scale factors, device origin, axes orientation,
affine transformation.
@since 3.1.5
*/
wxPoint DeviceToLogical(wxCoord x, wxCoord y) const;
/**
@overload
@since 3.1.5
*/
wxPoint DeviceToLogical(const wxPoint& pt) const;
/**
Converts device @a x, @a y coordinates to relative logical coordinates
taking into account all applied transformations like the current
mapping mode, scale factors, affine transformation.
Use this for converting distances like e.g. width and height.
@since 3.1.5
*/
wxSize DeviceToLogicalRel(int x, int y) const;
/**
@overload
@since 3.1.5
*/
wxSize DeviceToLogicalRel(const wxSize& dim) const;
/**
Converts logical (@a x, @a y) coordinates to device coordinates
taking into account all applied transformations like the current
mapping mode, scale factors, device origin, axes orientation,
affine transformation.
@since 3.1.5
*/
wxPoint LogicalToDevice(wxCoord x, wxCoord y) const;
/**
@overload
@since 3.1.5
*/
wxPoint LogicalToDevice(const wxPoint& pt) const;
/**
Converts logical @a x, @a y coordinates to relative device coordinates
taking into account all applied transformations like the current
mapping mode, scale factors, affine transformation.
Use this for converting distances like e.g. width and height.
@since 3.1.5
*/
wxSize LogicalToDeviceRel(int x, int y) const;
/**
@overload
@since 3.1.5
*/
wxSize LogicalToDeviceRel(const wxSize& dim) const;
//@}

View File

@ -77,7 +77,7 @@ public:
For the values of @a helpStyle, please see the documentation for
wxHtmlHelpController.
*/
wxHtmlHelpWindow(wxWindow* parent, int wxWindowID,
wxHtmlHelpWindow(wxWindow* parent, wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
int style = wxTAB_TRAVERSAL|wxBORDER_NONE,

View File

@ -60,6 +60,21 @@ enum wxImageResizeQuality
wxIMAGE_QUALITY_HIGH
};
/**
Constants for wxImage::Paste() for specifying alpha blending option.
@since 3.1.5
*/
enum wxImageAlphaBlendMode
{
/// Overwrite the original alpha values with the ones being pasted.
wxIMAGE_ALPHA_BLEND_OVER = 0,
/// Compose the original alpha values with the ones being pasted.
wxIMAGE_ALPHA_BLEND_COMPOSE = 1
};
/**
Possible values for PNG image type option.
@ -803,8 +818,17 @@ public:
/**
Copy the data of the given @a image to the specified position in this image.
Takes care of the mask colour and out of bounds problems.
@param alphaBlend
This parameter (new in wx 3.1.5) determines whether the alpha values
of the original image replace (default) or are composed with the
alpha channel of this image. Notice that alpha blending overrides
the mask handling.
*/
void Paste(const wxImage& image, int x, int y);
void Paste(const wxImage& image, int x, int y,
wxImageAlphaBlendMode alphaBlend = wxIMAGE_ALPHA_BLEND_OVER);
/**
Replaces the colour specified by @e r1,g1,b1 by the colour @e r2,g2,b2.

View File

@ -12,18 +12,28 @@
mutually exclusive options. It has a text label next to a (usually) round
button.
You can create a group of mutually-exclusive radio buttons by specifying
@c wxRB_GROUP for the first in the group. The group ends when another
radio button group is created, or there are no more radio buttons.
Radio buttons are typically used in groups of mutually-exclusive buttons,
i.e. exactly one of the buttons in the group is checked, and the other ones
are unchecked automatically. Such groups are created implicitly, but can
also be started explicitly by using @c wxRB_GROUP style: a button with this
style starts a new group and will become the initial selection in this
group. Alternatively, a radio button may be excluded from the group that it
would otherwise belong to by using @c wxRB_SINGLE style.
To find the other elements of the same radio button group, you can use
GetFirstInGroup(), GetPreviousInGroup(), GetNextInGroup() and
GetLastInGroup() functions.
@beginStyleTable
@style{wxRB_GROUP}
Marks the beginning of a new group of radio buttons.
@style{wxRB_SINGLE}
In some circumstances, radio buttons that are not consecutive
siblings trigger a hang bug in Windows (only). If this happens, add
this style to mark the button as not belonging to a group, and
implement the mutually-exclusive group behaviour yourself.
Creates a radio button which is not part of any radio button group.
When this style is used, no other radio buttons will be turned off
automatically when this button is turned on and such behaviour will
need to be implemented manually, in the event handler for this
button.
@endStyleTable
@beginEventEmissionTable{wxCommandEvent}
@ -119,5 +129,64 @@ public:
@true to check, @false to uncheck.
*/
virtual void SetValue(bool value);
/**
Returns the first button of the radio button group this button belongs
to.
For a radio button with @c wxRB_SINGLE style, this function returns this
button itself, as it is the only member of its group. Otherwise, the
function returns the closest previous radio button with @c wxRB_GROUP
style (which could still be this button itself) or the first radio
button in the same window.
The returned value is never @NULL.
@see GetPreviousInGroup(), GetNextInGroup(), GetLastInGroup()
@since 3.1.5
*/
wxRadioButton* GetFirstInGroup() const;
/**
Returns the last button of the radio button group this button belongs
to.
Similarly to GetFirstInGroup(), this function returns this button
itself if it has @c wxRB_SINGLE style. Otherwise, the function returns
the last button before the next button with @c wxRB_GROUP style or the
last radio button in the same window.
The returned value is never @NULL.
@see GetPreviousInGroup(), GetNextInGroup()
@since 3.1.5
*/
wxRadioButton* GetLastInGroup() const;
/**
Returns the previous radio button in the same group.
The return value is @NULL if there is no predecessor or if this button
has @c wxRB_SINGLE style.
@see GetFirstInGroup(), GetNextInGroup(), GetLastInGroup()
@since 3.1.5
*/
wxRadioButton* GetPreviousInGroup() const;
/**
Returns the next radio button in the same group.
The return value is @NULL if there is no successor or if this button
has @c wxRB_SINGLE style.
@see GetFirstInGroup(), GetPreviousInGroup(), GetLastInGroup()
@since 3.1.5
*/
wxRadioButton* GetNextInGroup() const;
};

View File

@ -1251,6 +1251,12 @@ public:
wxRect* normal_region,
wxRect* dropdown_region);
wxCoord GetButtonBarButtonTextWidth(
wxDC& dc,
const wxString& label,
wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size);
wxSize GetMinimisedPanelMinimumSize(
wxDC& dc,
const wxRibbonPanel* wnd,

View File

@ -130,7 +130,7 @@ public:
The UI help string to associate with the new tool.
@param kind
The kind of tool to add.
@param client_data
@param clientData
Client data to associate with the new tool.
@return An opaque pointer which can be used only with other tool bar
@ -144,7 +144,7 @@ public:
const wxBitmap& bitmap_disabled = wxNullBitmap,
const wxString& help_string = wxEmptyString,
wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL,
wxObject* client_data = NULL);
wxObject* clientData = NULL);
/**
Add a separator to the tool bar.
@ -232,7 +232,7 @@ public:
The UI help string to associate with the new tool.
@param kind
The kind of tool to add.
@param client_data
@param clientData
Client data to associate with the new tool.
@return An opaque pointer which can be used only with other tool bar
@ -249,7 +249,7 @@ public:
const wxBitmap& bitmap_disabled = wxNullBitmap,
const wxString& help_string = wxEmptyString,
wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL,
wxObject* client_data = NULL);
wxObject* clientData = NULL);
/**
Insert a separator to the tool bar at the specified position.

View File

@ -462,9 +462,9 @@ public:
whenever another button in the group is checked. ::wxITEM_DROPDOWN
specifies that a drop-down menu button will appear next to the
tool button (only GTK+ and MSW). Call SetDropdownMenu() afterwards.
@param shortHelpString
@param shortHelp
This string is used for the tools tooltip.
@param longHelpString
@param longHelp
This string is shown in the statusbar (if any) of the parent frame
when the mouse pointer is inside the tool.
@param clientData
@ -481,8 +481,8 @@ public:
const wxBitmap& bitmap,
const wxBitmap& bmpDisabled,
wxItemKind kind = wxITEM_NORMAL,
const wxString& shortHelpString = wxEmptyString,
const wxString& longHelpString = wxEmptyString,
const wxString& shortHelp = wxEmptyString,
const wxString& longHelp = wxEmptyString,
wxObject* clientData = NULL);
//@}

View File

@ -494,16 +494,16 @@ public:
/**
Creates and possible initializes the DOCTYPE.
@param name
@param rootName
The root name.
@param sysid
@param systemId
The system identifier.
@param pubid
@param publicId
The public identifier.
*/
wxXmlDoctype(const wxString& name = wxString(),
const wxString& sysid = wxString(),
const wxString& pubid = wxString());
wxXmlDoctype(const wxString& rootName = wxString(),
const wxString& systemId = wxString(),
const wxString& publicId = wxString());
/**
Removes all the DOCTYPE values.

View File

@ -1338,8 +1338,8 @@ void MyCanvas::DrawSplines(wxDC& dc)
{
angle += angles[ angle_pos ];
int r = R * radii[ radius_pos ] / 100;
pts[ i ].x = center.x + (wxCoord)( r * cos( M_PI * angle / 180.0) );
pts[ i ].y = center.y + (wxCoord)( r * sin( M_PI * angle / 180.0) );
pts[ i ].x = center.x + (wxCoord)( r * cos(wxDegToRad(angle)) );
pts[ i ].y = center.y + (wxCoord)( r * sin(wxDegToRad(angle)) );
angle_pos++;
if ( angle_pos >= WXSIZEOF(angles) ) angle_pos = 0;
@ -2013,11 +2013,9 @@ void MyCanvas::OnMouseMove(wxMouseEvent &event)
PrepareDC(dc);
m_owner->PrepareDC(dc);
wxPoint pos = event.GetPosition();
long x = dc.DeviceToLogicalX( pos.x );
long y = dc.DeviceToLogicalY( pos.y );
wxPoint pos = dc.DeviceToLogical(event.GetPosition());
wxString str;
str.Printf( "Current mouse position: %d,%d", (int)x, (int)y );
str.Printf( "Current mouse position: %d,%d", pos.x, pos.y );
m_owner->SetStatusText( str );
}

View File

@ -564,6 +564,15 @@ void MyFrame::InitWithReportItems()
itemCol.SetAlign(wxLIST_FORMAT_RIGHT);
m_listCtrl->InsertColumn(2, itemCol);
if ( m_numListItems <= 0 )
{
m_listCtrl->SetColumnWidth( 0, 100 );
m_listCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
m_listCtrl->SetColumnWidth( 2, wxLIST_AUTOSIZE_USEHEADER );
return;
}
// to speed up inserting we hide the control temporarily
m_listCtrl->Hide();
@ -584,25 +593,38 @@ void MyFrame::InitWithReportItems()
item.SetTextColour(*wxRED);
m_listCtrl->SetItem( item );
item.m_itemId = 2;
item.SetTextColour(*wxGREEN);
m_listCtrl->SetItem( item );
item.m_itemId = 4;
item.SetTextColour(*wxLIGHT_GREY);
item.SetFont(*wxITALIC_FONT);
item.SetBackgroundColour(*wxRED);
m_listCtrl->SetItem( item );
if ( m_numListItems > 2 )
{
item.m_itemId = 2;
item.SetTextColour(*wxGREEN);
m_listCtrl->SetItem( item );
}
if ( m_numListItems > 4 )
{
item.m_itemId = 4;
item.SetTextColour(*wxLIGHT_GREY);
item.SetFont(*wxITALIC_FONT);
item.SetBackgroundColour(*wxRED);
m_listCtrl->SetItem( item );
}
m_listCtrl->SetTextColour(*wxBLUE);
// Set images in columns
m_listCtrl->SetItemColumnImage(1, 1, 0);
if ( m_numListItems > 1 )
{
// Set images in columns
m_listCtrl->SetItemColumnImage(1, 1, 0);
}
wxListItem info;
info.SetImage(0);
info.SetId(3);
info.SetColumn(2);
m_listCtrl->SetItem(info);
if ( m_numListItems > 3 )
{
wxListItem info;
info.SetImage(0);
info.SetId(3);
info.SetColumn(2);
m_listCtrl->SetItem(info);
}
// test SetItemFont too
m_listCtrl->SetItemFont(0, *wxITALIC_FONT);
@ -1073,6 +1095,11 @@ void MyListCtrl::OnColClick(wxListEvent& event)
{
int col = event.GetColumn();
if ( col == -1 )
{
return; // clicked outside any column.
}
// set or unset image
static bool x = false;
x = !x;
@ -1409,8 +1436,6 @@ void MyListCtrl::OnListKeyDown(wxListEvent& event)
wxFALLTHROUGH;
default:
LogEvent(event, "OnListKeyDown");
event.Skip();
}
}
@ -1442,7 +1467,6 @@ void MyListCtrl::OnRightClick(wxMouseEvent& event)
case wxLIST_HITTEST_NOWHERE: where = "nowhere near"; break;
case wxLIST_HITTEST_ONITEMICON: where = "on icon of"; break;
case wxLIST_HITTEST_ONITEMLABEL: where = "on label of"; break;
case wxLIST_HITTEST_ONITEMRIGHT: where = "right on"; break;
case wxLIST_HITTEST_TOLEFT: where = "to the left of"; break;
case wxLIST_HITTEST_TORIGHT: where = "to the right of"; break;
default: where = "not clear exactly where on"; break;

View File

@ -119,7 +119,8 @@ protected:
void OnCheckOrRadioBox(wxCommandEvent& event);
void OnSlider(wxScrollEvent& event);
void OnSliderScroll(wxScrollEvent& event);
void OnSlider(wxCommandEvent& event);
void OnUpdateUIValueButton(wxUpdateUIEvent& event);
void OnUpdateUIMinMaxButton(wxUpdateUIEvent& event);
@ -161,6 +162,8 @@ protected:
bool IsValidValue(int val) const
{ return (val >= m_min) && (val <= m_max); }
static int ms_numSliderEvents;
// the slider range
int m_min, m_max;
@ -200,6 +203,8 @@ private:
DECLARE_WIDGETS_PAGE(SliderWidgetsPage)
};
int SliderWidgetsPage::ms_numSliderEvents = 0;
// ----------------------------------------------------------------------------
// event tables
// ----------------------------------------------------------------------------
@ -229,7 +234,8 @@ wxBEGIN_EVENT_TABLE(SliderWidgetsPage, WidgetsPage)
EVT_UPDATE_UI(SliderPage_CurValueText, SliderWidgetsPage::OnUpdateUICurValueText)
EVT_COMMAND_SCROLL(SliderPage_Slider, SliderWidgetsPage::OnSlider)
EVT_COMMAND_SCROLL(SliderPage_Slider, SliderWidgetsPage::OnSliderScroll)
EVT_SLIDER(SliderPage_Slider, SliderWidgetsPage::OnSlider)
EVT_CHECKBOX(wxID_ANY, SliderWidgetsPage::OnCheckOrRadioBox)
EVT_RADIOBOX(wxID_ANY, SliderWidgetsPage::OnCheckOrRadioBox)
@ -801,7 +807,7 @@ void SliderWidgetsPage::OnUpdateUISelectRange(wxUpdateUIEvent& event)
#endif // defined(__WXMSW__)
}
void SliderWidgetsPage::OnSlider(wxScrollEvent& event)
void SliderWidgetsPage::OnSliderScroll(wxScrollEvent& event)
{
wxASSERT_MSG( event.GetInt() == m_slider->GetValue(),
"slider value should be the same" );
@ -835,14 +841,17 @@ void SliderWidgetsPage::OnSlider(wxScrollEvent& event)
wxASSERT_MSG(index >= 0 && (size_t)index < WXSIZEOF(eventNames),
"Unknown slider event" );
static int s_numSliderEvents = 0;
wxLogMessage("Slider event #%d: %s (pos = %d, int value = %d)",
s_numSliderEvents++,
ms_numSliderEvents++,
eventNames[index],
event.GetPosition(),
event.GetInt());
}
void SliderWidgetsPage::OnSlider(wxCommandEvent& event)
{
wxLogMessage("Slider event #%d: wxEVT_SLIDER (value = %d)",
ms_numSliderEvents++, event.GetInt());
}
#endif // wxUSE_SLIDER

View File

@ -2839,7 +2839,7 @@ void wxAuiToolBar::OnMotion(wxMouseEvent& evt)
const bool button_pressed = HasCapture();
// start a drag event
if (!m_dragging && button_pressed &&
if (!m_dragging && button_pressed && m_actionItem &&
abs(evt.GetX() - m_actionPos.x) + abs(evt.GetY() - m_actionPos.y) > 5)
{
// TODO: sending this event only makes sense if there is an 'END_DRAG'

View File

@ -234,101 +234,19 @@ void wxControlContainer::SetLastFocus(wxWindow *win)
}
// --------------------------------------------------------------------
// The following four functions are used to find other radio buttons
// within the same group. Used by wxSetFocusToChild
// The following functions is used by wxSetFocusToChild()
// --------------------------------------------------------------------
#if wxUSE_RADIOBTN
#if defined(USE_RADIOBTN_NAV)
wxRadioButton* wxGetPreviousButtonInGroup(wxRadioButton *btn)
namespace
{
if ( btn->HasFlag(wxRB_GROUP) || btn->HasFlag(wxRB_SINGLE) )
return NULL;
const wxWindowList& siblings = btn->GetParent()->GetChildren();
wxWindowList::compatibility_iterator nodeThis = siblings.Find(btn);
wxCHECK_MSG( nodeThis, NULL, wxT("radio button not a child of its parent?") );
// Iterate over all previous siblings until we find the next radio button
wxWindowList::compatibility_iterator nodeBefore = nodeThis->GetPrevious();
wxRadioButton *prevBtn = 0;
while (nodeBefore)
{
prevBtn = wxDynamicCast(nodeBefore->GetData(), wxRadioButton);
if (prevBtn)
break;
nodeBefore = nodeBefore->GetPrevious();
}
if (!prevBtn || prevBtn->HasFlag(wxRB_SINGLE))
{
// no more buttons in group
return NULL;
}
return prevBtn;
}
wxRadioButton* wxGetNextButtonInGroup(wxRadioButton *btn)
{
if (btn->HasFlag(wxRB_SINGLE))
return NULL;
const wxWindowList& siblings = btn->GetParent()->GetChildren();
wxWindowList::compatibility_iterator nodeThis = siblings.Find(btn);
wxCHECK_MSG( nodeThis, NULL, wxT("radio button not a child of its parent?") );
// Iterate over all previous siblings until we find the next radio button
wxWindowList::compatibility_iterator nodeNext = nodeThis->GetNext();
wxRadioButton *nextBtn = 0;
while (nodeNext)
{
nextBtn = wxDynamicCast(nodeNext->GetData(), wxRadioButton);
if (nextBtn)
break;
nodeNext = nodeNext->GetNext();
}
if ( !nextBtn || nextBtn->HasFlag(wxRB_GROUP) || nextBtn->HasFlag(wxRB_SINGLE) )
{
// no more buttons or the first button of the next group
return NULL;
}
return nextBtn;
}
wxRadioButton* wxGetFirstButtonInGroup(wxRadioButton *btn)
{
while (true)
{
wxRadioButton* prevBtn = wxGetPreviousButtonInGroup(btn);
if (!prevBtn)
return btn;
btn = prevBtn;
}
}
wxRadioButton* wxGetLastButtonInGroup(wxRadioButton *btn)
{
while (true)
{
wxRadioButton* nextBtn = wxGetNextButtonInGroup(btn);
if (!nextBtn)
return btn;
btn = nextBtn;
}
}
wxRadioButton* wxGetSelectedButtonInGroup(wxRadioButton *btn)
wxRadioButton* wxGetSelectedButtonInGroup(const wxRadioButton *btn)
{
// Find currently selected button
if (btn->GetValue())
return btn;
return const_cast<wxRadioButton*>(btn);
if (btn->HasFlag(wxRB_SINGLE))
return NULL;
@ -336,19 +254,21 @@ wxRadioButton* wxGetSelectedButtonInGroup(wxRadioButton *btn)
wxRadioButton *selBtn;
// First check all previous buttons
for (selBtn = wxGetPreviousButtonInGroup(btn); selBtn; selBtn = wxGetPreviousButtonInGroup(selBtn))
for (selBtn = btn->GetPreviousInGroup(); selBtn; selBtn = selBtn->GetPreviousInGroup())
if (selBtn->GetValue())
return selBtn;
// Now all following buttons
for (selBtn = wxGetNextButtonInGroup(btn); selBtn; selBtn = wxGetNextButtonInGroup(selBtn))
for (selBtn = btn->GetNextInGroup(); selBtn; selBtn = selBtn->GetNextInGroup())
if (selBtn->GetValue())
return selBtn;
return NULL;
}
#endif // wxUSE_RADIOBTN
} // anonymous namespace
#endif // USE_RADIOBTN_NAV
// ----------------------------------------------------------------------------
// Keyboard handling - this is the place where the TAB traversal logic is
@ -468,7 +388,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
// If we are in a radio button group, start from the first item in the
// group
if ( event.IsFromTab() && wxIsKindOf(winFocus, wxRadioButton ) )
winFocus = wxGetFirstButtonInGroup((wxRadioButton*)winFocus);
winFocus = static_cast<wxRadioButton*>(winFocus)->GetFirstInGroup();
#endif // USE_RADIOBTN_NAV
// ok, we found the focus - now is it our child?
start_node = children.Find( winFocus );
@ -586,20 +506,20 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
// find the correct radio button to focus
if ( forward )
{
child = wxGetNextButtonInGroup(lastBtn);
child = lastBtn->GetNextInGroup();
if ( !child )
{
// no next button in group, set it to the first button
child = wxGetFirstButtonInGroup(lastBtn);
child = lastBtn->GetFirstInGroup();
}
}
else
{
child = wxGetPreviousButtonInGroup(lastBtn);
child = lastBtn->GetPreviousInGroup();
if ( !child )
{
// no previous button in group, set it to the last button
child = wxGetLastButtonInGroup(lastBtn);
child = lastBtn->GetLastInGroup();
}
}

View File

@ -23,6 +23,7 @@
#endif
#include "wx/convauto.h"
#include "wx/private/unicode.h"
// we use latin1 by default as it seems the least bad choice: the files we need
// to detect input of don't always come from the user system (they are often
@ -266,6 +267,23 @@ bool wxConvAuto::InitFromInput(const char *src, size_t len)
return true;
}
// checks if the input can be the beginning of a valid UTF-8 sequence
static bool wxCanBeUTF8SequencePrefix(const char *src, size_t len)
{
size_t i = 0;
unsigned char l = tableUtf8Lengths[(unsigned char)src[i]];
if ( !l )
return false; // invalid leading byte
while ( --l )
{
if ( ++i == len )
return true; // truncated sequence
if ( (src[i] & 0xC0) != 0x80 )
return false; // invalid continuation byte
}
return false; // complete sequence
}
size_t
wxConvAuto::ToWChar(wchar_t *dst, size_t dstLen,
const char *src, size_t srcLen) const
@ -307,25 +325,28 @@ wxConvAuto::ToWChar(wchar_t *dst, size_t dstLen,
// try to convert using the auto-detected encoding
size_t rc = m_conv->ToWChar(dst, dstLen, src, srcLen);
if ( rc == wxCONV_FAILED && m_bomType == wxBOM_None )
if ( rc == wxCONV_FAILED && m_bomType == wxBOM_None && !m_ownsConv )
{
// we may need more bytes before we can decode the input, don't switch
// to the fall-back conversion in this case as it would prevent us from
// decoding UTF-8 input when fed it byte by byte, as done by
// wxTextInputStream, for example
if ( srcLen < m_conv->GetMaxCharLen() )
// up to 2 extra bytes are needed for inputs that start with null bytes
// that look like the start of UTF-32BE BOM, but can be in UTF-8 too
size_t nNull = 0;
if ( srcLen != wxNO_LEN && srcLen >= 2 && !src[0] )
nNull = ( src[1]? 1 : 2 );
if ( srcLen < nNull + m_conv->GetMaxCharLen() &&
wxCanBeUTF8SequencePrefix(src + nNull, srcLen - nNull) )
return wxCONV_FAILED;
// if the conversion failed but we didn't really detect anything and
// simply tried UTF-8 by default, retry it using the fall-back
if ( m_encDefault == wxFONTENCODING_DEFAULT )
self->m_encDefault = GetFallbackEncoding();
if ( m_encDefault != wxFONTENCODING_MAX )
{
if ( m_ownsConv )
delete m_conv;
self->m_conv = new wxCSConv(m_encDefault == wxFONTENCODING_DEFAULT
? GetFallbackEncoding()
: m_encDefault);
self->m_conv = new wxCSConv(m_encDefault);
self->m_ownsConv = true;
rc = m_conv->ToWChar(dst, dstLen, src, srcLen);
@ -351,3 +372,32 @@ wxConvAuto::FromWChar(char *dst, size_t dstLen,
return m_conv->FromWChar(dst, dstLen, src, srcLen);
}
wxFontEncoding wxConvAuto::GetEncoding() const
{
switch ( m_bomType )
{
case wxBOM_UTF32BE:
return wxFONTENCODING_UTF32BE;
case wxBOM_UTF32LE:
return wxFONTENCODING_UTF32LE;
case wxBOM_UTF16BE:
return wxFONTENCODING_UTF16BE;
case wxBOM_UTF16LE:
return wxFONTENCODING_UTF16LE;
case wxBOM_UTF8:
return wxFONTENCODING_UTF8;
case wxBOM_Unknown:
case wxBOM_None:
if ( !m_conv )
return wxFONTENCODING_MAX;
else if ( !m_ownsConv )
return wxFONTENCODING_UTF8;
else
return m_encDefault;
}
wxFAIL_MSG( "unknown BOM type" );
return wxFONTENCODING_MAX;
}

View File

@ -512,6 +512,16 @@ wxPoint wxDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const
return wxPoint(LogicalToDeviceX(x), LogicalToDeviceY(y));
}
wxSize wxDCImpl::DeviceToLogicalRel(int x, int y) const
{
return wxSize(DeviceToLogicalXRel(x), DeviceToLogicalYRel(y));
}
wxSize wxDCImpl::LogicalToDeviceRel(int x, int y) const
{
return wxSize(LogicalToDeviceXRel(x), LogicalToDeviceYRel(y));
}
void wxDCImpl::ComputeScaleAndOrigin()
{
m_scaleX = m_logicalScaleX * m_userScaleX;

View File

@ -27,12 +27,6 @@
#include "wx/geometry.h"
#endif
//-----------------------------------------------------------------------------
// constants
//-----------------------------------------------------------------------------
static const double RAD2DEG = 180.0 / M_PI;
//-----------------------------------------------------------------------------
// Local functions
//-----------------------------------------------------------------------------
@ -613,6 +607,22 @@ wxPoint wxGCDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const
return wxPoint(wxRound(px), wxRound(py));
}
wxSize wxGCDCImpl::DeviceToLogicalRel(int x, int y) const
{
wxDouble dx = x;
wxDouble dy = y;
m_matrixCurrentInv.TransformDistance(&dx, &dy);
return wxSize(wxRound(dx), wxRound(dy));
}
wxSize wxGCDCImpl::LogicalToDeviceRel(int x, int y) const
{
wxDouble dx = x;
wxDouble dy = y;
m_matrixCurrent.TransformDistance(&dx, &dy);
return wxSize(wxRound(dx), wxRound(dy));
}
bool wxGCDCImpl::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
const wxColour& WXUNUSED(col),
wxFloodFillStyle WXUNUSED(style))
@ -670,11 +680,11 @@ void wxGCDCImpl::DoDrawArc( wxCoord x1, wxCoord y1,
double dy = y1 - yc;
double radius = sqrt((double)(dx * dx + dy * dy));
wxCoord rad = (wxCoord)radius;
double sa, ea;
double sa, ea; // In radians
if (x1 == x2 && y1 == y2)
{
sa = 0.0;
ea = 360.0;
ea = 2.0 * M_PI;
}
else if (radius == 0.0)
{
@ -683,11 +693,11 @@ void wxGCDCImpl::DoDrawArc( wxCoord x1, wxCoord y1,
else
{
sa = (x1 - xc == 0) ?
(y1 - yc < 0) ? 90.0 : -90.0 :
-atan2(double(y1 - yc), double(x1 - xc)) * RAD2DEG;
(y1 - yc < 0) ? M_PI / 2.0 : -M_PI / 2.0 :
-atan2(double(y1 - yc), double(x1 - xc));
ea = (x2 - xc == 0) ?
(y2 - yc < 0) ? 90.0 : -90.0 :
-atan2(double(y2 - yc), double(x2 - xc)) * RAD2DEG;
(y2 - yc < 0) ? M_PI / 2.0 : -M_PI / 2.0 :
-atan2(double(y2 - yc), double(x2 - xc));
}
bool fill = m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT;
@ -697,7 +707,7 @@ void wxGCDCImpl::DoDrawArc( wxCoord x1, wxCoord y1,
path.MoveToPoint( xc, yc );
// since these angles (ea,sa) are measured counter-clockwise, we invert them to
// get clockwise angles
path.AddArc( xc, yc , rad, wxDegToRad(-sa), wxDegToRad(-ea), false );
path.AddArc( xc, yc , rad, -sa, -ea, false );
if ( fill && ((x1!=x2)||(y1!=y2)) )
path.AddLineToPoint( xc, yc );
m_graphicContext->DrawPath(path);

View File

@ -227,6 +227,8 @@ wxString wxDynamicLibrary::GetPluginsDirectory()
{
#ifdef __UNIX__
wxString format = wxGetInstallPrefix();
if ( format.empty() )
return wxEmptyString;
wxString dir;
format << wxFILE_SEP_PATH
<< wxT("lib") << wxFILE_SEP_PATH

View File

@ -176,8 +176,7 @@ wxDouble wxPoint2DInt::GetVectorAngle() const
return 180;
}
// casts needed for MIPSpro compiler under SGI
wxDouble deg = atan2( (double)m_y , (double)m_x ) * 180 / M_PI;
wxDouble deg = wxRadToDeg(atan2( (double)m_y , (double)m_x ));
if ( deg < 0 )
{
deg += 360;
@ -189,8 +188,9 @@ wxDouble wxPoint2DInt::GetVectorAngle() const
void wxPoint2DInt::SetVectorAngle( wxDouble degrees )
{
wxDouble length = GetVectorLength();
m_x = (int)(length * cos( degrees / 180 * M_PI ));
m_y = (int)(length * sin( degrees / 180 * M_PI ));
double rad = wxDegToRad(degrees);
m_x = (int)(length * cos(rad));
m_y = (int)(length * sin(rad));
}
wxDouble wxPoint2DDouble::GetVectorAngle() const
@ -209,7 +209,7 @@ wxDouble wxPoint2DDouble::GetVectorAngle() const
else
return 180;
}
wxDouble deg = atan2( m_y , m_x ) * 180 / M_PI;
wxDouble deg = wxRadToDeg(atan2( m_y , m_x ));
if ( deg < 0 )
{
deg += 360;
@ -220,8 +220,9 @@ wxDouble wxPoint2DDouble::GetVectorAngle() const
void wxPoint2DDouble::SetVectorAngle( wxDouble degrees )
{
wxDouble length = GetVectorLength();
m_x = length * cos( degrees / 180 * M_PI );
m_y = length * sin( degrees / 180 * M_PI );
double rad = wxDegToRad(degrees);
m_x = length * cos(rad);
m_y = length * sin(rad);
}
// wxRect2D

View File

@ -1608,7 +1608,9 @@ wxImage wxImage::Size( const wxSize& size, const wxPoint& pos,
return image;
}
void wxImage::Paste( const wxImage &image, int x, int y )
void
wxImage::Paste(const wxImage & image, int x, int y,
wxImageAlphaBlendMode alphaBlend)
{
wxCHECK_RET( IsOk(), wxT("invalid image") );
wxCHECK_RET( image.IsOk(), wxT("invalid image") );
@ -1639,15 +1641,18 @@ void wxImage::Paste( const wxImage &image, int x, int y )
if (width < 1) return;
if (height < 1) return;
bool copiedPixels = false;
// If we can, copy the data using memcpy() as this is the fastest way. But
// for this the image being pasted must have "compatible" mask with this
// one meaning that either it must not have one at all or it must use the
// same masked colour.
if ( !image.HasMask() ||
// for this we must not do alpha compositing and the image being pasted
// must have "compatible" mask with this one meaning that either it must
// not have one at all or it must use the same masked colour.
if (alphaBlend == wxIMAGE_ALPHA_BLEND_OVER &&
(!image.HasMask() ||
((HasMask() &&
(GetMaskRed()==image.GetMaskRed()) &&
(GetMaskGreen()==image.GetMaskGreen()) &&
(GetMaskBlue()==image.GetMaskBlue()))) )
(GetMaskBlue()==image.GetMaskBlue())))) )
{
const unsigned char* source_data = image.GetData() + 3*(xx + yy*image.GetWidth());
int source_step = image.GetWidth()*3;
@ -1660,6 +1665,8 @@ void wxImage::Paste( const wxImage &image, int x, int y )
source_data += source_step;
target_data += target_step;
}
copiedPixels = true;
}
// Copy over the alpha channel from the original image
@ -1668,45 +1675,126 @@ void wxImage::Paste( const wxImage &image, int x, int y )
if ( !HasAlpha() )
InitAlpha();
const unsigned char* source_data = image.GetAlpha() + xx + yy*image.GetWidth();
int source_step = image.GetWidth();
const unsigned char*
alpha_source_data = image.GetAlpha() + xx + yy * image.GetWidth();
const int source_step = image.GetWidth();
unsigned char* target_data = GetAlpha() + (x+xx) + (y+yy)*M_IMGDATA->m_width;
int target_step = M_IMGDATA->m_width;
unsigned char*
alpha_target_data = GetAlpha() + (x + xx) + (y + yy) * M_IMGDATA->m_width;
const int target_step = M_IMGDATA->m_width;
for (int j = 0; j < height; j++,
source_data += source_step,
target_data += target_step)
switch (alphaBlend)
{
memcpy( target_data, source_data, width );
case wxIMAGE_ALPHA_BLEND_OVER:
{
// Copy just the alpha values.
for (int j = 0; j < height; j++,
alpha_source_data += source_step,
alpha_target_data += target_step)
{
memcpy(alpha_target_data, alpha_source_data, width);
}
break;
}
case wxIMAGE_ALPHA_BLEND_COMPOSE:
{
const unsigned char*
source_data = image.GetData() + 3 * (xx + yy * image.GetWidth());
unsigned char*
target_data = GetData() + 3 * ((x + xx) + (y + yy) * M_IMGDATA->m_width);
// Combine the alpha values but also apply alpha blending to
// the pixels themselves while we copy them.
for (int j = 0; j < height; j++,
alpha_source_data += source_step,
alpha_target_data += target_step,
source_data += 3 * source_step,
target_data += 3 * target_step)
{
for (int i = 0; i < width; i++)
{
float source_alpha = alpha_source_data[i] / 255.0f;
float light_left = (alpha_target_data[i] / 255.0f) * (1.0f - source_alpha);
float result_alpha = source_alpha + light_left;
alpha_target_data[i] = (unsigned char)((result_alpha * 255) +0.5);
for (int c = 3 * i; c < 3 * (i + 1); c++)
{
target_data[c] =
(unsigned char)(((source_data[c] * source_alpha +
target_data[c] * light_left) /
result_alpha) + 0.5);
}
}
}
copiedPixels = true;
break;
}
}
}
if (!HasMask() && image.HasMask())
// If we hadn't copied them yet we must need to take the mask of the image
// being pasted into account.
if (!copiedPixels)
{
unsigned char r = image.GetMaskRed();
unsigned char g = image.GetMaskGreen();
unsigned char b = image.GetMaskBlue();
const unsigned char* source_data = image.GetData() + 3 * (xx + yy * image.GetWidth());
int source_step = image.GetWidth() * 3;
const unsigned char* source_data = image.GetData() + 3*(xx + yy*image.GetWidth());
int source_step = image.GetWidth()*3;
unsigned char* target_data = GetData() + 3 * ((x + xx) + (y + yy) * M_IMGDATA->m_width);
int target_step = M_IMGDATA->m_width * 3;
unsigned char* target_data = GetData() + 3*((x+xx) + (y+yy)*M_IMGDATA->m_width);
int target_step = M_IMGDATA->m_width*3;
for (int j = 0; j < height; j++)
unsigned char* alpha_target_data = NULL;
const int target_alpha_step = M_IMGDATA->m_width;
if (HasAlpha())
{
for (int i = 0; i < width*3; i+=3)
alpha_target_data = GetAlpha() + (x + xx) + (y + yy) * M_IMGDATA->m_width;
}
// The mask colours should only be taken into account if the mask is actually enabled
if (!image.HasMask())
{
// Copy all pixels
for (int j = 0; j < height; j++)
{
if ((source_data[i] != r) ||
(source_data[i+1] != g) ||
(source_data[i+2] != b))
memcpy(target_data, source_data, width * 3);
source_data += source_step;
target_data += target_step;
// Make all the copied pixels fully opaque
if (alpha_target_data != NULL)
{
memcpy( target_data+i, source_data+i, 3 );
memset(alpha_target_data, wxALPHA_OPAQUE, width);
alpha_target_data += target_alpha_step;
}
}
source_data += source_step;
target_data += target_step;
}
else
{
// Copy all 'non masked' pixels
unsigned char r = image.GetMaskRed();
unsigned char g = image.GetMaskGreen();
unsigned char b = image.GetMaskBlue();
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width * 3; i += 3)
{
if ((source_data[i] != r) ||
(source_data[i + 1] != g) ||
(source_data[i + 2] != b))
{
// Copy the non masked pixel
memcpy(target_data + i, source_data + i, 3);
if (alpha_target_data != NULL) // Make the copied pixel fully opaque
alpha_target_data[i / 3] = wxALPHA_OPAQUE;
}
}
source_data += source_step;
target_data += target_step;
if (alpha_target_data != NULL)
alpha_target_data += target_alpha_step;
}
}
}
}

View File

@ -92,4 +92,96 @@ wxCONSTRUCTOR_6( wxRadioButton, wxWindow*, Parent, wxWindowID, Id, \
wxString, Label, wxPoint, Position, wxSize, Size, long, WindowStyle )
// ----------------------------------------------------------------------------
// wxRadioButton group navigation
// ----------------------------------------------------------------------------
wxRadioButton* wxRadioButtonBase::GetFirstInGroup() const
{
wxRadioButton*
btn = static_cast<wxRadioButton*>(const_cast<wxRadioButtonBase*>(this));
while (true)
{
wxRadioButton* prevBtn = btn->GetPreviousInGroup();
if (!prevBtn)
return btn;
btn = prevBtn;
}
}
wxRadioButton* wxRadioButtonBase::GetLastInGroup() const
{
wxRadioButton*
btn = static_cast<wxRadioButton*>(const_cast<wxRadioButtonBase*>(this));
while (true)
{
wxRadioButton* nextBtn = btn->GetNextInGroup();
if (!nextBtn)
return btn;
btn = nextBtn;
}
}
wxRadioButton* wxRadioButtonBase::GetPreviousInGroup() const
{
if ( HasFlag(wxRB_GROUP) || HasFlag(wxRB_SINGLE) )
return NULL;
const wxWindowList& siblings = GetParent()->GetChildren();
wxWindowList::compatibility_iterator nodeThis = siblings.Find(this);
wxCHECK_MSG( nodeThis, NULL, wxT("radio button not a child of its parent?") );
// Iterate over all previous siblings until we find the next radio button
wxWindowList::compatibility_iterator nodeBefore = nodeThis->GetPrevious();
wxRadioButton *prevBtn = 0;
while (nodeBefore)
{
prevBtn = wxDynamicCast(nodeBefore->GetData(), wxRadioButton);
if (prevBtn)
break;
nodeBefore = nodeBefore->GetPrevious();
}
if (!prevBtn || prevBtn->HasFlag(wxRB_SINGLE))
{
// no more buttons in group
return NULL;
}
return prevBtn;
}
wxRadioButton* wxRadioButtonBase::GetNextInGroup() const
{
if ( HasFlag(wxRB_SINGLE) )
return NULL;
const wxWindowList& siblings = GetParent()->GetChildren();
wxWindowList::compatibility_iterator nodeThis = siblings.Find(this);
wxCHECK_MSG( nodeThis, NULL, wxT("radio button not a child of its parent?") );
// Iterate over all previous siblings until we find the next radio button
wxWindowList::compatibility_iterator nodeNext = nodeThis->GetNext();
wxRadioButton *nextBtn = 0;
while (nodeNext)
{
nextBtn = wxDynamicCast(nodeNext->GetData(), wxRadioButton);
if (nextBtn)
break;
nodeNext = nodeNext->GetNext();
}
if ( !nextBtn || nextBtn->HasFlag(wxRB_GROUP) || nextBtn->HasFlag(wxRB_SINGLE) )
{
// no more buttons or the first button of the next group
return NULL;
}
return nextBtn;
}
#endif // wxUSE_RADIOBTN

View File

@ -46,6 +46,7 @@
#include "wx/encconv.h"
#include "wx/fontmap.h"
#include "wx/private/unicode.h"
#ifdef __DARWIN__
#include "wx/osx/core/private/strconv_cf.h"
@ -921,7 +922,7 @@ const wxUint32 wxUnicodePUA = 0x100000;
const wxUint32 wxUnicodePUAEnd = wxUnicodePUA + 256;
// this table gives the length of the UTF-8 encoding from its first character:
const unsigned char tableUtf8Lengths[256] = {
extern const unsigned char tableUtf8Lengths[256] = {
// single-byte sequences (ASCII):
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 00..0F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10..1F

View File

@ -23,6 +23,8 @@
#include "wx/stringops.h"
#endif
#include "wx/private/unicode.h"
// ===========================================================================
// implementation
// ===========================================================================
@ -97,40 +99,13 @@ wxWxCharBuffer wxStringOperationsWchar::EncodeNChars(size_t n, const wxUniChar&
// UTF-8 sequences lengths
// ---------------------------------------------------------------------------
const unsigned char wxStringOperationsUtf8::ms_utf8IterTable[256] = {
// single-byte sequences (ASCII):
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 00..0F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10..1F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20..2F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30..3F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40..4F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 50..5F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60..6F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 70..7F
// these are invalid, we use step 1 to skip
// over them (should never happen):
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 80..8F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 90..9F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A0..AF
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B0..BF
1, 1, // C0,C1
// two-byte sequences:
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C2..CF
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // D0..DF
// three-byte sequences:
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // E0..EF
// four-byte sequences:
4, 4, 4, 4, 4, // F0..F4
// these are invalid again (5- or 6-byte
// sequences and sequences for code points
// above U+10FFFF, as restricted by RFC 3629):
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F5..FF
};
unsigned char wxStringOperationsUtf8::GetUTF8IterOffset(unsigned char c)
{
unsigned char l = tableUtf8Lengths[c];
if ( !l ) //skip over invalid characters
l = 1;
return l;
}
// ---------------------------------------------------------------------------
// UTF-8 operations
@ -166,7 +141,7 @@ bool wxStringOperationsUtf8::IsValidUtf8String(const char *str, size_t len)
{
// if the string is not NULL-terminated, verify we have enough
// bytes in it left for current character's encoding:
if ( c + ms_utf8IterTable[*c] > end )
if ( c + GetUTF8IterOffset(*c) > end )
return false;
}
@ -364,7 +339,7 @@ wxCharBuffer wxStringOperationsUtf8::EncodeNChars(size_t n, const wxUniChar& ch)
{
Utf8CharBuffer once(EncodeChar(ch));
// the IncIter() table can be used to determine the length of ch's encoding:
size_t len = ms_utf8IterTable[(unsigned char)once.data[0]];
size_t len = GetUTF8IterOffset(once.data[0]);
wxCharBuffer buf(n * len);
char *ptr = buf.data();

View File

@ -97,10 +97,11 @@ wxChar wxTextInputStream::GetChar()
m_validEnd = 0;
}
// We may need to decode up to 4 characters if we have input starting with
// 3 BOM-like bytes, but not actually containing a BOM, as decoding it will
// only succeed when 4 bytes are read -- and will yield 4 wide characters.
wxChar wbuf[4];
// We may need to decode up to 6 characters if we have input starting with
// 2 null bytes (like in UTF-32BE BOM), and then 3 bytes that look like
// the start of UTF-8 sequence, as decoding it will only succeed when
// 6 bytes are read -- and will yield 6 wide characters.
wxChar wbuf[6];
for(size_t inlen = 0; inlen < sizeof(m_lastBytes); inlen++)
{
if ( inlen >= m_validEnd )
@ -134,12 +135,13 @@ wxChar wxTextInputStream::GetChar()
// one extra byte, the only explanation is that we were using a
// wxConvAuto conversion recognizing the initial BOM and that
// it couldn't detect the presence or absence of BOM so far,
// but now finally has enough data to see that there is none.
// As we must have fallen back to Latin-1 in this case, return
// just the first byte and keep the other ones for the next
// time.
m_validBegin = 1;
return wbuf[0];
// but now finally has enough data to see that there is none, or
// it was trying to decode the data as UTF-8 sequence, but now
// recognized that it's not valid UTF-8 and switched to fallback.
// We don't know how long is the first character or if it's decoded
// as 1 or 2 wchar_t characters, so we need to start with 1 byte again.
inlen = -1;
break;
#if SIZEOF_WCHAR_T == 2
case 2:

View File

@ -15,6 +15,7 @@
#endif
#include "wx/ustring.h"
#include "wx/private/unicode.h"
#ifndef WX_PRECOMP
#include "wx/crt.h"
@ -67,41 +68,6 @@ wxUString &wxUString::assignFromAscii( const char *str, size_type n )
// UTF-8
// ----------------------------------------------------------------------------
// this table gives the length of the UTF-8 encoding from its first character:
const unsigned char tableUtf8Lengths[256] = {
// single-byte sequences (ASCII):
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 00..0F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10..1F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20..2F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30..3F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40..4F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 50..5F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60..6F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 70..7F
// these are invalid:
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80..8F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90..9F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A0..AF
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B0..BF
0, 0, // C0,C1
// two-byte sequences:
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C2..CF
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // D0..DF
// three-byte sequences:
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // E0..EF
// four-byte sequences:
4, 4, 4, 4, 4, // F0..F4
// these are invalid again (5- or 6-byte
// sequences and sequences for code points
// above U+10FFFF, as restricted by RFC 3629):
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F5..FF
};
wxUString &wxUString::assignFromUTF8( const char *str )
{
if (!str)

View File

@ -182,12 +182,12 @@ void wxUsleep(unsigned long milliseconds)
}
#endif
const wxChar *wxGetInstallPrefix()
wxString wxGetInstallPrefix()
{
wxString prefix;
if ( wxGetEnv(wxT("WXPREFIX"), &prefix) )
return prefix.c_str();
return prefix;
#ifdef wxINSTALL_PREFIX
return wxT(wxINSTALL_PREFIX);

View File

@ -135,6 +135,11 @@ wxBitmapComboBox::~wxBitmapComboBox()
DoClear();
}
wxString wxBitmapComboBox::GetStringSelection() const
{
return wxItemContainer::GetStringSelection();
}
// ----------------------------------------------------------------------------
// Item manipulation
// ----------------------------------------------------------------------------

View File

@ -103,7 +103,8 @@ void wxCaret::InitGeneric()
#ifndef wxHAS_CARET_USING_OVERLAYS
m_xOld =
m_yOld = -1;
m_bmpUnderCaret.Create(m_width, m_height);
if (m_width && m_height)
m_bmpUnderCaret.Create(m_width, m_height);
#endif
}
@ -174,7 +175,10 @@ void wxCaret::DoSize()
m_overlay.Reset();
#else
// Change bitmap size
m_bmpUnderCaret = wxBitmap(m_width, m_height);
if (m_width && m_height)
m_bmpUnderCaret = wxBitmap(m_width, m_height);
else
m_bmpUnderCaret = wxBitmap();
#endif
if (countVisible > 0)
{

View File

@ -950,6 +950,7 @@ bool wxListLineData::Highlight( bool on )
return false;
m_highlighted = on;
m_owner->UpdateSelectionCount(on);
return true;
}
@ -1571,6 +1572,7 @@ wxEND_EVENT_TABLE()
void wxListMainWindow::Init()
{
m_dirty = true;
m_selCount =
m_countVirt = 0;
m_lineFrom =
m_lineTo = (size_t)-1;
@ -1598,7 +1600,8 @@ void wxListMainWindow::Init()
m_current =
m_lineLastClicked =
m_lineSelectSingleOnUp =
m_lineBeforeLastClicked = (size_t)-1;
m_lineBeforeLastClicked =
m_anchor = (size_t)-1;
m_hasCheckBoxes = false;
}
@ -1866,8 +1869,13 @@ bool wxListMainWindow::IsHighlighted(size_t line) const
void wxListMainWindow::HighlightLines( size_t lineFrom,
size_t lineTo,
bool highlight )
bool highlight,
SendEvent sendEvent )
{
// It is safe to swap the bounds here if they are not in order.
if ( lineFrom > lineTo )
wxSwap(lineFrom, lineTo);
if ( IsVirtual() )
{
wxArrayInt linesChanged;
@ -1890,13 +1898,13 @@ void wxListMainWindow::HighlightLines( size_t lineFrom,
{
for ( size_t line = lineFrom; line <= lineTo; line++ )
{
if ( HighlightLine(line, highlight) )
if ( HighlightLine(line, highlight, sendEvent) )
RefreshLine(line);
}
}
}
bool wxListMainWindow::HighlightLine( size_t line, bool highlight )
bool wxListMainWindow::HighlightLine( size_t line, bool highlight, SendEvent sendEvent )
{
bool changed;
@ -1912,7 +1920,7 @@ bool wxListMainWindow::HighlightLine( size_t line, bool highlight )
changed = ld->Highlight(highlight);
}
if ( changed )
if ( changed && sendEvent )
{
SendNotify( line, highlight ? wxEVT_LIST_ITEM_SELECTED
: wxEVT_LIST_ITEM_DESELECTED );
@ -2197,6 +2205,58 @@ void wxListMainWindow::HighlightAll( bool on )
}
}
void wxListMainWindow::HighlightOnly( size_t line, size_t oldLine )
{
const unsigned selCount = GetSelectedItemCount();
if ( selCount == 1 && IsHighlighted(line) )
{
return; // Nothing changed.
}
if ( oldLine != (size_t)-1 )
{
IsHighlighted(oldLine) ? ReverseHighlight(oldLine)
: RefreshLine(oldLine); // refresh the old focus to remove it
}
if ( selCount > 1 ) // multiple-selection only
{
// Deselecting many items at once will generate wxEVT_XXX_DESELECTED event
// for each one of them. although this may be inefficient if the number of
// deselected items is too much, we keep doing this (for non-virtual list
// controls) for backward compatibility concerns. For virtual listctrl (in
// multi-selection mode), wxMSW sends only a notification to indicate that
// something has been deselected. Notice that to be fully compatible with
// wxMSW behaviour, _line_ shouldn't be deselected if it was selected.
const SendEvent sendEvent = IsVirtual() ? SendEvent_None : SendEvent_Normal;
size_t lineFrom = 0,
lineTo = GetItemCount() - 1;
if ( line > lineFrom && line < lineTo )
{
HighlightLines(lineFrom, line - 1, false, sendEvent);
HighlightLines(line + 1, lineTo, false, sendEvent);
}
else // _line_ is equal to lineFrom or lineTo
{
line == lineFrom ? ++lineFrom : --lineTo;
HighlightLines(lineFrom, lineTo, false, sendEvent);
}
// If we didn't send the event for individual items above, send it for all of them now.
if ( sendEvent == SendEvent_None )
SendNotify((size_t)-1, wxEVT_LIST_ITEM_DESELECTED);
}
// _line_ should be the only selected item.
HighlightLine(line);
// refresh the new focus to add it.
RefreshLine(line);
}
void wxListMainWindow::OnChildFocus(wxChildFocusEvent& WXUNUSED(event))
{
// Do nothing here. This prevents the default handler in wxScrolledWindow
@ -2241,8 +2301,13 @@ void wxListMainWindow::SendNotify( size_t line,
GetParent()->GetEventHandler()->ProcessEvent( le );
}
void wxListMainWindow::ChangeCurrent(size_t current)
bool wxListMainWindow::ChangeCurrentWithoutEvent(size_t current)
{
if ( current == m_current )
{
return false; // Nothing changed!
}
m_current = current;
// as the current item changed, we shouldn't start editing it when the
@ -2250,7 +2315,13 @@ void wxListMainWindow::ChangeCurrent(size_t current)
if ( m_renameTimer->IsRunning() )
m_renameTimer->Stop();
SendNotify(current, wxEVT_LIST_ITEM_FOCUSED);
return true;
}
void wxListMainWindow::ChangeCurrent(size_t current)
{
if ( ChangeCurrentWithoutEvent(current) )
SendNotify(current, wxEVT_LIST_ITEM_FOCUSED);
}
wxTextCtrl *wxListMainWindow::EditLabel(long item, wxClassInfo* textControlClass)
@ -2396,7 +2467,11 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
evtCtx.SetEventObject(GetParent());
GetParent()->GetEventHandler()->ProcessEvent(evtCtx);
}
return;
if ( IsEmpty() )
return;
// Continue processing...
}
if (m_dirty)
@ -2521,8 +2596,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
if (m_lineSelectSingleOnUp != (size_t)-1)
{
// select single line
HighlightAll( false );
ReverseHighlight(m_lineSelectSingleOnUp);
HighlightOnly(m_lineSelectSingleOnUp);
}
if (m_lastOnSame)
@ -2542,6 +2616,14 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
m_lastOnSame = false;
}
if ( GetSelectedItemCount() == 1 || event.CmdDown() )
{
// In multiple selection mode, the anchor is set to the first selected
// item or can be changed to m_current if Ctrl key is down, as is the
// case under wxMSW.
m_anchor = m_current;
}
m_lineSelectSingleOnUp = (size_t)-1;
}
else
@ -2561,9 +2643,8 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
// Multi-selections should not be cleared if a selected item is clicked.
if (!IsHighlighted(current))
{
HighlightAll(false);
ChangeCurrent(current);
ReverseHighlight(m_current);
HighlightOnly(m_current);
}
SendNotify( current, wxEVT_LIST_ITEM_RIGHT_CLICK, event.GetPosition() );
@ -2581,7 +2662,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
m_lineLastClicked = current;
size_t oldCurrent = m_current;
bool oldWasSelected = IsHighlighted(m_current);
bool oldWasSelected = HasCurrent() && IsHighlighted(m_current);
bool cmdModifierDown = event.CmdDown();
if ( IsSingleSel() || !(cmdModifierDown || event.ShiftDown()) )
@ -2592,11 +2673,8 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
}
else if (IsSingleSel() || !IsHighlighted(current))
{
HighlightAll(false);
ChangeCurrent(current);
ReverseHighlight(m_current);
HighlightOnly(m_current, oldWasSelected ? oldCurrent : (size_t)-1);
}
else // multi sel & current is highlighted & no mod keys
{
@ -2616,16 +2694,15 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
{
ChangeCurrent(current);
size_t lineFrom = oldCurrent,
lineTo = current;
if ( lineTo < lineFrom )
if ( oldCurrent == (size_t)-1 )
{
lineTo = lineFrom;
lineFrom = m_current;
// Highlight m_current only if there is no previous selection.
HighlightLine(m_current);
}
else if ( oldCurrent != current && m_anchor != (size_t)-1 )
{
ExtendSelection(oldCurrent, current);
}
HighlightLines(lineFrom, lineTo);
}
else // !ctrl, !shift
{
@ -2634,7 +2711,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
}
}
if (m_current != oldCurrent)
if (m_current != oldCurrent && oldCurrent != (size_t)-1)
RefreshLine( oldCurrent );
// Set the flag telling us whether the next click on this item should
@ -2739,6 +2816,81 @@ bool wxListMainWindow::ScrollList(int WXUNUSED(dx), int dy)
// keyboard handling
// ----------------------------------------------------------------------------
// Helper function which handles items selection correctly and efficiently. and
// simply, mimic the wxMSW behaviour. And The benefit of this function is that it
// ensures that wxEVT_LIST_ITEM_{DE}SELECTED events are only generated for items
// freshly (de)selected (i.e. items that have really changed state). Useful for
// multi-selection mode when selecting using mouse or arrows with Shift key down.
void wxListMainWindow::ExtendSelection(size_t oldCurrent, size_t newCurrent)
{
// Refresh the old/new focus to remove/add it
RefreshLine(oldCurrent);
RefreshLine(newCurrent);
// Given a selection [anchor, old], to change/extend it to new (i.e. the
// selection becomes [anchor, new]) we discriminate three possible cases:
//
// Case 1) new < old <= anchor || anchor <= old < new
// i.e. oldCurrent between anchor and newCurrent, in which case we:
// - Highlight everything between anchor and newCurrent (inclusive).
//
// Case 2) old < new <= anchor || anchor <= new < old
// i.e. newCurrent between anchor and oldCurrent, in which case we:
// - Unhighlight everything between oldCurrent and newCurrent (exclusive).
//
// Case 3) old < anchor < new || new < anchor < old
// i.e. anchor between oldCurrent and newCurrent, in which case we
// - Highlight everything between anchor and newCurrent (inclusive).
// - Unhighlight everything between anchor (exclusive) and oldCurrent.
size_t lineFrom, lineTo;
if ( (newCurrent < oldCurrent && oldCurrent <= m_anchor) ||
(newCurrent > oldCurrent && oldCurrent >= m_anchor) )
{
lineFrom = m_anchor;
lineTo = newCurrent;
HighlightLines(lineFrom, lineTo);
}
else if ( (oldCurrent < newCurrent && newCurrent <= m_anchor) ||
(oldCurrent > newCurrent && newCurrent >= m_anchor) )
{
lineFrom = oldCurrent;
lineTo = newCurrent;
// Exclude newCurrent from being deselected
(lineTo < lineFrom) ? ++lineTo : --lineTo;
HighlightLines(lineFrom, lineTo, false);
// For virtual listctrl (in multi-selection mode), wxMSW sends only
// a notification to indicate that something has been deselected.
if ( IsVirtual() )
SendNotify((size_t)-1, wxEVT_LIST_ITEM_DESELECTED);
}
else if ( (oldCurrent < m_anchor && m_anchor < newCurrent) ||
(newCurrent < m_anchor && m_anchor < oldCurrent) )
{
lineFrom = m_anchor;
lineTo = oldCurrent;
// Exclude anchor from being deselected
(lineTo < lineFrom) ? --lineFrom : ++lineFrom;
HighlightLines(lineFrom, lineTo, false);
// See above.
if ( IsVirtual() )
SendNotify((size_t)-1, wxEVT_LIST_ITEM_DESELECTED);
lineFrom = m_anchor;
lineTo = newCurrent;
HighlightLines(lineFrom, lineTo);
}
}
void wxListMainWindow::OnArrowChar(size_t newCurrent, const wxKeyEvent& event)
{
wxCHECK_RET( newCurrent < (size_t)GetItemCount(),
@ -2746,43 +2898,34 @@ void wxListMainWindow::OnArrowChar(size_t newCurrent, const wxKeyEvent& event)
size_t oldCurrent = m_current;
ChangeCurrent(newCurrent);
// in single selection we just ignore Shift as we can't select several
// items anyhow
if ( event.ShiftDown() && !IsSingleSel() )
{
ChangeCurrent(newCurrent);
// refresh the old focus to remove it
RefreshLine( oldCurrent );
// select all the items between the old and the new one
if ( oldCurrent > newCurrent )
{
newCurrent = oldCurrent;
oldCurrent = m_current;
}
HighlightLines(oldCurrent, newCurrent);
ExtendSelection(oldCurrent, newCurrent);
}
else // !shift
{
// all previously selected items are unselected unless ctrl is held
// in a multiselection control
// all previously selected items are unselected unless ctrl is held in
// a multi-selection control. in single selection mode we must always
// have a selected item.
if ( !event.ControlDown() || IsSingleSel() )
HighlightAll(false);
{
HighlightOnly(m_current, oldCurrent);
ChangeCurrent(newCurrent);
// refresh the old focus to remove it
RefreshLine( oldCurrent );
// in single selection mode we must always have a selected item
if ( !event.ControlDown() || IsSingleSel() )
HighlightLine( m_current, true );
// Update anchor
m_anchor = m_current;
}
else
{
// refresh the old/new focus to remove/add it
RefreshLine(oldCurrent);
RefreshLine(m_current);
}
}
RefreshLine( m_current );
MoveToFocus();
}
@ -2799,10 +2942,11 @@ void wxListMainWindow::OnKeyDown( wxKeyEvent &event )
// send a list event
wxListEvent le( wxEVT_LIST_KEY_DOWN, parent->GetId() );
const size_t current = ShouldSendEventForCurrent() ? m_current : (size_t)-1;
le.m_item.m_itemId =
le.m_itemIndex = m_current;
if (HasCurrent())
GetLine(m_current)->GetItem( 0, le.m_item );
le.m_itemIndex = current;
if ( current != (size_t)-1 )
GetLine(current)->GetItem( 0, le.m_item );
le.m_code = event.GetKeyCode();
le.SetEventObject( parent );
if (parent->GetEventHandler()->ProcessEvent( le ))
@ -2956,7 +3100,7 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
{
ReverseHighlight(m_current);
}
else // normal space press
else if ( ShouldSendEventForCurrent() ) // normal space press
{
SendNotify( m_current, wxEVT_LIST_ITEM_ACTIVATED );
}
@ -2969,7 +3113,7 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
case WXK_RETURN:
case WXK_EXECUTE:
if ( event.HasModifiers() )
if ( event.HasModifiers() || !ShouldSendEventForCurrent() )
{
event.Skip();
break;
@ -3078,6 +3222,7 @@ void wxListMainWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
{
m_hasFocus = true;
UpdateCurrent();
RefreshSelected();
}
}
@ -3621,17 +3766,7 @@ int wxListMainWindow::GetSelectedItemCount() const
if ( IsVirtual() )
return m_selStore.GetSelectedCount();
// TODO: we probably should maintain the number of items selected even for
// non virtual controls as enumerating all lines is really slow...
size_t countSel = 0;
size_t count = GetItemCount();
for ( size_t line = 0; line < count; line++ )
{
if ( GetLine(line)->IsHighlighted() )
countSel++;
}
return countSel;
return m_selCount;
}
// ----------------------------------------------------------------------------
@ -4036,9 +4171,6 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
if ( !noRefresh )
{
// FIXME: why should we call it from here?
UpdateCurrent();
RefreshAll();
}
}
@ -4059,7 +4191,13 @@ void wxListMainWindow::RefreshAll()
void wxListMainWindow::UpdateCurrent()
{
if ( !HasCurrent() && !IsEmpty() )
ChangeCurrent(0);
{
// Initialise m_current to the first item without sending any
// wxEVT_LIST_ITEM_FOCUSED event (typicaly when the control gains focus)
// and this is to allow changing the focused item using the arrow keys.
// which is the behaviour found in the wxMSW port.
ChangeCurrentWithoutEvent(0);
}
}
long wxListMainWindow::GetNextItem( long item,
@ -4248,6 +4386,10 @@ void wxListMainWindow::DoDeleteAllItems()
m_countVirt = 0;
m_selStore.Clear();
}
else
{
m_selCount = 0;
}
if ( InReportView() )
ResetVisibleLinesRange();

View File

@ -684,8 +684,9 @@ void wxTextCtrl::Init()
m_text = NULL;
m_buffer = NULL;
m_showPositionOnThaw = NULL;
m_showPositionDefer = NULL;
m_anonymousMarkList = NULL;
m_afterLayoutId = 0;
}
wxTextCtrl::~wxTextCtrl()
@ -702,6 +703,8 @@ wxTextCtrl::~wxTextCtrl()
if (m_anonymousMarkList)
g_slist_free(m_anonymousMarkList);
if (m_afterLayoutId)
g_source_remove(m_afterLayoutId);
}
wxTextCtrl::wxTextCtrl( wxWindow *parent,
@ -1102,6 +1105,25 @@ bool wxTextCtrl::IsEmpty() const
return wxTextEntry::IsEmpty();
}
void wxTextCtrl::GTKAfterLayout()
{
m_afterLayoutId = 0;
if (m_showPositionDefer && !IsFrozen())
{
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(m_text), m_showPositionDefer);
m_showPositionDefer = NULL;
}
}
extern "C" {
static gboolean afterLayout(void* data)
{
wxTextCtrl* win = static_cast<wxTextCtrl*>(data);
win->GTKAfterLayout();
return false;
}
}
void wxTextCtrl::WriteText( const wxString &text )
{
wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") );
@ -1163,15 +1185,16 @@ void wxTextCtrl::WriteText( const wxString &text )
gtk_text_buffer_delete_selection(m_buffer, false, true);
// Insert the text
GtkTextMark* insertMark = gtk_text_buffer_get_insert(m_buffer);
GtkTextIter iter;
gtk_text_buffer_get_iter_at_mark( m_buffer, &iter,
gtk_text_buffer_get_insert (m_buffer) );
gtk_text_buffer_get_iter_at_mark(m_buffer, &iter, insertMark);
const bool insertIsEnd = gtk_text_iter_is_end(&iter) != 0;
gtk_text_buffer_insert( m_buffer, &iter, buffer, buffer.length() );
// Scroll to cursor, but only if scrollbar thumb is at the very bottom
// won't work when frozen, text view is not using m_buffer then
if (!IsFrozen())
// Scroll to cursor, if it is at the end and scrollbar thumb is at the bottom
if (insertIsEnd)
{
GtkAdjustment* adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(m_widget));
const double value = gtk_adjustment_get_value(adj);
@ -1179,10 +1202,19 @@ void wxTextCtrl::WriteText( const wxString &text )
const double page_size = gtk_adjustment_get_page_size(adj);
if (wxIsSameDouble(value, upper - page_size))
{
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(m_text),
gtk_text_buffer_get_insert(m_buffer), 0, false, 0, 1);
if (!IsFrozen())
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(m_text), insertMark);
// GtkTextView's incremental background layout makes scrolling
// to end unreliable until the layout has been completed
m_showPositionDefer = insertMark;
}
}
if (m_afterLayoutId == 0)
{
m_afterLayoutId =
g_idle_add_full(GTK_TEXT_VIEW_PRIORITY_VALIDATE + 1, afterLayout, this, NULL);
}
}
wxString wxTextCtrl::GetLineText( long lineNo ) const
@ -1363,7 +1395,7 @@ void wxTextCtrl::SetInsertionPoint( long pos )
GtkTextMark* mark = gtk_text_buffer_get_insert(m_buffer);
if (IsFrozen())
// defer until Thaw, text view is not using m_buffer now
m_showPositionOnThaw = mark;
m_showPositionDefer = mark;
else
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(m_text), mark);
}
@ -1480,7 +1512,7 @@ void wxTextCtrl::ShowPosition( long pos )
gtk_text_buffer_move_mark(m_buffer, mark, &iter);
if (IsFrozen())
// defer until Thaw, text view is not using m_buffer now
m_showPositionOnThaw = mark;
m_showPositionDefer = mark;
else
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(m_text), mark);
}
@ -2136,11 +2168,11 @@ void wxTextCtrl::DoThaw()
g_object_unref(m_buffer);
g_signal_handler_disconnect(m_buffer, sig_id);
if (m_showPositionOnThaw != NULL)
if (m_showPositionDefer)
{
gtk_text_view_scroll_mark_onscreen(
GTK_TEXT_VIEW(m_text), m_showPositionOnThaw);
m_showPositionOnThaw = NULL;
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(m_text), m_showPositionDefer);
if (m_afterLayoutId == 0)
m_showPositionDefer = NULL;
}
}

View File

@ -14,6 +14,7 @@
#include "wx/dir.h"
#include "wx/dynlib.h"
#include "wx/filename.h"
#include "wx/stdpaths.h"
#include "wx/stockitem.h"
#include "wx/gtk/webview_webkit.h"
#include "wx/gtk/control.h"
@ -369,7 +370,7 @@ wxgtk_webview_webkit_counted_matches(WebKitFindController *,
}
// This function checks if the specified directory contains our web extension.
static bool CheckDirectoryForWebExt(const char* dirname)
static bool CheckDirectoryForWebExt(const wxString& dirname)
{
wxDir dir;
if ( !wxDir::Exists(dirname) || !dir.Open(dirname) )
@ -399,6 +400,23 @@ static bool CheckDirectoryForWebExt(const char* dirname)
return false;
}
static bool TrySetWebExtensionsDirectory(WebKitWebContext *context, const wxString& dir)
{
if (dir.empty() || !CheckDirectoryForWebExt(dir))
return false;
webkit_web_context_set_web_extensions_directory(context, dir.utf8_str());
return true;
}
static wxString GetStandardWebExtensionsDir()
{
wxString dir = wxDynamicLibrary::GetPluginsDirectory();
if ( !dir.empty() )
dir += "/web-extensions";
return dir;
}
static void
wxgtk_initialize_web_extensions(WebKitWebContext *context,
GDBusServer *dbusServer)
@ -406,36 +424,28 @@ wxgtk_initialize_web_extensions(WebKitWebContext *context,
const char *address = g_dbus_server_get_client_address(dbusServer);
GVariant *user_data = g_variant_new("(s)", address);
// The first value is the location in which the extension is supposed to be
// normally installed, while the other three are used as fallbacks to allow
// running the tests and sample using wxWebView before installing it.
const char* const directories[] =
// Try to setup extension loading from the location it is supposed to be
// normally installed in.
if ( !TrySetWebExtensionsDirectory(context, GetStandardWebExtensionsDir()) )
{
WX_WEB_EXTENSIONS_DIRECTORY,
"..",
"../..",
"lib",
};
const char* dir = NULL;
for ( size_t n = 0; n < WXSIZEOF(directories); ++n )
{
if ( CheckDirectoryForWebExt(directories[n]) )
// These relative locations are used as fallbacks to allow running
// the tests and sample using wxWebView before installing it.
wxString exepath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath();
if ( !exepath.empty() )
{
dir = directories[n];
break;
}
}
wxString const directories[] =
{
exepath + "/..",
exepath + "/../..",
exepath + "/lib",
};
if ( dir )
{
webkit_web_context_set_web_extensions_directory(context, dir);
}
else
{
wxLogWarning(_("Web extension not found in \"%s\", "
"some wxWebView functionality will be not available"),
WX_WEB_EXTENSIONS_DIRECTORY);
for ( size_t n = 0; n < WXSIZEOF(directories); ++n )
{
if ( !TrySetWebExtensionsDirectory(context, directories[n]) )
break;
}
}
}
webkit_web_context_set_web_extensions_initialization_user_data(context,
@ -1020,10 +1030,11 @@ bool wxWebViewWebKit::IsEditable() const
void wxWebViewWebKit::DeleteSelection()
{
if (m_extension)
GDBusProxy *extension = GetExtensionProxy();
if (extension)
{
guint64 page_id = webkit_web_view_get_page_id(m_web_view);
GVariant *retval = g_dbus_proxy_call_sync(m_extension,
GVariant *retval = g_dbus_proxy_call_sync(extension,
"DeleteSelection",
g_variant_new("(t)", page_id),
G_DBUS_CALL_FLAGS_NONE, -1,
@ -1037,10 +1048,11 @@ void wxWebViewWebKit::DeleteSelection()
bool wxWebViewWebKit::HasSelection() const
{
if (m_extension)
GDBusProxy *extension = GetExtensionProxy();
if (extension)
{
guint64 page_id = webkit_web_view_get_page_id(m_web_view);
GVariant *retval = g_dbus_proxy_call_sync(m_extension,
GVariant *retval = g_dbus_proxy_call_sync(extension,
"HasSelection",
g_variant_new("(t)", page_id),
G_DBUS_CALL_FLAGS_NONE, -1,
@ -1064,10 +1076,11 @@ void wxWebViewWebKit::SelectAll()
wxString wxWebViewWebKit::GetSelectedText() const
{
if (m_extension)
GDBusProxy *extension = GetExtensionProxy();
if (extension)
{
guint64 page_id = webkit_web_view_get_page_id(m_web_view);
GVariant *retval = g_dbus_proxy_call_sync(m_extension,
GVariant *retval = g_dbus_proxy_call_sync(extension,
"GetSelectedText",
g_variant_new("(t)", page_id),
G_DBUS_CALL_FLAGS_NONE, -1,
@ -1085,10 +1098,11 @@ wxString wxWebViewWebKit::GetSelectedText() const
wxString wxWebViewWebKit::GetSelectedSource() const
{
if (m_extension)
GDBusProxy *extension = GetExtensionProxy();
if (extension)
{
guint64 page_id = webkit_web_view_get_page_id(m_web_view);
GVariant *retval = g_dbus_proxy_call_sync(m_extension,
GVariant *retval = g_dbus_proxy_call_sync(extension,
"GetSelectedSource",
g_variant_new("(t)", page_id),
G_DBUS_CALL_FLAGS_NONE, -1,
@ -1106,10 +1120,11 @@ wxString wxWebViewWebKit::GetSelectedSource() const
void wxWebViewWebKit::ClearSelection()
{
if (m_extension)
GDBusProxy *extension = GetExtensionProxy();
if (extension)
{
guint64 page_id = webkit_web_view_get_page_id(m_web_view);
GVariant *retval = g_dbus_proxy_call_sync(m_extension,
GVariant *retval = g_dbus_proxy_call_sync(extension,
"ClearSelection",
g_variant_new("(t)", page_id),
G_DBUS_CALL_FLAGS_NONE, -1,
@ -1123,10 +1138,11 @@ void wxWebViewWebKit::ClearSelection()
wxString wxWebViewWebKit::GetPageText() const
{
if (m_extension)
GDBusProxy *extension = GetExtensionProxy();
if (extension)
{
guint64 page_id = webkit_web_view_get_page_id(m_web_view);
GVariant *retval = g_dbus_proxy_call_sync(m_extension,
GVariant *retval = g_dbus_proxy_call_sync(extension,
"GetPageText",
g_variant_new("(t)", page_id),
G_DBUS_CALL_FLAGS_NONE, -1,
@ -1410,4 +1426,15 @@ void wxWebViewWebKit::SetupWebExtensionServer()
g_object_unref(observer);
}
GDBusProxy *wxWebViewWebKit::GetExtensionProxy() const
{
if (!m_extension)
{
g_warning("Web extension not found in \"%s\", "
"some wxWebView functionality will be not available",
(const char*)GetStandardWebExtensionsDir().utf8_str());
}
return m_extension;
}
#endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT2

View File

@ -2118,6 +2118,28 @@ wxPoint wxMSWDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const
return wxPoint(p[0].x, p[0].y);
}
wxSize wxMSWDCImpl::DeviceToLogicalRel(int x, int y) const
{
POINT p[2];
p[0].x = 0;
p[0].y = 0;
p[1].x = x;
p[1].y = y;
::DPtoLP(GetHdc(), p, WXSIZEOF(p));
return wxSize(p[1].x-p[0].x, p[1].y-p[0].y);
}
wxSize wxMSWDCImpl::LogicalToDeviceRel(int x, int y) const
{
POINT p[2];
p[0].x = 0;
p[0].y = 0;
p[1].x = x;
p[1].y = y;
::LPtoDP(GetHdc(), p, WXSIZEOF(p));
return wxSize(p[1].x-p[0].x, p[1].y-p[0].y);
}
// ----------------------------------------------------------------------------
// Transform matrix
// ----------------------------------------------------------------------------

View File

@ -4494,11 +4494,11 @@ void wxD2DContext::DrawBitmap(const wxGraphicsBitmap& bmp, wxDouble x, wxDouble
wxD2DBitmapData* bitmapData = wxGetD2DBitmapData(bmp);
bitmapData->Bind(this);
D2D1_SIZE_F imgSize = bitmapData->GetD2DBitmap()->GetSize();
wxBitmap const& bitmap = static_cast<wxD2DBitmapData::NativeType*>(bitmapData->GetNativeBitmap())->GetSourceBitmap();
m_renderTargetHolder->DrawBitmap(
bitmapData->GetD2DBitmap(),
D2D1::RectF(0, 0, imgSize.width, imgSize.height),
D2D1::RectF(0, 0, bitmap.GetWidth(), bitmap.GetHeight()),
D2D1::RectF(x, y, x + w, y + h),
GetInterpolationQuality(),
GetCompositionMode());

View File

@ -788,7 +788,15 @@ bool wxListCtrl::SetColumnWidth(int col, int width)
else if ( width == wxLIST_AUTOSIZE_USEHEADER)
width = LVSCW_AUTOSIZE_USEHEADER;
return ListView_SetColumnWidth(GetHwnd(), col, width) != 0;
if ( !ListView_SetColumnWidth(GetHwnd(), col, width) )
return false;
// Failure to explicitly refresh the control with horizontal rules results
// in corrupted rules display.
if ( HasFlag(wxLC_HRULES) )
Refresh();
return true;
}
// ----------------------------------------------------------------------------
@ -3261,12 +3269,7 @@ void wxListCtrl::OnPaint(wxPaintEvent& event)
dc.SetPen(pen);
dc.SetBrush(* wxTRANSPARENT_BRUSH);
// Find the coordinate of the right most visible point: this is not the
// same as GetClientSize().x because the window might not be fully visible,
// it could be clipped by its parent.
const int availableWidth = GetParent()->GetClientSize().x - GetPosition().x;
int visibleWidth = wxMin(GetClientSize().x,
availableWidth - GetWindowBorderSize().x);
wxSize clientSize = GetClientSize();
const int countPerPage = GetCountPerPage();
if (countPerPage < 0)
@ -3278,9 +3281,6 @@ void wxListCtrl::OnPaint(wxPaintEvent& event)
const long top = GetTopItem();
const long bottom = wxMin(top + countPerPage, itemCount - 1);
wxRect clipRect;
dc.GetClippingBox(clipRect);
if (drawHRules)
{
wxRect itemRect;
@ -3289,23 +3289,9 @@ void wxListCtrl::OnPaint(wxPaintEvent& event)
if (GetItemRect(i, itemRect))
{
const int cy = itemRect.GetBottom();
dc.DrawLine(clipRect.x, cy, clipRect.GetRight() + 1, cy);
dc.DrawLine(0, cy, clientSize.x, cy);
}
}
/*
The drawing can be clipped horizontally to the rightmost column.
This happens when an item is added (and visible) and results in a
horizontal rule being clipped instead of drawn across the entire
list control. In that case we request for the part to the right of
the rightmost column to be drawn as well.
*/
if ( clipRect.GetRight() < visibleWidth - 1 && clipRect.width )
{
RefreshRect(wxRect(clipRect.GetRight(), clipRect.y,
visibleWidth - clipRect.width, clipRect.height),
false /* don't erase background */);
}
}
if (drawVRules)
@ -3347,7 +3333,7 @@ void wxListCtrl::OnPaint(wxPaintEvent& event)
wxDCBrushChanger changeBrush(dc, GetBackgroundColour());
dc.DrawRectangle(0, topItemRect.GetY() - gap,
visibleWidth, gap);
clientSize.GetWidth(), gap);
}
const int numCols = GetColumnCount();

View File

@ -313,15 +313,28 @@ bool wxSlider::MSWOnScroll(int WXUNUSED(orientation),
SetValue(newPos);
wxScrollEvent event(scrollEvent, m_windowId);
bool processed = false;
event.SetPosition(newPos);
event.SetEventObject( this );
HandleWindowEvent(event);
processed = HandleWindowEvent(event);
wxCommandEvent cevent( wxEVT_SLIDER, GetId() );
cevent.SetInt( newPos );
cevent.SetEventObject( this );
// Do not generate wxEVT_SLIDER when the native scroll message
// parameter is SB_ENDSCROLL, which always follows only after
// another scroll message which already changed the slider value.
// Therefore, sending wxEVT_SLIDER after SB_ENDSCROLL
// would result in two wxEVT_SLIDER events with the same value.
if ( wParam != SB_ENDSCROLL )
{
wxCommandEvent cevent( wxEVT_SLIDER, GetId() );
return HandleWindowEvent( cevent );
cevent.SetInt( newPos );
cevent.SetEventObject( this );
processed = HandleWindowEvent( cevent );
}
return processed;
}
void wxSlider::Command (wxCommandEvent & event)

View File

@ -518,7 +518,7 @@ void wxWidgetCocoaImpl::SetupKeyEvent(wxKeyEvent &wxevent , NSEvent * nsEvent, N
}
}
if ( !keyval )
if ( !keyval && aunichar < 256 ) // only for ASCII characters
{
if ( wxevent.GetEventType() == wxEVT_KEY_UP || wxevent.GetEventType() == wxEVT_KEY_DOWN )
keyval = wxToupper( aunichar ) ;

View File

@ -355,7 +355,6 @@ void wxPropertyGrid::Init1()
m_inOnValidationFailure = false;
m_permanentValidationFailureBehavior = wxPG_VFB_DEFAULT;
m_dragStatus = 0;
m_mouseSide = 16;
m_editorFocused = false;
// Set up default unspecified value 'colour'
@ -5002,8 +5001,11 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y,
int splitterHit;
int splitterHitOffset;
int columnHit = state->HitTestH( x, &splitterHit, &splitterHitOffset );
int splitterX = x - splitterHitOffset;
#if wxUSE_TOOLTIPS
wxPGProperty* prevHover = m_propHover;
int prevCol = m_colHover;
#endif
m_colHover = columnHit;
if ( m_dragStatus > 0 )
@ -5012,6 +5014,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y,
x < (m_pState->GetVirtualWidth() - wxPG_DRAG_MARGIN) )
{
int splitterX = x - splitterHitOffset;
int newSplitterX = x - m_dragOffset;
// Splitter redraw required?
@ -5042,10 +5045,6 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y,
int ih = m_lineHeight;
int sy = y;
#if wxUSE_TOOLTIPS
wxPGProperty* prevHover = m_propHover;
unsigned char prevSide = m_mouseSide;
#endif
int curPropHoverY = y - (y % ih);
// On which item it hovers
@ -5064,20 +5063,13 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y,
}
#if wxUSE_TOOLTIPS
// Store which side we are on
m_mouseSide = 0;
if ( columnHit == 1 )
m_mouseSide = 2;
else if ( columnHit == 0 )
m_mouseSide = 1;
//
// If tooltips are enabled, show label or value as a tip
// in case it doesn't otherwise show in full length.
//
if ( m_windowStyle & wxPG_TOOLTIPS )
{
if ( m_propHover != prevHover || prevSide != m_mouseSide )
if ( m_propHover != prevHover || prevCol != m_colHover )
{
if ( m_propHover && !m_propHover->IsCategory() )
{
@ -5089,40 +5081,59 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y,
SetToolTip(tipString);
}
else
else if ( m_colHover >= 0 && m_colHover < (int)m_pState->GetColumnCount())
{
// Show cropped value string as a tooltip
wxString tipString;
int space = 0;
wxPGCell cell;
int item = ( m_colHover == 1 ? m_propHover->GetChoiceSelection() : -1 );
m_propHover->GetDisplayInfo(m_colHover, item, 0, &tipString, &cell);
int space = m_pState->GetColumnWidth(m_colHover);
if ( m_mouseSide == 1 )
int imageWidth = 0;
const wxBitmap& bmp = cell.GetBitmap();
if ( bmp.IsOk() )
{
tipString = m_propHover->GetLabel();
space = splitterX-m_marginWidth-3;
}
else if ( m_mouseSide == 2 )
{
tipString = m_propHover->GetDisplayedString();
space = m_width - splitterX;
if ( m_propHover->HasFlag(wxPG_PROP_CUSTOMIMAGE) )
space -= wxPG_CUSTOM_IMAGE_WIDTH +
wxCC_CUSTOM_IMAGE_MARGIN1 +
wxCC_CUSTOM_IMAGE_MARGIN2;
imageWidth = bmp.GetWidth();
int hMax = m_lineHeight - wxPG_CUSTOM_IMAGE_SPACINGY - 1;
if ( bmp.GetHeight() > hMax )
imageWidth *= (double)hMax / bmp.GetHeight();
}
if ( space )
if ( m_colHover == 0 )
{
int tw, th;
GetTextExtent( tipString, &tw, &th, 0, 0 );
if ( tw > space )
SetToolTip( tipString );
if ( !(m_windowStyle & wxPG_HIDE_CATEGORIES) || m_propHover->GetParent() != m_pState->DoGetRoot() )
space -= (m_propHover->GetDepth()-1)*m_subgroup_extramargin;
}
else
else if ( m_colHover == 1 && !m_propHover->IsValueUnspecified())
{
SetToolTip(wxEmptyString);
wxSize imageSize = GetImageSize(m_propHover, -1);
if ( imageSize.x > 0 )
imageWidth = imageSize.x;
tipString = m_propHover->GetValueAsString();
if ( GetColumnCount() <= 2 )
{
wxString unitsString = m_propHover->GetAttribute(wxPG_ATTR_UNITS, wxEmptyString);
if ( !unitsString.empty() )
tipString = wxString::Format(wxS("%s %s"), tipString, unitsString );
}
}
space -= m_propHover->GetImageOffset(imageWidth);
space -= (wxPG_XBEFORETEXT + 1);
int tw, th;
const wxFont* font = NULL;
if ( (m_windowStyle & wxPG_BOLD_MODIFIED) && m_propHover->HasFlag(wxPG_PROP_MODIFIED) )
font = &m_captionFont;
if ( cell.GetFont().IsOk() )
font = &cell.GetFont();
GetTextExtent( tipString, &tw, &th, 0, 0, font );
if ( tw > space )
SetToolTip( tipString );
}
else
{
SetToolTip(wxEmptyString);
}
}
else

View File

@ -298,7 +298,7 @@ bool wxSingleInstanceCheckerImpl::Create(const wxString& name)
// message is that the previous instance of the program
// crashed), don't show it by default, i.e. unless the
// program is running with --verbose command line option.
wxLogInfo(_("Deleted stale lock file '%s'."),
wxLogVerbose(_("Deleted stale lock file '%s'."),
name.c_str());
// retry now

View File

@ -185,6 +185,7 @@ TEST_GUI_OBJECTS = \
test_gui_affinematrix.o \
test_gui_boundingbox.o \
test_gui_clippingbox.o \
test_gui_coords.o \
test_gui_graphmatrix.o \
test_gui_graphpath.o \
test_gui_config.o \
@ -547,7 +548,7 @@ data:
data-images:
@mkdir -p image
@for f in horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png; do \
@for f in horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png; do \
if test ! -f image/$$f -a ! -d image/$$f ; \
then x=yep ; \
else x=`find $(srcdir)/image/$$f -newer image/$$f -print` ; \
@ -899,6 +900,9 @@ test_gui_boundingbox.o: $(srcdir)/graphics/boundingbox.cpp $(TEST_GUI_ODEP)
test_gui_clippingbox.o: $(srcdir)/graphics/clippingbox.cpp $(TEST_GUI_ODEP)
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/graphics/clippingbox.cpp
test_gui_coords.o: $(srcdir)/graphics/coords.cpp $(TEST_GUI_ODEP)
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/graphics/coords.cpp
test_gui_graphmatrix.o: $(srcdir)/graphics/graphmatrix.cpp $(TEST_GUI_ODEP)
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/graphics/graphmatrix.cpp

View File

@ -24,9 +24,6 @@
#include "itemcontainertest.h"
#include "asserthelper.h"
//Test only if we are based off of wxComboBox
#ifndef wxGENERIC_BITMAPCOMBOBOX
class BitmapComboBoxTestCase : public TextEntryTestCase,
public ItemContainerTestCase,
public CppUnit::TestCase
@ -82,9 +79,9 @@ void BitmapComboBoxTestCase::Bitmap()
wxArrayString items;
items.push_back("item 0");
items.push_back("item 1");
//We need this otherwise MSVC complains as it cannot find a suitable append
static_cast<wxComboBox*>(m_combo)->Append(items);
// TODO: Add wxBitmapComboBoxBase::Append(wxArrayString )
for( unsigned int i = 0; i < items.size(); ++i )
m_combo->Append(items[i]);
CPPUNIT_ASSERT(!m_combo->GetItemBitmap(0).IsOk());
@ -104,8 +101,10 @@ void BitmapComboBoxTestCase::Bitmap()
CPPUNIT_ASSERT(m_combo->GetItemBitmap(0).IsOk());
CPPUNIT_ASSERT_EQUAL(wxSize(16, 16), m_combo->GetBitmapSize());
m_combo->SetSelection( 1 );
CPPUNIT_ASSERT_EQUAL( m_combo->GetStringSelection(), "item with bitmap" );
}
#endif //wxGENERIC_BITMAPCOMBOBOX
#endif //wxUSE_BITMAPCOMBOBOX

View File

@ -26,6 +26,7 @@
#include "wx/uiaction.h"
#include "wx/imaglist.h"
#include "wx/artprov.h"
#include "wx/stopwatch.h"
void ListBaseTestCase::ColumnsOrder()
{
@ -177,6 +178,123 @@ void ListBaseTestCase::ChangeMode()
CPPUNIT_ASSERT_EQUAL( "First", list->GetItemText(0) );
}
#ifdef __WXGTK__
#define wxGTK_TIMED_YIELD(t) \
if ( !IsRunningUnderXVFB() ) \
for ( wxStopWatch sw; sw.Time() < t; ) wxYield()
#else // !__WXGTK__
#define wxGTK_TIMED_YIELD(t)
#endif // __WXGTK__
void ListBaseTestCase::MultiSelect()
{
#if wxUSE_UIACTIONSIMULATOR
#ifndef __WXMSW__
// FIXME: This test fails on Travis CI although works fine on
// development machine, no idea why though!
if ( IsAutomaticTest() )
return;
#endif // !__WXMSW__
wxListCtrl* const list = GetList();
EventCounter focused(list, wxEVT_LIST_ITEM_FOCUSED);
EventCounter selected(list, wxEVT_LIST_ITEM_SELECTED);
EventCounter deselected(list, wxEVT_LIST_ITEM_DESELECTED);
list->InsertColumn(0, "Header");
for ( int i = 0; i < 10; ++i )
list->InsertItem(i, wxString::Format("Item %d", i));
wxUIActionSimulator sim;
wxRect pos;
list->GetItemRect(2, pos); // Choose the third item as anchor
// We move in slightly so we are not on the edge
wxPoint point = list->ClientToScreen(pos.GetPosition()) + wxPoint(10, 10);
sim.MouseMove(point);
wxYield();
sim.MouseClick(); // select the anchor
wxYield();
wxGTK_TIMED_YIELD(50);
list->GetItemRect(5, pos);
point = list->ClientToScreen(pos.GetPosition()) + wxPoint(10, 10);
sim.MouseMove(point);
wxYield();
sim.KeyDown(WXK_SHIFT);
sim.MouseClick();
sim.KeyUp(WXK_SHIFT);
wxYield();
wxGTK_TIMED_YIELD(10);
// when the first item was selected the focus changes to it, but not
// on subsequent clicks
CPPUNIT_ASSERT_EQUAL(4, list->GetSelectedItemCount()); // item 2 to 5 (inclusive) are selected
CPPUNIT_ASSERT_EQUAL(2, focused.GetCount()); // count the focus which was on the anchor
CPPUNIT_ASSERT_EQUAL(4, selected.GetCount());
CPPUNIT_ASSERT_EQUAL(0, deselected.GetCount());
focused.Clear();
selected.Clear();
deselected.Clear();
sim.Char(WXK_END, wxMOD_SHIFT); // extend the selection to the last item
wxYield();
wxGTK_TIMED_YIELD(10);
CPPUNIT_ASSERT_EQUAL(8, list->GetSelectedItemCount()); // item 2 to 9 (inclusive) are selected
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount()); // focus is on the last item
CPPUNIT_ASSERT_EQUAL(4, selected.GetCount()); // only newly selected items got the event
CPPUNIT_ASSERT_EQUAL(0, deselected.GetCount());
focused.Clear();
selected.Clear();
deselected.Clear();
sim.Char(WXK_HOME, wxMOD_SHIFT); // select from anchor to the first item
wxYield();
wxGTK_TIMED_YIELD(10);
CPPUNIT_ASSERT_EQUAL(3, list->GetSelectedItemCount()); // item 0 to 2 (inclusive) are selected
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount()); // focus is on item 0
CPPUNIT_ASSERT_EQUAL(2, selected.GetCount()); // events are only generated for item 0 and 1
CPPUNIT_ASSERT_EQUAL(7, deselected.GetCount()); // item 2 (exclusive) to 9 are deselected
focused.Clear();
selected.Clear();
deselected.Clear();
list->EnsureVisible(0);
wxYield();
list->GetItemRect(2, pos);
point = list->ClientToScreen(pos.GetPosition()) + wxPoint(10, 10);
sim.MouseMove(point);
wxYield();
sim.MouseClick();
wxYield();
CPPUNIT_ASSERT_EQUAL(1, list->GetSelectedItemCount()); // anchor is the only selected item
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount()); // because the focus changed from item 0 to anchor
CPPUNIT_ASSERT_EQUAL(0, selected.GetCount()); // anchor is already in selection state
CPPUNIT_ASSERT_EQUAL(2, deselected.GetCount()); // items 0 and 1 are deselected
#endif // wxUSE_UIACTIONSIMULATOR
}
void ListBaseTestCase::ItemClick()
{
#if wxUSE_UIACTIONSIMULATOR
@ -236,16 +354,9 @@ void ListBaseTestCase::ItemClick()
// when the first item was selected the focus changes to it, but not
// on subsequent clicks
// FIXME: This test fail under wxGTK & wxOSX because we get 3 FOCUSED events and
// 2 SELECTED ones instead of the one of each we expect for some
// reason, this needs to be debugged as it may indicate a bug in the
// generic wxListCtrl implementation.
#ifndef _WX_GENERIC_LISTCTRL_H_
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount());
CPPUNIT_ASSERT_EQUAL(1, selected.GetCount());
CPPUNIT_ASSERT_EQUAL(1, deselected.GetCount());
#endif
CPPUNIT_ASSERT_EQUAL(1, activated.GetCount());
CPPUNIT_ASSERT_EQUAL(1, rclick.GetCount());
#endif // wxUSE_UIACTIONSIMULATOR

View File

@ -26,6 +26,7 @@ protected:
CPPUNIT_TEST( ChangeMode ); \
WXUISIM_TEST( ItemClick ); \
WXUISIM_TEST( KeyDown ); \
WXUISIM_TEST( MultiSelect ); \
CPPUNIT_TEST( DeleteItems ); \
CPPUNIT_TEST( InsertItem ); \
CPPUNIT_TEST( Find ); \
@ -40,6 +41,7 @@ protected:
void ItemRect();
void ItemText();
void ChangeMode();
void MultiSelect();
void ItemClick();
void KeyDown();
void DeleteItems();

View File

@ -20,6 +20,7 @@
#include "wx/listctrl.h"
#include "listbasetest.h"
#include "testableframe.h"
class ListViewTestCase : public ListBaseTestCase, public CppUnit::TestCase
{
@ -61,7 +62,8 @@ void ListViewTestCase::setUp()
void ListViewTestCase::tearDown()
{
wxDELETE(m_list);
DeleteTestWindow(m_list);
m_list = NULL;
}
void ListViewTestCase::Selection()
@ -104,6 +106,8 @@ void ListViewTestCase::Selection()
void ListViewTestCase::Focus()
{
EventCounter focused(m_list, wxEVT_LIST_ITEM_FOCUSED);
m_list->InsertColumn(0, "Column 0");
m_list->InsertItem(0, "Item 0");
@ -111,10 +115,12 @@ void ListViewTestCase::Focus()
m_list->InsertItem(2, "Item 2");
m_list->InsertItem(3, "Item 3");
CPPUNIT_ASSERT_EQUAL(0, focused.GetCount());
CPPUNIT_ASSERT_EQUAL(-1, m_list->GetFocusedItem());
m_list->Focus(0);
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount());
CPPUNIT_ASSERT_EQUAL(0, m_list->GetFocusedItem());
}

View File

@ -27,40 +27,19 @@
#include "testableframe.h"
#include "testwindow.h"
class RadioButtonTestCase : public CppUnit::TestCase
class RadioButtonTestCase
{
public:
RadioButtonTestCase() { }
void setUp() wxOVERRIDE;
void tearDown() wxOVERRIDE;
private:
CPPUNIT_TEST_SUITE( RadioButtonTestCase );
WXUISIM_TEST( Click );
CPPUNIT_TEST( Value );
CPPUNIT_TEST( Group );
CPPUNIT_TEST( Single );
CPPUNIT_TEST_SUITE_END();
void Click();
void Value();
void Group();
void Single();
RadioButtonTestCase();
~RadioButtonTestCase();
protected:
wxRadioButton* m_radio;
wxDECLARE_NO_COPY_CLASS(RadioButtonTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( RadioButtonTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( RadioButtonTestCase,
"RadioButtonTestCase" );
void RadioButtonTestCase::setUp()
RadioButtonTestCase::RadioButtonTestCase()
{
m_radio = new wxRadioButton(wxTheApp->GetTopWindow(), wxID_ANY,
"wxRadioButton");
@ -68,12 +47,12 @@ void RadioButtonTestCase::setUp()
m_radio->Refresh();
}
void RadioButtonTestCase::tearDown()
RadioButtonTestCase::~RadioButtonTestCase()
{
wxDELETE(m_radio);
delete m_radio;
}
void RadioButtonTestCase::Click()
TEST_CASE_METHOD(RadioButtonTestCase, "RadioButton::Click", "[radiobutton]")
{
// OS X doesn't support selecting a single radio button
#if wxUSE_UIACTIONSIMULATOR && !defined(__WXOSX__)
@ -87,87 +66,115 @@ void RadioButtonTestCase::Click()
wxYield();
CPPUNIT_ASSERT_EQUAL( 1, selected.GetCount() );
CHECK(selected.GetCount() == 1);
#endif
}
void RadioButtonTestCase::Value()
TEST_CASE_METHOD(RadioButtonTestCase, "RadioButton::Value", "[radiobutton]")
{
#ifndef __WXGTK__
EventCounter selected(m_radio, wxEVT_RADIOBUTTON);
m_radio->SetValue(true);
CPPUNIT_ASSERT(m_radio->GetValue());
CHECK(m_radio->GetValue());
m_radio->SetValue(false);
CPPUNIT_ASSERT(!m_radio->GetValue());
CHECK(!m_radio->GetValue());
CPPUNIT_ASSERT_EQUAL(0, selected.GetCount());
CHECK(selected.GetCount() == 0);
#endif
}
void RadioButtonTestCase::Group()
TEST_CASE_METHOD(RadioButtonTestCase, "RadioButton::Group", "[radiobutton]")
{
wxWindow* const parent = wxTheApp->GetTopWindow();
// Create two different radio groups.
wxRadioButton* g1radio0 = new wxRadioButton(parent, wxID_ANY, "radio 1.0",
wxScopedPtr<wxRadioButton> g1radio0(new wxRadioButton(parent, wxID_ANY, "radio 1.0",
wxDefaultPosition, wxDefaultSize,
wxRB_GROUP);
wxRB_GROUP));
wxRadioButton* g1radio1 = new wxRadioButton(parent, wxID_ANY, "radio 1.1");
wxScopedPtr<wxRadioButton> g1radio1(new wxRadioButton(parent, wxID_ANY, "radio 1.1"));
wxRadioButton* g2radio0 = new wxRadioButton(parent, wxID_ANY, "radio 2.0",
wxScopedPtr<wxRadioButton> g2radio0(new wxRadioButton(parent, wxID_ANY, "radio 2.0",
wxDefaultPosition, wxDefaultSize,
wxRB_GROUP);
wxRB_GROUP));
wxRadioButton* g2radio1 = new wxRadioButton(parent, wxID_ANY, "radio 2.1");
wxScopedPtr<wxRadioButton> g2radio1(new wxRadioButton(parent, wxID_ANY, "radio 2.1"));
// Check that having another control between radio buttons doesn't break
// grouping.
wxStaticText* text = new wxStaticText(parent, wxID_ANY, "Label");
wxRadioButton* g2radio2 = new wxRadioButton(parent, wxID_ANY, "radio 2.1");
wxScopedPtr<wxStaticText> text(new wxStaticText(parent, wxID_ANY, "Label"));
wxScopedPtr<wxRadioButton> g2radio2(new wxRadioButton(parent, wxID_ANY, "radio 2.2"));
g1radio0->SetValue(true);
g2radio0->SetValue(true);
CPPUNIT_ASSERT(g1radio0->GetValue());
CPPUNIT_ASSERT(!g1radio1->GetValue());
CPPUNIT_ASSERT(g2radio0->GetValue());
CPPUNIT_ASSERT(!g2radio1->GetValue());
CHECK(g1radio0->GetValue());
CHECK(!g1radio1->GetValue());
CHECK(g2radio0->GetValue());
CHECK(!g2radio1->GetValue());
g1radio1->SetValue(true);
g2radio1->SetValue(true);
CPPUNIT_ASSERT(!g1radio0->GetValue());
CPPUNIT_ASSERT(g1radio1->GetValue());
CPPUNIT_ASSERT(!g2radio0->GetValue());
CPPUNIT_ASSERT(g2radio1->GetValue());
CHECK(!g1radio0->GetValue());
CHECK(g1radio1->GetValue());
CHECK(!g2radio0->GetValue());
CHECK(g2radio1->GetValue());
g2radio2->SetValue(true);
CPPUNIT_ASSERT(!g2radio0->GetValue());
CPPUNIT_ASSERT(!g2radio1->GetValue());
CPPUNIT_ASSERT(g2radio2->GetValue());
CHECK(!g2radio0->GetValue());
CHECK(!g2radio1->GetValue());
CHECK(g2radio2->GetValue());
g1radio0->SetValue(true);
g2radio0->SetValue(true);
CPPUNIT_ASSERT(g1radio0->GetValue());
CPPUNIT_ASSERT(!g1radio1->GetValue());
CPPUNIT_ASSERT(g2radio0->GetValue());
CPPUNIT_ASSERT(!g2radio1->GetValue());
CHECK(g1radio0->GetValue());
CHECK(!g1radio1->GetValue());
CHECK(g2radio0->GetValue());
CHECK(!g2radio1->GetValue());
wxDELETE(g1radio0);
wxDELETE(g1radio1);
wxDELETE(g2radio0);
wxDELETE(g2radio1);
wxDELETE(g2radio2);
wxDELETE(text);
// Check that group navigation functions behave as expected.
// GetFirstInGroup()
CHECK_SAME_WINDOW(g1radio0->GetFirstInGroup(), g1radio0);
CHECK_SAME_WINDOW(g1radio1->GetFirstInGroup(), g1radio0);
CHECK_SAME_WINDOW(g2radio0->GetFirstInGroup(), g2radio0);
CHECK_SAME_WINDOW(g2radio1->GetFirstInGroup(), g2radio0);
CHECK_SAME_WINDOW(g2radio2->GetFirstInGroup(), g2radio0);
// GetLastInGroup()
CHECK_SAME_WINDOW(g1radio0->GetLastInGroup(), g1radio1);
CHECK_SAME_WINDOW(g1radio1->GetLastInGroup(), g1radio1);
CHECK_SAME_WINDOW(g2radio0->GetLastInGroup(), g2radio2);
CHECK_SAME_WINDOW(g2radio1->GetLastInGroup(), g2radio2);
CHECK_SAME_WINDOW(g2radio2->GetLastInGroup(), g2radio2);
// GetNextInGroup()
CHECK_SAME_WINDOW(g1radio0->GetNextInGroup(), g1radio1);
CHECK_SAME_WINDOW(g1radio1->GetNextInGroup(), NULL);
CHECK_SAME_WINDOW(g2radio0->GetNextInGroup(), g2radio1);
CHECK_SAME_WINDOW(g2radio1->GetNextInGroup(), g2radio2);
CHECK_SAME_WINDOW(g2radio2->GetNextInGroup(), NULL);
// GetPreviousInGroup()
CHECK_SAME_WINDOW(g1radio0->GetPreviousInGroup(), NULL);
CHECK_SAME_WINDOW(g1radio1->GetPreviousInGroup(), g1radio0);
CHECK_SAME_WINDOW(g2radio0->GetPreviousInGroup(), NULL);
CHECK_SAME_WINDOW(g2radio1->GetPreviousInGroup(), g2radio0);
CHECK_SAME_WINDOW(g2radio2->GetPreviousInGroup(), g2radio1);
}
void RadioButtonTestCase::Single()
TEST_CASE_METHOD(RadioButtonTestCase, "RadioButton::Single", "[radiobutton]")
{
//Create a group of 2 buttons, having second button selected
wxScopedPtr<wxRadioButton> gradio0(new wxRadioButton(wxTheApp->GetTopWindow(),
@ -197,9 +204,15 @@ void RadioButtonTestCase::Single()
CHECK(gradio1->GetValue());
CHECK(ngradio->GetValue());
// Also check that navigation works as expected with "single" buttons.
CHECK_SAME_WINDOW(sradio->GetFirstInGroup(), sradio);
CHECK_SAME_WINDOW(sradio->GetLastInGroup(), sradio);
CHECK_SAME_WINDOW(sradio->GetPreviousInGroup(), NULL);
CHECK_SAME_WINDOW(sradio->GetNextInGroup(), NULL);
}
TEST_CASE("wxRadioButton::Focus", "[radiobutton][focus]")
TEST_CASE("RadioButton::Focus", "[radiobutton][focus]")
{
// Create a container panel just to be able to destroy all the windows
// created here at once by simply destroying it.

View File

@ -35,6 +35,7 @@ private:
#ifndef __WXOSX__
WXUISIM_TEST( PageUpDown );
WXUISIM_TEST( LineUpDown );
WXUISIM_TEST( EvtSlider );
WXUISIM_TEST( LinePageSize );
#endif
CPPUNIT_TEST( Value );
@ -47,6 +48,7 @@ private:
void PageUpDown();
void LineUpDown();
void EvtSlider();
void LinePageSize();
void Value();
void Range();
@ -125,6 +127,24 @@ void SliderTestCase::LineUpDown()
#endif
}
void SliderTestCase::EvtSlider()
{
#if wxUSE_UIACTIONSIMULATOR
EventCounter slider(m_slider, wxEVT_SLIDER);
wxUIActionSimulator sim;
wxYield();
m_slider->SetFocus();
sim.Char(WXK_UP);
sim.Char(WXK_DOWN);
wxYield();
CPPUNIT_ASSERT_EQUAL(2, slider.GetCount());
#endif
}
void SliderTestCase::LinePageSize()
{
#if wxUSE_UIACTIONSIMULATOR

View File

@ -136,10 +136,22 @@ TEST_CASE_METHOD(WindowTestCase, "Window::Mouse", "[window]")
CHECK(m_window->GetCursor().IsOk());
#if wxUSE_CARET
//A plain window doesn't have a caret
CHECK(!m_window->GetCaret());
wxCaret* caret = new wxCaret(m_window, 16, 16);
wxCaret* caret;
// Try creating the caret in two different, but normally equivalent, ways.
SECTION("Caret 1-step")
{
caret = new wxCaret(m_window, 16, 16);
}
SECTION("Caret 2-step")
{
caret = new wxCaret();
caret->Create(m_window, 16, 16);
}
m_window->SetCaret(caret);
CHECK(m_window->GetCaret()->IsOk());

1430
tests/graphics/coords.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1454,6 +1454,438 @@ void ImageTestCase::ScaleCompare()
#endif //wxUSE_IMAGE
TEST_CASE("wxImage::Paste", "[image][paste]")
{
const static char* squares_xpm[] =
{
"9 9 7 1",
" c None",
"y c #FFFF00",
"r c #FF0000",
"g c #00FF00",
"b c #0000FF",
"o c #FF6600",
"w c #FFFFFF",
"rrrrwgggg",
"rrrrwgggg",
"rrrrwgggg",
"rrrrwgggg",
"wwwwwwwww",
"bbbbwoooo",
"bbbbwoooo",
"bbbbwoooo",
"bbbbwoooo"
};
const static char* toggle_equal_size_xpm[] =
{
"9 9 2 1",
" c None",
"y c #FFFF00",
"y y y y y",
" y y y y ",
"y y y y y",
" y y y y ",
"y y y y y",
" y y y y ",
"y y y y y",
" y y y y ",
"y y y y y",
};
const static char* transparent_image_xpm[] =
{
"5 5 2 1",
" c None", // Mask
"y c #FFFF00",
" ",
" ",
" ",
" ",
" ",
};
const static char* light_image_xpm[] =
{
"5 5 2 1",
" c None",
"y c #FFFF00",
"yyyyy",
"yyyyy",
"yyyyy",
"yyyyy",
"yyyyy",
};
const static char* black_image_xpm[] =
{
"5 5 2 1",
" c #000000",
"y c None", // Mask
" ",
" ",
" ",
" ",
" ",
};
// Execute AddHandler() just once.
static const bool
registeredHandler = (wxImage::AddHandler(new wxPNGHandler()), true);
SECTION("Paste same size image")
{
wxImage actual(squares_xpm);
wxImage paste(toggle_equal_size_xpm);
wxImage expected(toggle_equal_size_xpm);
actual.Paste(paste, 0, 0);
CHECK_THAT(actual, RGBSameAs(expected));
// Without alpha using "compose" doesn't change anything.
actual.Paste(paste, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste larger image")
{
const static char* toggle_larger_size_xpm[] =
{
"13 13 2 1",
" c None",
"y c #FFFF00",
"y y y y y y y",
" y y y y y y ",
"y y y y y y y",
" y y y y y y ",
"y y y y y y y",
" y y y y y y ",
"y y y y y y y",
" y y y y y y ",
"y y y y y y y",
" y y y y y y ",
"y y y y y y y",
" y y y y y y ",
"y y y y y y y",
};
wxImage actual(squares_xpm);
wxImage paste(toggle_larger_size_xpm);
wxImage expected(toggle_equal_size_xpm);
actual.Paste(paste, -2, -2);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste smaller image")
{
const static char* toggle_smaller_size_xpm[] =
{
"5 5 2 1",
" c None",
"y c #FFFF00",
"y y y",
" y y ",
"y y y",
" y y ",
"y y y",
};
const static char* expected_xpm[] =
{
"9 9 7 1",
" c None",
"y c #FFFF00",
"r c #FF0000",
"g c #00FF00",
"b c #0000FF",
"o c #FF6600",
"w c #FFFFFF",
"rrrrwgggg",
"rrrrwgggg",
"rry y ygg",
"rr y y gg",
"wwy y yww",
"bb y y oo",
"bby y yoo",
"bbbbwoooo",
"bbbbwoooo"
};
wxImage actual(squares_xpm);
wxImage paste(toggle_smaller_size_xpm);
wxImage expected(expected_xpm);
actual.Paste(paste, 2, 2);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste beyond top left corner")
{
const static char* expected_xpm[] =
{
"9 9 7 1",
" c None",
"y c #FFFF00",
"r c #FF0000",
"g c #00FF00",
"b c #0000FF",
"o c #FF6600",
"w c #FFFFFF",
"oooowgggg",
"oooowgggg",
"oooowgggg",
"oooowgggg",
"wwwwwwwww",
"bbbbwoooo",
"bbbbwoooo",
"bbbbwoooo",
"bbbbwoooo"
};
wxImage actual(squares_xpm);
wxImage paste(squares_xpm);
wxImage expected(expected_xpm);
actual.Paste(paste, -5, -5);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste beyond top right corner")
{
const static char* expected_xpm[] =
{
"9 9 7 1",
" c None",
"y c #FFFF00",
"r c #FF0000",
"g c #00FF00",
"b c #0000FF",
"o c #FF6600",
"w c #FFFFFF",
"rrrrwbbbb",
"rrrrwbbbb",
"rrrrwbbbb",
"rrrrwbbbb",
"wwwwwwwww",
"bbbbwoooo",
"bbbbwoooo",
"bbbbwoooo",
"bbbbwoooo"
};
wxImage actual(squares_xpm);
wxImage paste(squares_xpm);
wxImage expected(expected_xpm);
actual.Paste(paste, 5, -5);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste beyond bottom right corner")
{
const static char* expected_xpm[] =
{
"9 9 7 1",
" c None",
"y c #FF0000",
"r c #FF0000",
"g c #00FF00",
"b c #0000FF",
"o c #FF6600",
"w c #FFFFFF",
"rrrrwgggg",
"rrrrwgggg",
"rrrrwgggg",
"rrrrwgggg",
"wwwwwwwww",
"bbbbwrrrr",
"bbbbwrrrr",
"bbbbwrrrr",
"bbbbwrrrr"
};
wxImage actual(squares_xpm);
wxImage paste(squares_xpm);
wxImage expected(expected_xpm);
actual.Paste(paste, 5, 5);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste beyond bottom left corner")
{
const static char* expected_xpm[] =
{
"9 9 7 1",
" c None",
"y c #FFFF00",
"r c #FF0000",
"g c #00FF00",
"b c #0000FF",
"o c #FF6600",
"w c #FFFFFF",
"rrrrwgggg",
"rrrrwgggg",
"rrrrwgggg",
"rrrrwgggg",
"wwwwwwwww",
"ggggwoooo",
"ggggwoooo",
"ggggwoooo",
"ggggwoooo"
};
wxImage actual(squares_xpm);
wxImage paste(squares_xpm);
wxImage expected(expected_xpm);
actual.Paste(paste, -5, 5);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste fully opaque image onto blank image without alpha")
{
const wxImage background("image/paste_input_background.png");
REQUIRE(background.IsOk());
wxImage actual(background.GetSize());
actual.Paste(background, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSameAs(background));
CHECK(!actual.HasAlpha());
}
SECTION("Paste fully opaque image onto blank image with alpha")
{
const wxImage background("image/paste_input_background.png");
REQUIRE(background.IsOk());
wxImage actual(background.GetSize());
actual.InitAlpha();
actual.Paste(background, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSameAs(background));
CHECK_THAT(actual, CenterAlphaPixelEquals(wxALPHA_OPAQUE));
}
SECTION("Paste fully transparent image")
{
const wxImage background("image/paste_input_background.png");
REQUIRE(background.IsOk());
wxImage actual = background.Copy();
wxImage transparent(actual.GetSize());
transparent.InitAlpha();
memset(transparent.GetAlpha(), 0, transparent.GetWidth() * transparent.GetHeight());
actual.Paste(transparent, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSameAs(background));
CHECK_THAT(actual, CenterAlphaPixelEquals(wxALPHA_OPAQUE));
}
SECTION("Paste image with transparent region")
{
wxImage actual("image/paste_input_background.png");
REQUIRE(actual.IsOk());
const wxImage opaque_square("image/paste_input_overlay_transparent_border_opaque_square.png");
REQUIRE(opaque_square.IsOk());
actual.Paste(opaque_square, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSameAs(wxImage("image/paste_result_background_plus_overlay_transparent_border_opaque_square.png")));
CHECK_THAT(actual, CenterAlphaPixelEquals(wxALPHA_OPAQUE));
}
SECTION("Paste image with semi transparent region")
{
wxImage actual("image/paste_input_background.png");
REQUIRE(actual.IsOk());
const wxImage transparent_square("image/paste_input_overlay_transparent_border_semitransparent_square.png");
REQUIRE(transparent_square.IsOk());
actual.Paste(transparent_square, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSameAs(wxImage("image/paste_result_background_plus_overlay_transparent_border_semitransparent_square.png")));
CHECK_THAT(actual, CenterAlphaPixelEquals(wxALPHA_OPAQUE));
}
SECTION("Paste two semi transparent images on top of background")
{
wxImage actual("image/paste_input_background.png");
REQUIRE(actual.IsOk());
const wxImage transparent_square("image/paste_input_overlay_transparent_border_semitransparent_square.png");
REQUIRE(transparent_square.IsOk());
const wxImage transparent_circle("image/paste_input_overlay_transparent_border_semitransparent_circle.png");
REQUIRE(transparent_circle.IsOk());
actual.Paste(transparent_circle, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
actual.Paste(transparent_square, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSimilarTo(wxImage("image/paste_result_background_plus_circle_plus_square.png"), 1));
CHECK_THAT(actual, CenterAlphaPixelEquals(wxALPHA_OPAQUE));
}
SECTION("Paste two semi transparent images together first, then on top of background")
{
wxImage actual("image/paste_input_background.png");
REQUIRE(actual.IsOk());
const wxImage transparent_square("image/paste_input_overlay_transparent_border_semitransparent_square.png");
REQUIRE(transparent_square.IsOk());
const wxImage transparent_circle("image/paste_input_overlay_transparent_border_semitransparent_circle.png");
REQUIRE(transparent_circle.IsOk());
wxImage circle = transparent_circle.Copy();
circle.Paste(transparent_square, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
actual.Paste(circle, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
// When applied in this order, two times a rounding difference is triggered.
CHECK_THAT(actual, RGBSimilarTo(wxImage("image/paste_result_background_plus_circle_plus_square.png"), 2));
CHECK_THAT(actual, CenterAlphaPixelEquals(wxALPHA_OPAQUE));
}
SECTION("Paste semitransparent image over transparent image")
{
const wxImage transparent_square("image/paste_input_overlay_transparent_border_semitransparent_square.png");
REQUIRE(transparent_square.IsOk());
const wxImage transparent_circle("image/paste_input_overlay_transparent_border_semitransparent_circle.png");
REQUIRE(transparent_circle.IsOk());
wxImage actual(transparent_circle.GetSize());
actual.InitAlpha();
memset(actual.GetAlpha(), 0, actual.GetWidth() * actual.GetHeight());
actual.Paste(transparent_circle, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, CenterAlphaPixelEquals(192));
actual.Paste(transparent_square, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSimilarTo(wxImage("image/paste_result_no_background_square_over_circle.png"), 1));
CHECK_THAT(actual, CenterAlphaPixelEquals(224));
}
SECTION("Paste fully transparent (masked) image over light image") // todo make test case for 'blend with mask'
{
wxImage actual(light_image_xpm);
actual.InitAlpha();
wxImage paste(transparent_image_xpm);
wxImage expected(light_image_xpm);
actual.Paste(paste, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste fully black (masked) image over light image") // todo make test case for 'blend with mask'
{
wxImage actual(light_image_xpm);
actual.InitAlpha();
wxImage paste(black_image_xpm);
wxImage expected(black_image_xpm);
actual.Paste(paste, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, RGBSameAs(expected));
}
SECTION("Paste dark image over light image")
{
wxImage black("image/paste_input_black.png");
wxImage actual("image/paste_input_background.png");
actual.InitAlpha();
actual.Paste(black, 0, 0, wxIMAGE_ALPHA_BLEND_COMPOSE);
CHECK_THAT(actual, CenterAlphaPixelEquals(255));
CHECK_THAT(actual, RGBSameAs(black));
}
SECTION("Paste large image with negative vertical offset")
{
wxImage target(442, 249);
wxImage to_be_pasted(345, 24900);
target.InitAlpha();
target.Paste(to_be_pasted, 48, -12325, wxIMAGE_ALPHA_BLEND_COMPOSE);
}
SECTION("Paste large image with negative horizontal offset")
{
wxImage target(249, 442);
wxImage to_be_pasted(24900, 345);
target.InitAlpha();
target.Paste(to_be_pasted, -12325, 48, wxIMAGE_ALPHA_BLEND_COMPOSE);
}
}
/*
TODO: add lots of more tests to wxImage functions

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Some files were not shown because too many files have changed in this diff Show More