diff --git a/Makefile.in b/Makefile.in index e44bc57695..564c1011e7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4579,7 +4579,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS = \ monodll_datavgen.o \ monodll_editlbox.o \ monodll_laywin.o \ - monodll_calctrlg.o + monodll_calctrlg.o \ + monodll_rowheightcache.o @COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS) COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \ $(__LOWLEVEL_SRC_OBJECTS_1) \ @@ -4839,7 +4840,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \ monodll_datavgen.o \ monodll_editlbox.o \ monodll_laywin.o \ - monodll_calctrlg.o + monodll_calctrlg.o \ + monodll_rowheightcache.o @COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS) COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS = \ monodll_fontmgrcmn.o \ @@ -6555,7 +6557,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1 = \ monolib_datavgen.o \ monolib_editlbox.o \ monolib_laywin.o \ - monolib_calctrlg.o + monolib_calctrlg.o \ + monolib_rowheightcache.o @COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_1 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1) COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \ $(__LOWLEVEL_SRC_OBJECTS_3) \ @@ -6815,7 +6818,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \ monolib_datavgen.o \ monolib_editlbox.o \ monolib_laywin.o \ - monolib_calctrlg.o + monolib_calctrlg.o \ + monolib_rowheightcache.o @COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_1 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1) COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_fontmgrcmn.o \ @@ -8678,7 +8682,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2 = \ coredll_datavgen.o \ coredll_editlbox.o \ coredll_laywin.o \ - coredll_calctrlg.o + coredll_calctrlg.o \ + coredll_rowheightcache.o @COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_2 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2) COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \ $(__LOWLEVEL_SRC_OBJECTS_5) \ @@ -8938,7 +8943,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \ coredll_datavgen.o \ coredll_editlbox.o \ coredll_laywin.o \ - coredll_calctrlg.o + coredll_calctrlg.o \ + coredll_rowheightcache.o @COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_2 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2) COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_fontmgrcmn.o \ @@ -10396,7 +10402,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3 = \ corelib_datavgen.o \ corelib_editlbox.o \ corelib_laywin.o \ - corelib_calctrlg.o + corelib_calctrlg.o \ + corelib_rowheightcache.o @COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_3 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3) COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \ $(__LOWLEVEL_SRC_OBJECTS_7) \ @@ -10656,7 +10663,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \ corelib_datavgen.o \ corelib_editlbox.o \ corelib_laywin.o \ - corelib_calctrlg.o + corelib_calctrlg.o \ + corelib_rowheightcache.o @COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_3 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3) COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_fontmgrcmn.o \ @@ -20698,6 +20706,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@monodll_calctrlg.o: $(srcdir)/src/generic/calctrlg.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/calctrlg.cpp +@COND_USE_GUI_1@monodll_rowheightcache.o: $(srcdir)/src/generic/rowheightcache.cpp $(MONODLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/rowheightcache.cpp + @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monodll_osx_cocoa_mediactrl.o: $(srcdir)/src/osx/cocoa/mediactrl.mm $(MONODLL_ODEP) @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/mediactrl.mm @@ -25951,6 +25962,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@monolib_calctrlg.o: $(srcdir)/src/generic/calctrlg.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/calctrlg.cpp +@COND_USE_GUI_1@monolib_rowheightcache.o: $(srcdir)/src/generic/rowheightcache.cpp $(MONOLIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/rowheightcache.cpp + @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monolib_osx_cocoa_mediactrl.o: $(srcdir)/src/osx/cocoa/mediactrl.mm $(MONOLIB_ODEP) @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/mediactrl.mm @@ -31297,6 +31311,9 @@ coredll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@coredll_calctrlg.o: $(srcdir)/src/generic/calctrlg.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/calctrlg.cpp +@COND_USE_GUI_1@coredll_rowheightcache.o: $(srcdir)/src/generic/rowheightcache.cpp $(COREDLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/rowheightcache.cpp + corelib_event.o: $(srcdir)/src/common/event.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/event.cpp @@ -35545,6 +35562,9 @@ corelib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@corelib_calctrlg.o: $(srcdir)/src/generic/calctrlg.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/calctrlg.cpp +@COND_USE_GUI_1@corelib_rowheightcache.o: $(srcdir)/src/generic/rowheightcache.cpp $(CORELIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/rowheightcache.cpp + advdll_version_rc.o: $(srcdir)/src/msw/version.rc $(ADVDLL_ODEP) $(WINDRES) -i$< -o$@ --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)_adv$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include $(__INC_TIFF_BUILD_p_66) $(__INC_TIFF_p_66) $(__INC_JPEG_p_66) $(__INC_PNG_p_65) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define WXUSINGDLL --define WXMAKINGDLL_ADV diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 3f84e21ae5..6001ccbd34 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1005,6 +1005,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/generic/editlbox.cpp src/generic/laywin.cpp src/generic/calctrlg.cpp + src/generic/rowheightcache.cpp wx/affinematrix2dbase.h diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index 3111a384c2..c126d0f237 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -908,6 +908,7 @@ set(GUI_CMN_SRC src/generic/wizard.cpp src/generic/editlbox.cpp src/generic/datavgen.cpp + src/generic/rowheightcache.cpp ) set(GUI_CMN_HDR diff --git a/build/files b/build/files index d774633b94..13a542b9c9 100644 --- a/build/files +++ b/build/files @@ -899,6 +899,7 @@ GUI_CMN_SRC = src/generic/renderg.cpp src/generic/richmsgdlgg.cpp src/generic/richtooltipg.cpp + src/generic/rowheightcache.cpp src/generic/sashwin.cpp src/generic/scrlwing.cpp src/generic/selstore.cpp diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index 8112f30f89..ca37c2f67e 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -2126,7 +2126,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_datavgen.obj \ $(OBJS)\monodll_editlbox.obj \ $(OBJS)\monodll_laywin.obj \ - $(OBJS)\monodll_calctrlg.obj + $(OBJS)\monodll_calctrlg.obj \ + $(OBJS)\monodll_rowheightcache.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_OBJECTS = \ @@ -2451,7 +2452,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_datavgen.obj \ $(OBJS)\monodll_editlbox.obj \ $(OBJS)\monodll_laywin.obj \ - $(OBJS)\monodll_calctrlg.obj + $(OBJS)\monodll_calctrlg.obj \ + $(OBJS)\monodll_rowheightcache.obj !endif !if "$(USE_STC)" == "1" ____MONOLIB_STC_SRC_FILENAMES_OBJECTS = \ @@ -2955,7 +2957,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_datavgen.obj \ $(OBJS)\monolib_editlbox.obj \ $(OBJS)\monolib_laywin.obj \ - $(OBJS)\monolib_calctrlg.obj + $(OBJS)\monolib_calctrlg.obj \ + $(OBJS)\monolib_rowheightcache.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_1_OBJECTS = \ @@ -3280,7 +3283,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_datavgen.obj \ $(OBJS)\monolib_editlbox.obj \ $(OBJS)\monolib_laywin.obj \ - $(OBJS)\monolib_calctrlg.obj + $(OBJS)\monolib_calctrlg.obj \ + $(OBJS)\monolib_rowheightcache.obj !endif !if "$(USE_STC)" == "1" ____MONOLIB_STC_SRC_FILENAMES_1_OBJECTS = \ @@ -3659,7 +3663,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_datavgen.obj \ $(OBJS)\coredll_editlbox.obj \ $(OBJS)\coredll_laywin.obj \ - $(OBJS)\coredll_calctrlg.obj + $(OBJS)\coredll_calctrlg.obj \ + $(OBJS)\coredll_rowheightcache.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_2_OBJECTS = \ @@ -3984,7 +3989,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_datavgen.obj \ $(OBJS)\coredll_editlbox.obj \ $(OBJS)\coredll_laywin.obj \ - $(OBJS)\coredll_calctrlg.obj + $(OBJS)\coredll_calctrlg.obj \ + $(OBJS)\coredll_rowheightcache.obj !endif !if "$(MONOLITHIC)" == "0" && "$(SHARED)" == "0" && "$(USE_GUI)" == "1" __corelib___depname = \ @@ -4329,7 +4335,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_datavgen.obj \ $(OBJS)\corelib_editlbox.obj \ $(OBJS)\corelib_laywin.obj \ - $(OBJS)\corelib_calctrlg.obj + $(OBJS)\corelib_calctrlg.obj \ + $(OBJS)\corelib_rowheightcache.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_3_OBJECTS = \ @@ -4654,7 +4661,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_datavgen.obj \ $(OBJS)\corelib_editlbox.obj \ $(OBJS)\corelib_laywin.obj \ - $(OBJS)\corelib_calctrlg.obj + $(OBJS)\corelib_calctrlg.obj \ + $(OBJS)\corelib_rowheightcache.obj !endif !if "$(SHARED)" == "1" ____wxcore_namedll_DEP = $(__coredll___depname) @@ -8937,6 +8945,11 @@ $(OBJS)\monodll_calctrlg.obj: ..\..\src\generic\calctrlg.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\calctrlg.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp +!endif + $(OBJS)\monodll_version.res: ..\..\src\msw\version.rc brcc32 -32 -r -fo$@ -i$(BCCDIR)\include -d__WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) -i$(SETUPHDIR) -i..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_4) -dWXBUILDING -dWXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG) -i$(BCCDIR)\include\windows\sdk -i..\..\src\tiff\libtiff -i..\..\src\jpeg -i..\..\src\png -i..\..\src\zlib -i..\..\src\regex -i..\..\src\expat\expat\lib -i..\..\src\stc\scintilla\include -i..\..\src\stc\scintilla\lexlib -i..\..\src\stc\scintilla\src -d__WX__ -dSCI_LEXER -dNO_CXX11_REGEX -dLINK_LEXERS -dwxUSE_BASE=1 -dWXMAKINGDLL ..\..\src\msw\version.rc @@ -11478,6 +11491,11 @@ $(OBJS)\monolib_calctrlg.obj: ..\..\src\generic\calctrlg.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\calctrlg.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp +!endif + $(OBJS)\basedll_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) -q -c -P -o$@ $(BASEDLL_CXXFLAGS) -H ..\..\src\common\dummy.cpp @@ -13983,6 +14001,11 @@ $(OBJS)\coredll_calctrlg.obj: ..\..\src\generic\calctrlg.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\calctrlg.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp + $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp +!endif + $(OBJS)\corelib_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) -H ..\..\src\common\dummy.cpp @@ -15711,6 +15734,11 @@ $(OBJS)\corelib_calctrlg.obj: ..\..\src\generic\calctrlg.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\calctrlg.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp + $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp +!endif + $(OBJS)\advdll_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) -H ..\..\src\common\dummy.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index c6a2042c6b..6de7992c59 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -2152,7 +2152,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_datavgen.o \ $(OBJS)\monodll_editlbox.o \ $(OBJS)\monodll_laywin.o \ - $(OBJS)\monodll_calctrlg.o + $(OBJS)\monodll_calctrlg.o \ + $(OBJS)\monodll_rowheightcache.o endif endif ifeq ($(USE_GUI),1) @@ -2479,7 +2480,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_datavgen.o \ $(OBJS)\monodll_editlbox.o \ $(OBJS)\monodll_laywin.o \ - $(OBJS)\monodll_calctrlg.o + $(OBJS)\monodll_calctrlg.o \ + $(OBJS)\monodll_rowheightcache.o endif endif ifeq ($(USE_STC),1) @@ -2987,7 +2989,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_datavgen.o \ $(OBJS)\monolib_editlbox.o \ $(OBJS)\monolib_laywin.o \ - $(OBJS)\monolib_calctrlg.o + $(OBJS)\monolib_calctrlg.o \ + $(OBJS)\monolib_rowheightcache.o endif endif ifeq ($(USE_GUI),1) @@ -3314,7 +3317,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_datavgen.o \ $(OBJS)\monolib_editlbox.o \ $(OBJS)\monolib_laywin.o \ - $(OBJS)\monolib_calctrlg.o + $(OBJS)\monolib_calctrlg.o \ + $(OBJS)\monolib_rowheightcache.o endif endif ifeq ($(USE_STC),1) @@ -3707,7 +3711,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_datavgen.o \ $(OBJS)\coredll_editlbox.o \ $(OBJS)\coredll_laywin.o \ - $(OBJS)\coredll_calctrlg.o + $(OBJS)\coredll_calctrlg.o \ + $(OBJS)\coredll_rowheightcache.o endif endif ifeq ($(USE_GUI),1) @@ -4034,7 +4039,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_datavgen.o \ $(OBJS)\coredll_editlbox.o \ $(OBJS)\coredll_laywin.o \ - $(OBJS)\coredll_calctrlg.o + $(OBJS)\coredll_calctrlg.o \ + $(OBJS)\coredll_rowheightcache.o endif endif ifeq ($(MONOLITHIC),0) @@ -4385,7 +4391,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_datavgen.o \ $(OBJS)\corelib_editlbox.o \ $(OBJS)\corelib_laywin.o \ - $(OBJS)\corelib_calctrlg.o + $(OBJS)\corelib_calctrlg.o \ + $(OBJS)\corelib_rowheightcache.o endif endif ifeq ($(USE_GUI),1) @@ -4712,7 +4719,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_datavgen.o \ $(OBJS)\corelib_editlbox.o \ $(OBJS)\corelib_laywin.o \ - $(OBJS)\corelib_calctrlg.o + $(OBJS)\corelib_calctrlg.o \ + $(OBJS)\corelib_rowheightcache.o endif endif ifeq ($(SHARED),1) @@ -9119,6 +9127,11 @@ $(OBJS)\monodll_calctrlg.o: ../../src/generic/calctrlg.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monodll_rowheightcache.o: ../../src/generic/rowheightcache.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + $(OBJS)\monodll_version_rc.o: ../../src/msw/version.rc $(WINDRES) -i$< -o$@ --define __WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) --include-dir $(SETUPHDIR) --include-dir ../../include $(__CAIRO_INCLUDEDIR_p) --define WXBUILDING --define WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG) --include-dir ../../src/tiff/libtiff --include-dir ../../src/jpeg --include-dir ../../src/png --include-dir ../../src/zlib --include-dir ../../src/regex --include-dir ../../src/expat/expat/lib --include-dir ../../src/stc/scintilla/include --include-dir ../../src/stc/scintilla/lexlib --include-dir ../../src/stc/scintilla/src --define __WX__ --define SCI_LEXER --define NO_CXX11_REGEX --define LINK_LEXERS --define wxUSE_BASE=1 --define WXMAKINGDLL @@ -11660,6 +11673,11 @@ $(OBJS)\monolib_calctrlg.o: ../../src/generic/calctrlg.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monolib_rowheightcache.o: ../../src/generic/rowheightcache.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + $(OBJS)\basedll_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< @@ -14165,6 +14183,11 @@ $(OBJS)\coredll_calctrlg.o: ../../src/generic/calctrlg.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\coredll_rowheightcache.o: ../../src/generic/rowheightcache.cpp + $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< +endif + $(OBJS)\corelib_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< @@ -15893,6 +15916,11 @@ $(OBJS)\corelib_calctrlg.o: ../../src/generic/calctrlg.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\corelib_rowheightcache.o: ../../src/generic/rowheightcache.cpp + $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< +endif + $(OBJS)\advdll_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index c1ce7f10bd..13d3cc7abc 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -2443,7 +2443,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_datavgen.obj \ $(OBJS)\monodll_editlbox.obj \ $(OBJS)\monodll_laywin.obj \ - $(OBJS)\monodll_calctrlg.obj + $(OBJS)\monodll_calctrlg.obj \ + $(OBJS)\monodll_rowheightcache.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_OBJECTS = \ @@ -2768,7 +2769,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_datavgen.obj \ $(OBJS)\monodll_editlbox.obj \ $(OBJS)\monodll_laywin.obj \ - $(OBJS)\monodll_calctrlg.obj + $(OBJS)\monodll_calctrlg.obj \ + $(OBJS)\monodll_rowheightcache.obj !endif !if "$(USE_STC)" == "1" ____MONOLIB_STC_SRC_FILENAMES_OBJECTS = \ @@ -3278,7 +3280,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_datavgen.obj \ $(OBJS)\monolib_editlbox.obj \ $(OBJS)\monolib_laywin.obj \ - $(OBJS)\monolib_calctrlg.obj + $(OBJS)\monolib_calctrlg.obj \ + $(OBJS)\monolib_rowheightcache.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_1_OBJECTS = \ @@ -3603,7 +3606,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_datavgen.obj \ $(OBJS)\monolib_editlbox.obj \ $(OBJS)\monolib_laywin.obj \ - $(OBJS)\monolib_calctrlg.obj + $(OBJS)\monolib_calctrlg.obj \ + $(OBJS)\monolib_rowheightcache.obj !endif !if "$(USE_STC)" == "1" ____MONOLIB_STC_SRC_FILENAMES_1_OBJECTS = \ @@ -4048,7 +4052,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_datavgen.obj \ $(OBJS)\coredll_editlbox.obj \ $(OBJS)\coredll_laywin.obj \ - $(OBJS)\coredll_calctrlg.obj + $(OBJS)\coredll_calctrlg.obj \ + $(OBJS)\coredll_rowheightcache.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_2_OBJECTS = \ @@ -4373,7 +4378,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_datavgen.obj \ $(OBJS)\coredll_editlbox.obj \ $(OBJS)\coredll_laywin.obj \ - $(OBJS)\coredll_calctrlg.obj + $(OBJS)\coredll_calctrlg.obj \ + $(OBJS)\coredll_rowheightcache.obj !endif !if "$(MONOLITHIC)" == "0" && "$(SHARED)" == "0" && "$(USE_GUI)" == "1" __corelib___depname = \ @@ -4724,7 +4730,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_datavgen.obj \ $(OBJS)\corelib_editlbox.obj \ $(OBJS)\corelib_laywin.obj \ - $(OBJS)\corelib_calctrlg.obj + $(OBJS)\corelib_calctrlg.obj \ + $(OBJS)\corelib_rowheightcache.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_3_OBJECTS = \ @@ -5049,7 +5056,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_datavgen.obj \ $(OBJS)\corelib_editlbox.obj \ $(OBJS)\corelib_laywin.obj \ - $(OBJS)\corelib_calctrlg.obj + $(OBJS)\corelib_calctrlg.obj \ + $(OBJS)\corelib_rowheightcache.obj !endif !if "$(SHARED)" == "1" ____wxcore_namedll_DEP = $(__coredll___depname) @@ -9646,6 +9654,11 @@ $(OBJS)\monodll_calctrlg.obj: ..\..\src\generic\calctrlg.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\calctrlg.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp +!endif + $(OBJS)\monodll_version.res: ..\..\src\msw\version.rc rc /fo$@ /d WIN32 $(____DEBUGRUNTIME_6) /d _CRT_SECURE_NO_DEPRECATE=1 /d _CRT_NON_CONFORMING_SWPRINTFS=1 /d _SCL_SECURE_NO_WARNINGS=1 $(__NO_VC_CRTDBG_p_72) /d __WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) /i $(SETUPHDIR) /i ..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_4) /d WXBUILDING /d WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG) /i ..\..\src\tiff\libtiff /i ..\..\src\jpeg /i ..\..\src\png /i ..\..\src\zlib /i ..\..\src\regex /i ..\..\src\expat\expat\lib /i ..\..\src\stc\scintilla\include /i ..\..\src\stc\scintilla\lexlib /i ..\..\src\stc\scintilla\src /d __WX__ /d SCI_LEXER /d NO_CXX11_REGEX /d LINK_LEXERS /d wxUSE_BASE=1 /d WXMAKINGDLL ..\..\src\msw\version.rc @@ -12187,6 +12200,11 @@ $(OBJS)\monolib_calctrlg.obj: ..\..\src\generic\calctrlg.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\calctrlg.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp +!endif + $(OBJS)\basedll_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp @@ -14692,6 +14710,11 @@ $(OBJS)\coredll_calctrlg.obj: ..\..\src\generic\calctrlg.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\calctrlg.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp + $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp +!endif + $(OBJS)\corelib_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp @@ -16420,6 +16443,11 @@ $(OBJS)\corelib_calctrlg.obj: ..\..\src\generic\calctrlg.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\calctrlg.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp + $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp +!endif + $(OBJS)\advdll_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp diff --git a/build/msw/wx_core.vcxproj b/build/msw/wx_core.vcxproj index bf3ea86b5a..87c60a35e1 100644 --- a/build/msw/wx_core.vcxproj +++ b/build/msw/wx_core.vcxproj @@ -1061,6 +1061,7 @@ + diff --git a/build/msw/wx_core.vcxproj.filters b/build/msw/wx_core.vcxproj.filters index 7e17bd7ad0..83c265118a 100644 --- a/build/msw/wx_core.vcxproj.filters +++ b/build/msw/wx_core.vcxproj.filters @@ -603,6 +603,9 @@ Generic Sources + + Generic Sources + Generic Sources diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj index f64feb56e0..abd7d4a0ad 100644 --- a/build/msw/wx_vc7_core.vcproj +++ b/build/msw/wx_vc7_core.vcproj @@ -1286,6 +1286,9 @@ + + diff --git a/build/msw/wx_vc8_core.vcproj b/build/msw/wx_vc8_core.vcproj index b734aa02bd..c2f829be68 100644 --- a/build/msw/wx_vc8_core.vcproj +++ b/build/msw/wx_vc8_core.vcproj @@ -2127,6 +2127,10 @@ RelativePath="..\..\src\generic\richtooltipg.cpp" > + + diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj index 0b33c64c19..6f8f12e632 100644 --- a/build/msw/wx_vc9_core.vcproj +++ b/build/msw/wx_vc9_core.vcproj @@ -2123,6 +2123,10 @@ RelativePath="..\..\src\generic\richtooltipg.cpp" > + + diff --git a/docs/changes.txt b/docs/changes.txt index 4d09c8f13b..1bda884cde 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -144,6 +144,7 @@ All (GUI): - Adapt AUI colours to system colour changes (Daniel Kulp). - Fix removing and inserting pages in wxToolbook (Stefan Ziegler). - Fix bug in template selection in docview framework (jwiesemann). +- Improve wxDataViewCtrl performance with variable line heights (Jens Goepfert). wxGTK: diff --git a/include/wx/generic/private/rowheightcache.h b/include/wx/generic/private/rowheightcache.h new file mode 100644 index 0000000000..d9586f16e7 --- /dev/null +++ b/include/wx/generic/private/rowheightcache.h @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/private/rowheightcache.h +// Purpose: height cache of rows in a dataview +// Author: Jens Goepfert (mail@jensgoepfert.de) +// Created: 2018-03-06 +// Copyright: (c) wxWidgets team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_ROWHEIGHTCACHE_H_ +#define _WX_PRIVATE_ROWHEIGHTCACHE_H_ + +#include "wx/hashmap.h" +#include "wx/vector.h" + +// struct describing a range of rows which contains rows .. +struct RowRange +{ + unsigned int from; + unsigned int to; +}; + +/** +@class RowRanges +A helper class that manages a set of RowRange objects. +It stores the indices that are members of a group in a memory +efficiant way. +*/ +class WXDLLIMPEXP_CORE RowRanges +//class RowRanges +{ +public: + /** + Adds a row index to this group by adding it to an existing RowRange + or by creating a new one. + */ + void Add(unsigned int row); + + /** + Removes a row index and all indices after idx from this group. + */ + void Remove(unsigned int row); + + /** + Checks whether a row index is contained in this group. + */ + bool Has(unsigned int row) const; + + /** + Returns the number of row indices that are contained in this group. + */ + unsigned int CountAll() const; + + /** + Returns the number of rows that are in this group before the given row index. + not including given row. + */ + unsigned int CountTo(unsigned int row) const; + unsigned int GetSize() const; // for debugging statistics + +private: + wxVector m_ranges; + /** + If a new row index was inserted Cleanup checks if the neighbour ranges + of idx can includes the same row indices and discards + unnecessary RowRange objects. + */ + void CleanUp(unsigned int idx); +}; + +WX_DECLARE_HASH_MAP(unsigned int, RowRanges*, wxIntegerHash, wxIntegerEqual, + HeightToRowRangesMap); + +/** +@class HeightCache + +HeightCache implements a cache mechanism for the DataViewCtrl to give +fast access to: +* the height of one line (GetLineHeight) +* the y-coordinate where a row starts (GetLineStart) +* and vice versa (GetLineAt) + +The layout of the cache is a hashmap where the keys are all exisiting +row heights in pixels. The values are RowRange objects that represents +all having the specified height. + +{ +22: RowRange([0..10], [15..17], [20..2000]), +42: RowRange([11..12], [18..18]), +62: RowRange([13..14], [19..19]) +} + +Examples +======== + +GetLineStart +------------ +To retrieve the y-coordinate of item 1000 it is neccessary to look into +each key of the hashmap *m_heightToRowRange*. Get the row count of +indices lower than 1000 (RowRange::CountTo) and multiplies it wich the +according height. + +RowRange([0..10], [15..17], [20..2000]).CountTo(1000) +--> 0..10 are 11 items, 15..17 are 3 items and 20..1000 are 980 items (1000-20) += 11 + 3 + 980 = 994 items + +GetLineStart(1000) --> (22 * 994) + (42 * 3) + (62 * 3) = 22180 + +GetLineHeight +------------- +To retrieve the line height look into each key and check if row is +contained in RowRange (RowRange::Has) + +GetLineAt +--------- +To retrieve the row that starts at a specific y-coordinate. +Look into each key and count all rows. +Use bisect algorithm in combination with GetLineStart() to +find the appropriate item +*/ +class WXDLLIMPEXP_ADV HeightCache +{ +public: + bool GetLineStart(unsigned int row, int &start); + bool GetLineHeight(unsigned int row, int &height); + bool GetLineAt(int y, unsigned int &row); + + void Put(const unsigned int row, const int height); + /** + removes the stored height of the given row from the cache + and invalidates all cached rows (including row) + */ + void Remove(const unsigned int row); + void Clear(); + +private: + bool GetLineInfo(unsigned int row, int &start, int &height); + HeightToRowRangesMap m_heightToRowRange; +}; + + +#endif // _WX_PRIVATE_ROWHEIGHTCACHE_H_ diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 448a58bf5b..9674e53d5b 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -53,6 +53,7 @@ #include "wx/stopwatch.h" #include "wx/weakref.h" #include "wx/generic/private/markuptext.h" +#include "wx/generic/private/rowheightcache.h" #include "wx/generic/private/widthcalc.h" #if wxUSE_ACCESSIBILITY #include "wx/private/markupparser.h" @@ -910,6 +911,7 @@ private: bool m_hasFocus; bool m_useCellFocus; bool m_currentColSetByKeyboard; + HeightCache *m_rowHeightCache; #if wxUSE_DRAG_AND_DROP int m_dragCount; @@ -1946,6 +1948,14 @@ wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID i m_useCellFocus = false; m_currentRow = (unsigned)-1; m_lineHeight = GetDefaultRowHeight(); + if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT)) + { + m_rowHeightCache = new HeightCache(); + } + else + { + m_rowHeightCache = NULL; + } #if wxUSE_DRAG_AND_DROP m_dragCount = 0; @@ -1982,6 +1992,11 @@ wxDataViewMainWindow::~wxDataViewMainWindow() { DestroyTree(); delete m_renameTimer; + if (m_rowHeightCache != NULL) + { + m_rowHeightCache->Clear(); + delete m_rowHeightCache; + } } @@ -2739,6 +2754,12 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData } else { + if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT)) + { + // specific position (row) is unclear, so clear whole height cache + m_rowHeightCache->Clear(); + } + wxDataViewTreeNode *parentNode = FindNode(parent); if ( !parentNode ) @@ -2880,6 +2901,9 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent, return true; } + if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT)) + m_rowHeightCache->Remove(GetRowByItem(parent) + itemPosInNode); + // Delete the item from wxDataViewTreeNode representation: const int itemsDeleted = 1 + itemNode->GetSubTreeCount(); @@ -2944,6 +2968,9 @@ bool wxDataViewMainWindow::DoItemChanged(const wxDataViewItem & item, int view_c { if ( !IsVirtualList() ) { + if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT)) + m_rowHeightCache->Remove(GetRowByItem(item)); + // Move this node to its new correct place after it was updated. // // In principle, we could skip the call to PutInSortOrder() if the modified @@ -3277,6 +3304,9 @@ void wxDataViewMainWindow::SendSelectionChangedEvent( const wxDataViewItem& item void wxDataViewMainWindow::RefreshRows( unsigned int from, unsigned int to ) { + if (from == to && from == ((unsigned)-1)) + return; + wxRect rect = GetLinesRect(from, to); m_owner->CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y); @@ -3325,21 +3355,35 @@ int wxDataViewMainWindow::GetLineStart( unsigned int row ) const if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) { - // TODO make more efficient - int start = 0; + if (m_rowHeightCache->GetLineStart(row, start)) + return start; unsigned int r; for (r = 0; r < row; r++) { - const wxDataViewTreeNode* node = GetTreeNodeByRow(r); - if (!node) return start; + int height = 0; + if (m_rowHeightCache->GetLineHeight(r, height)) + { + start += height; + continue; + } - wxDataViewItem item = node->GetItem(); + wxDataViewItem item; + if (IsList()) + { + item = GetItemByRow(r); + } + else + { + const wxDataViewTreeNode* node = GetTreeNodeByRow(r); + if (!node) return start; + item = node->GetItem(); + } unsigned int cols = GetOwner()->GetColumnCount(); unsigned int col; - int height = m_lineHeight; + height = m_lineHeight; for (col = 0; col < cols; col++) { const wxDataViewColumn *column = GetOwner()->GetColumn(col); @@ -3359,6 +3403,8 @@ int wxDataViewMainWindow::GetLineStart( unsigned int row ) const } start += height; + + m_rowHeightCache->Put(r, height); } return start; @@ -3377,39 +3423,58 @@ int wxDataViewMainWindow::GetLineAt( unsigned int y ) const if ( !GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT) ) return y / m_lineHeight; - // TODO make more efficient unsigned int row = 0; unsigned int yy = 0; + + if (m_rowHeightCache->GetLineAt(y, row)) + return row; + for (;;) { - const wxDataViewTreeNode* node = GetTreeNodeByRow(row); - if (!node) + int height = 0; + if (!m_rowHeightCache->GetLineHeight(row, height)) { - // not really correct... - return row + ((y-yy) / m_lineHeight); - } + // row height not in cache -> get it from the renderer... - wxDataViewItem item = node->GetItem(); + wxDataViewItem item; + if (IsList()) + { + item = GetItemByRow(row); + } + else + { + const wxDataViewTreeNode* node = GetTreeNodeByRow(row); + if (!node) + { + // not really correct... + return row + ((y - yy) / m_lineHeight); + } + item = node->GetItem(); + } - unsigned int cols = GetOwner()->GetColumnCount(); - unsigned int col; - int height = m_lineHeight; - for (col = 0; col < cols; col++) - { - const wxDataViewColumn *column = GetOwner()->GetColumn(col); - if (column->IsHidden()) - continue; // skip it! + unsigned int cols = GetOwner()->GetColumnCount(); + unsigned int col; + height = m_lineHeight; + for (col = 0; col < cols; col++) + { + const wxDataViewColumn *column = GetOwner()->GetColumn(col); + if (column->IsHidden()) + continue; // skip it! - if ((col != 0) && - model->IsContainer(item) && - !model->HasContainerColumns(item)) - continue; // skip it! + if ((col != 0) && + model->IsContainer(item) && + !model->HasContainerColumns(item)) + continue; // skip it! - wxDataViewRenderer *renderer = - const_cast(column->GetRenderer()); - renderer->PrepareForItem(model, item, column->GetModelColumn()); + wxDataViewRenderer *renderer = + const_cast(column->GetRenderer()); + renderer->PrepareForItem(model, item, column->GetModelColumn()); - height = wxMax( height, renderer->GetSize().y ); + height = wxMax( height, renderer->GetSize().y ); + } + + // ... and store the height in the cache + m_rowHeightCache->Put(row, height); } yy += height; @@ -3426,16 +3491,24 @@ int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) { - wxASSERT( !IsVirtualList() ); + int height = 0; + if (m_rowHeightCache->GetLineHeight(row, height)) + return height; - const wxDataViewTreeNode* node = GetTreeNodeByRow(row); - // wxASSERT( node ); - if (!node) return m_lineHeight; - - wxDataViewItem item = node->GetItem(); - - int height = m_lineHeight; + wxDataViewItem item; + if (IsList()) + { + item = GetItemByRow(row); + } + else + { + const wxDataViewTreeNode* node = GetTreeNodeByRow(row); + // wxASSERT( node ); + if (!node) return m_lineHeight; + item = node->GetItem(); + } + height = m_lineHeight; unsigned int cols = GetOwner()->GetColumnCount(); unsigned int col; for (col = 0; col < cols; col++) @@ -3456,6 +3529,8 @@ int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const height = wxMax( height, renderer->GetSize().y ); } + m_rowHeightCache->Put(row, height); + return height; } else @@ -3602,6 +3677,13 @@ void wxDataViewMainWindow::Expand( unsigned int row ) if (!node->HasChildren()) return; + if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT)) + { + // Expand makes new rows visible thus we invalidates all following + // rows in the height cache + m_rowHeightCache->Remove(row); + } + if (!node->IsOpen()) { if ( !SendExpanderEvent(wxEVT_DATAVIEW_ITEM_EXPANDING, node->GetItem()) ) @@ -3651,6 +3733,13 @@ void wxDataViewMainWindow::Collapse(unsigned int row) if (!node->HasChildren()) return; + if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT)) + { + // Collapse hides rows thus we invalidates all following + // rows in the height cache + m_rowHeightCache->Remove(row); + } + if (node->IsOpen()) { if ( !SendExpanderEvent(wxEVT_DATAVIEW_ITEM_COLLAPSING,node->GetItem()) ) diff --git a/src/generic/rowheightcache.cpp b/src/generic/rowheightcache.cpp new file mode 100644 index 0000000000..f3c43d5aa1 --- /dev/null +++ b/src/generic/rowheightcache.cpp @@ -0,0 +1,337 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/private/rowheightcache.h +// Purpose: height cache of rows in a dataview +// Author: Jens Goepfert (mail@jensgoepfert.de) +// Created: 2018-03-06 +// Copyright: (c) wxWidgets team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/log.h" +#endif // WX_PRECOMP + +#include "wx/generic/private/rowheightcache.h" + +// ---------------------------------------------------------------------------- +// private structs +// ---------------------------------------------------------------------------- + +// ============================================================================ +// implementation +// ============================================================================ + + +// ---------------------------------------------------------------------------- +// RowRanges +// ---------------------------------------------------------------------------- + +void RowRanges::Add(const unsigned int row) +{ + size_t count = m_ranges.size(); + size_t rngIdx = 0; + for (rngIdx = 0; rngIdx < count; ++rngIdx) + { + RowRange &rng = m_ranges[rngIdx]; + + if (row >= rng.from && rng.to > row) + { + // index already in range + return; + } + + if (row == rng.from - 1) + { + // extend range at the beginning (to the left) + rng.from = row; + // no cleanup necessary + return; + } + if (row == rng.to) + { + // extend range at the end (set to row+1 because 'to' is not including) + rng.to = row + 1; + CleanUp(rngIdx); + return; + } + + if (rng.from > row + 1) + { + // this range is already behind row index, so break here and insert a new range before + break; + } + } + // wxLogMessage("New Range: %d" , count); + + RowRange newRange; + newRange.from = row; + newRange.to = row + 1; + m_ranges.insert(m_ranges.begin() + rngIdx, newRange); +} + +void RowRanges::Remove(const unsigned int row) +{ + size_t count = m_ranges.size(); + size_t rngIdx = 0; + while (rngIdx < count) + { + RowRange &rng = m_ranges[rngIdx]; + if (rng.from >= row) + { + // this range starts behind row index, so remove it + m_ranges.erase(m_ranges.begin() + rngIdx); + count--; + continue; + } + if (rng.to > row) + { + // this ranges includes row, so cut off at row index to exclude row + rng.to = row; + } + + rngIdx += 1; + } +} + + +void RowRanges::CleanUp(unsigned int idx) +{ + size_t count = m_ranges.size(); + size_t rngIdx = 0; + if (idx > 0) + { + // start one RowRange before + rngIdx = idx - 1; + } + if (idx >= count) + { + // should never reached, due CleanUp is private and internal called correctly + return; + } + RowRange *prevRng = &m_ranges[rngIdx]; + rngIdx++; + while (rngIdx <= idx + 1 && rngIdx < count) + { + RowRange &rng = m_ranges[rngIdx]; + + if (prevRng->to == rng.from) + { + // this range starts where the previous range began, so remove this + // and set the to-value of the previous range to the to-value of this range + prevRng->to = rng.to; + m_ranges.erase(m_ranges.begin() + rngIdx); + count--; + continue; + } + + prevRng = &rng; + rngIdx += 1; + } +} + +bool RowRanges::Has(unsigned int row) const +{ + size_t count = m_ranges.size(); + for (size_t rngIdx = 0; rngIdx < count; rngIdx++) + { + const RowRange &rng = m_ranges[rngIdx]; + if (rng.from <= row && row < rng.to) + { + return true; + } + } + return false; +} + +unsigned int RowRanges::CountAll() const +{ + unsigned int ctr = 0; + size_t count = m_ranges.size(); + for (size_t rngIdx = 0; rngIdx < count; rngIdx++) + { + const RowRange &rng = m_ranges[rngIdx]; + ctr += rng.to - rng.from; + } + return ctr; +} + +unsigned int RowRanges::CountTo(unsigned int row) const +{ + unsigned int ctr = 0; + size_t count = m_ranges.size(); + for (size_t rngIdx = 0; rngIdx < count; rngIdx++) + { + const RowRange &rng = m_ranges[rngIdx]; + if (rng.from > row) + { + break; + } + else if (rng.to < row) + { + ctr += rng.to - rng.from; + } + else + { + ctr += row - rng.from; + break; + } + } + return ctr; +} + +unsigned int RowRanges::GetSize() const // for debugging statistics +{ + return m_ranges.size(); +} + + +// ---------------------------------------------------------------------------- +// HeightCache +// ---------------------------------------------------------------------------- + +bool HeightCache::GetLineInfo(unsigned int row, int &start, int &height) +{ + int y = 0; + bool found = false; + HeightToRowRangesMap::iterator it; + for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it) + { + int rowHeight = it->first; + RowRanges* rowRanges = it->second; + if (rowRanges->Has(row)) + { + height = rowHeight; + found = true; + } + y += rowHeight * (rowRanges->CountTo(row)); + } + if (found) + { + start = y; + } + return found; +} + +bool HeightCache::GetLineStart(unsigned int row, int &start) +{ + int height = 0; + return GetLineInfo(row, start, height); +} + +bool HeightCache::GetLineHeight(unsigned int row, int &height) +{ + HeightToRowRangesMap::iterator it; + for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it) + { + int rowHeight = it->first; + RowRanges* rowRanges = it->second; + if (rowRanges->Has(row)) + { + height = rowHeight; + return true; + } + } + return false; +} + +bool HeightCache::GetLineAt(int y, unsigned int &row) +{ + unsigned int total = 0; + HeightToRowRangesMap::iterator it; + for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it) + { + RowRanges* rowRanges = it->second; + total += rowRanges->CountAll(); + } + + if (total == 0) + { + return false; + } + + int lo = 0; + int hi = total; + int start, height; + while (lo < hi) + { + int mid = (lo + hi) / 2; + if (GetLineInfo(mid, start, height)) + { + if (start + height <= y) + { + lo = mid + 1; + } + else + { + hi = mid; + } + } + else + { + // should never happen, except the HeightCache has gaps which is an invalid state + return false; + } + } + if (GetLineInfo(lo, start, height)) + { + if (y < start) + { + // given y point is before the first row + return false; + } + row = lo; + return true; + } + else + { + // given y point is after the last row + return false; + } +} + +void HeightCache::Put(const unsigned int row, const int height) +{ + RowRanges *rowRanges = m_heightToRowRange[height]; + if (rowRanges == NULL) + { + rowRanges = new RowRanges(); + m_heightToRowRange[height] = rowRanges; + } + rowRanges->Add(row); +} + +void HeightCache::Remove(const unsigned int row) +{ + HeightToRowRangesMap::iterator it; + for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it) + { + RowRanges* rowRanges = it->second; + rowRanges->Remove(row); + } +} + +void HeightCache::Clear() +{ + HeightToRowRangesMap::iterator it; + for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it) + { + RowRanges* rowRanges = it->second; + delete rowRanges; + } + m_heightToRowRange.clear(); +} diff --git a/tests/Makefile.in b/tests/Makefile.in index f5dfdc06dc..ce5b95441e 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -254,6 +254,7 @@ TEST_GUI_OBJECTS = \ test_gui_socket.o \ test_gui_tlw.o \ test_gui_dataview.o \ + test_gui_rowheightcachetest.o \ test_gui_boxsizer.o \ test_gui_gridsizer.o \ test_gui_wrapsizer.o \ @@ -1030,6 +1031,9 @@ test_gui_tlw.o: $(srcdir)/persistence/tlw.cpp $(TEST_GUI_ODEP) test_gui_dataview.o: $(srcdir)/persistence/dataview.cpp $(TEST_GUI_ODEP) $(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/persistence/dataview.cpp +test_gui_rowheightcachetest.o: $(srcdir)/rowheightcache/rowheightcachetest.cpp $(TEST_GUI_ODEP) + $(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/rowheightcache/rowheightcachetest.cpp + test_gui_boxsizer.o: $(srcdir)/sizers/boxsizer.cpp $(TEST_GUI_ODEP) $(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/sizers/boxsizer.cpp diff --git a/tests/makefile.bcc b/tests/makefile.bcc index a0892cbd57..8d81a43d47 100644 --- a/tests/makefile.bcc +++ b/tests/makefile.bcc @@ -241,6 +241,7 @@ TEST_GUI_OBJECTS = \ $(OBJS)\test_gui_socket.obj \ $(OBJS)\test_gui_tlw.obj \ $(OBJS)\test_gui_dataview.obj \ + $(OBJS)\test_gui_rowheightcachetest.obj \ $(OBJS)\test_gui_boxsizer.obj \ $(OBJS)\test_gui_gridsizer.obj \ $(OBJS)\test_gui_wrapsizer.obj \ @@ -1084,6 +1085,9 @@ $(OBJS)\test_gui_tlw.obj: .\persistence\tlw.cpp $(OBJS)\test_gui_dataview.obj: .\persistence\dataview.cpp $(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\persistence\dataview.cpp +$(OBJS)\test_gui_rowheightcachetest.obj: .\rowheightcache\rowheightcachetest.cpp + $(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\rowheightcache\rowheightcachetest.cpp + $(OBJS)\test_gui_boxsizer.obj: .\sizers\boxsizer.cpp $(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\sizers\boxsizer.cpp diff --git a/tests/makefile.gcc b/tests/makefile.gcc index a4e16537b8..5df276613e 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -236,6 +236,7 @@ TEST_GUI_OBJECTS = \ $(OBJS)\test_gui_socket.o \ $(OBJS)\test_gui_tlw.o \ $(OBJS)\test_gui_dataview.o \ + $(OBJS)\test_gui_rowheightcachetest.o \ $(OBJS)\test_gui_boxsizer.o \ $(OBJS)\test_gui_gridsizer.o \ $(OBJS)\test_gui_wrapsizer.o \ @@ -1061,6 +1062,9 @@ $(OBJS)\test_gui_tlw.o: ./persistence/tlw.cpp $(OBJS)\test_gui_dataview.o: ./persistence/dataview.cpp $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\test_gui_rowheightcachetest.o: ./rowheightcache/rowheightcachetest.cpp + $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\test_gui_boxsizer.o: ./sizers/boxsizer.cpp $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $< diff --git a/tests/makefile.vc b/tests/makefile.vc index e197998717..0fbadd461a 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -247,6 +247,7 @@ TEST_GUI_OBJECTS = \ $(OBJS)\test_gui_socket.obj \ $(OBJS)\test_gui_tlw.obj \ $(OBJS)\test_gui_dataview.obj \ + $(OBJS)\test_gui_rowheightcachetest.obj \ $(OBJS)\test_gui_boxsizer.obj \ $(OBJS)\test_gui_gridsizer.obj \ $(OBJS)\test_gui_wrapsizer.obj \ @@ -1275,6 +1276,9 @@ $(OBJS)\test_gui_tlw.obj: .\persistence\tlw.cpp $(OBJS)\test_gui_dataview.obj: .\persistence\dataview.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\persistence\dataview.cpp +$(OBJS)\test_gui_rowheightcachetest.obj: .\rowheightcache\rowheightcachetest.cpp + $(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\rowheightcache\rowheightcachetest.cpp + $(OBJS)\test_gui_boxsizer.obj: .\sizers\boxsizer.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\sizers\boxsizer.cpp diff --git a/tests/rowheightcache/rowheightcachetest.cpp b/tests/rowheightcache/rowheightcachetest.cpp new file mode 100644 index 0000000000..51e0ac1daa --- /dev/null +++ b/tests/rowheightcache/rowheightcachetest.cpp @@ -0,0 +1,280 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/rowheightcache/rowheightcachetest.cpp +// Purpose: unit tests for the row height cache of a dataview +// Author: Jens Goepfert (mail@jensgoepfert.de) +// Created: 2018-03-06 +// Copyright: (c) wxWidgets team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "testprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#endif + +#include "wx/generic/private/rowheightcache.h" + +// ---------------------------------------------------------------------------- +// local functions +// ---------------------------------------------------------------------------- + + +// ---------------------------------------------------------------------------- +// TestRowRangesAdd +// ---------------------------------------------------------------------------- +TEST_CASE("RowHeightCacheTestCase::TestRowRangesSimple", "[dataview][heightcache]") +{ + RowRanges *rr = new RowRanges(); + + CHECK(rr->CountAll() == 0); + + for (unsigned int i = 0; i <= 10; i++) + { + CHECK(rr->Has(i) == false); + + rr->Add(i); + + CHECK(rr->CountAll() == i+1); + CHECK(rr->CountTo(i) == i); + CHECK(rr->Has(i) == true); + } + + CHECK(rr->GetSize() == 1); // every row is sorted in the same range, so count == 1 + CHECK(rr->CountAll() == 11); // 11 rows collected + CHECK(rr->CountTo(10) == 10); + + rr->Add(5); // row 5 already contained -> does nothing + + CHECK(rr->GetSize() == 1); // every row is sorted in the same range, so count == 1 + CHECK(rr->CountAll() == 11); // 11 rows collected + CHECK(rr->CountTo(10) == 10); + + for (int i = 10; i >= 0; i--) + { + CHECK(rr->CountAll() == (unsigned)i+1); + CHECK(rr->CountTo((unsigned)i) == (unsigned)i); + + rr->Remove(i); + + CHECK(rr->CountAll() == (unsigned)i); + CHECK(rr->CountTo((unsigned)i) == (unsigned)i); + } + + CHECK(rr->CountAll() == 0); // everything removed, no row range is left behind + for (int i = 10; i > 0; i--) + { + CHECK(rr->CountTo(i) == 0); + } + CHECK(rr->GetSize() == 0); +} + +// ---------------------------------------------------------------------------- +// TestRowRangesRemove +// ---------------------------------------------------------------------------- +TEST_CASE("RowHeightCacheTestCase::TestRowRangesGapsMod2", "[dataview][heightcache]") +{ + RowRanges *rr = new RowRanges(); + for (int i = 0; i < 100; i++) + { + CHECK(rr->Has(i) == false); + + if (i % 2 == 0) + { + rr->Add(i); + } + } + CHECK(rr->CountAll() == 50); + CHECK(rr->CountTo(100) == 50); + + for (unsigned int i = 99; i > 0; i--) + { + if (i % 2 == 0) + { + CHECK(rr->Has(i) == true); + rr->Remove(i); + CHECK(rr->Has(i) == false); + } + else + { + CHECK(rr->Has(i) == false); + } + } + + // only row 0 is in the RowRanges, so remove 1 does nothing + rr->Remove(1); + + CHECK(rr->CountAll() == 1); + CHECK(rr->CountTo(0) == 0); + CHECK(rr->CountTo(1) == 1); + CHECK(rr->CountTo(100) == 1); + CHECK(rr->GetSize() == 1); + + rr->Remove(0); // last row is beeing removed + + CHECK(rr->CountAll() == 0); + CHECK(rr->CountTo(0) == 0); + CHECK(rr->CountTo(1) == 0); + CHECK(rr->CountTo(100) == 0); + CHECK(rr->GetSize() == 0); + + rr->Add(10); + CHECK(rr->GetSize() == 1); + CHECK(rr->CountTo(1) == 0); // tests CountTo first break + rr->Add(5); // inserts a range at the beginning + CHECK(rr->GetSize() == 2); + rr->Remove(10); + rr->Remove(5); + CHECK(rr->GetSize() == 0); +} + +// ---------------------------------------------------------------------------- +// TestRowRangesCleanUp1 +// ---------------------------------------------------------------------------- +TEST_CASE("RowHeightCacheTestCase::TestRowRangesCleanUp1", "[dataview][heightcache]") +{ + RowRanges *rr = new RowRanges(); + for (unsigned int i = 0; i < 100; i++) + { + CHECK(rr->Has(i) == false); + + if (i % 2 == 0) + { + rr->Add(i); + } + } + CHECK(rr->GetSize() == 50); // adding 50 rows (only even) results in 50 range objects + CHECK(rr->CountAll() == 50); + CHECK(rr->CountTo(100) == 50); + + for (unsigned int i = 0; i < 100; i++) + { + if (i % 2 == 1) + { + rr->Add(i); + } + } + + CHECK(rr->GetSize() == 1); // adding 50 rows (only odd) should combined to 1 range object + CHECK(rr->CountAll() == 100); + CHECK(rr->CountTo(100) == 100); +} + +// ---------------------------------------------------------------------------- +// TestRowRangesCleanUp2 +// ---------------------------------------------------------------------------- +TEST_CASE("RowHeightCacheTestCase::TestRowRangesCleanUp2", "[dataview][heightcache]") +{ + RowRanges *rr = new RowRanges(); + for (unsigned int i = 0; i < 10; i++) + { + rr->Add(i); + } + CHECK(rr->GetSize() == 1); // adding 10 sequent rows results in 1 range objects + CHECK(rr->CountAll() == 10); + CHECK(rr->CountTo(100) == 10); + + for (unsigned int i = 12; i < 20; i++) + { + rr->Add(i); + } + + CHECK(rr->GetSize() == 2); + rr->Add(11); // tests extending a range at the beginning (to the left) + CHECK(rr->GetSize() == 2); + rr->Add(10); // extends a range and reduces them + CHECK(rr->GetSize() == 1); +} + +// ---------------------------------------------------------------------------- +// TestHeightCache +// ---------------------------------------------------------------------------- +TEST_CASE("RowHeightCacheTestCase::TestHeightCache", "[dataview][heightcache]") +{ + HeightCache *hc = new HeightCache(); + + for (unsigned int i = 0; i <= 10; i++) + { + hc->Put(i, 22); + } + for (unsigned int i = 15; i <= 17; i++) + { + hc->Put(i, 22); + } + for (unsigned int i = 20; i <= 2000; i++) + { + hc->Put(i, 22); + } + + hc->Put(11, 42); + hc->Put(12, 42); + hc->Put(18, 42); + + hc->Put(13, 62); + hc->Put(14, 62); + hc->Put(19, 62); + + int start = 0; + int height = 0; + unsigned int row = 666; + + CHECK(hc->GetLineStart(1000, start) == true); + CHECK(start == 22180); + + CHECK(hc->GetLineHeight(1000, height) == true); + CHECK(height == 22); + + CHECK(hc->GetLineHeight(5000, start) == false); + + // test invalid y + CHECK(hc->GetLineAt(-1, row) == false); + CHECK(row == 666); + + // test start of first row + CHECK(hc->GetLineAt(0, row) == true); + CHECK(row == 0); + + // test end of first row + CHECK(hc->GetLineAt(21, row) == true); + CHECK(row == 0); + + // test start of second row + CHECK(hc->GetLineAt(22, row) == true); + CHECK(row == 1); + + hc->Remove(1000); // Delete row 1000 and everything behind + + CHECK(hc->GetLineAt(22179, row) == true); + CHECK(row == 999); + CHECK(hc->GetLineHeight(999, height) == true); + CHECK(height == 22); + + row = 666; + height = 666; + CHECK(hc->GetLineAt(22180, row) == false); + CHECK(row == 666); + CHECK(hc->GetLineHeight(1000, height) == false); + CHECK(height == 666); + + hc->Clear(); // Clear all items + for (int i = 20; i <= 2000; i++) + { + height = 666; + CHECK(hc->GetLineHeight(i, height) == false); + CHECK(height == 666); + } + + hc->Clear(); // Clear twice should not crash + + row = 666; + height = 666; + CHECK(hc->GetLineAt(22180, row) == false); + CHECK(row == 666); +} diff --git a/tests/test.bkl b/tests/test.bkl index b8c42324c8..62eeddde4f 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -266,6 +266,7 @@ net/socket.cpp persistence/tlw.cpp persistence/dataview.cpp + rowheightcache/rowheightcachetest.cpp sizers/boxsizer.cpp sizers/gridsizer.cpp sizers/wrapsizer.cpp diff --git a/tests/test_vc7_test_gui.vcproj b/tests/test_vc7_test_gui.vcproj index d02aa25b43..62698892cc 100644 --- a/tests/test_vc7_test_gui.vcproj +++ b/tests/test_vc7_test_gui.vcproj @@ -523,6 +523,9 @@ + + diff --git a/tests/test_vc8_test_gui.vcproj b/tests/test_vc8_test_gui.vcproj index f82a0b7ed7..cc0031584f 100644 --- a/tests/test_vc8_test_gui.vcproj +++ b/tests/test_vc8_test_gui.vcproj @@ -1166,6 +1166,10 @@ RelativePath=".\controls\richtextctrltest.cpp" > + + diff --git a/tests/test_vc9_test_gui.vcproj b/tests/test_vc9_test_gui.vcproj index 9c5b2a55b9..dc7119cdfc 100644 --- a/tests/test_vc9_test_gui.vcproj +++ b/tests/test_vc9_test_gui.vcproj @@ -1138,6 +1138,10 @@ RelativePath=".\controls\richtextctrltest.cpp" > + +