diff --git a/Makefile.in b/Makefile.in
index ff78f39f6d..44cfcabc1e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -2289,6 +2289,7 @@ RIBBONDLL_OBJECTS = \
ribbondll_art_internal.o \
ribbondll_art_msw.o \
ribbondll_art_aui.o \
+ ribbondll_art_msw_flat.o \
ribbondll_bar.o \
ribbondll_buttonbar.o \
ribbondll_control.o \
@@ -2308,6 +2309,7 @@ RIBBONLIB_OBJECTS = \
ribbonlib_art_internal.o \
ribbonlib_art_msw.o \
ribbonlib_art_aui.o \
+ ribbonlib_art_msw_flat.o \
ribbonlib_bar.o \
ribbonlib_buttonbar.o \
ribbonlib_control.o \
@@ -4338,6 +4340,7 @@ COND_USE_GUI_1___MONOLIB_GUI_SRC_OBJECTS = \
monodll_art_internal.o \
monodll_art_msw.o \
monodll_art_aui.o \
+ monodll_art_msw_flat.o \
monodll_bar.o \
monodll_ribbon_buttonbar.o \
monodll_ribbon_control.o \
@@ -6123,6 +6126,7 @@ COND_USE_GUI_1___MONOLIB_GUI_SRC_OBJECTS_1 = \
monolib_art_internal.o \
monolib_art_msw.o \
monolib_art_aui.o \
+ monolib_art_msw_flat.o \
monolib_bar.o \
monolib_ribbon_buttonbar.o \
monolib_ribbon_control.o \
@@ -16941,6 +16945,9 @@ monodll_art_msw.o: $(srcdir)/src/ribbon/art_msw.cpp $(MONODLL_ODEP)
monodll_art_aui.o: $(srcdir)/src/ribbon/art_aui.cpp $(MONODLL_ODEP)
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/ribbon/art_aui.cpp
+monodll_art_msw_flat.o: $(srcdir)/src/ribbon/art_msw_flat.cpp $(MONODLL_ODEP)
+ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/ribbon/art_msw_flat.cpp
+
monodll_bar.o: $(srcdir)/src/ribbon/bar.cpp $(MONODLL_ODEP)
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/ribbon/bar.cpp
@@ -21729,6 +21736,9 @@ monolib_art_msw.o: $(srcdir)/src/ribbon/art_msw.cpp $(MONOLIB_ODEP)
monolib_art_aui.o: $(srcdir)/src/ribbon/art_aui.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/ribbon/art_aui.cpp
+monolib_art_msw_flat.o: $(srcdir)/src/ribbon/art_msw_flat.cpp $(MONOLIB_ODEP)
+ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/ribbon/art_msw_flat.cpp
+
monolib_bar.o: $(srcdir)/src/ribbon/bar.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/ribbon/bar.cpp
@@ -34302,6 +34312,9 @@ ribbondll_art_msw.o: $(srcdir)/src/ribbon/art_msw.cpp $(RIBBONDLL_ODEP)
ribbondll_art_aui.o: $(srcdir)/src/ribbon/art_aui.cpp $(RIBBONDLL_ODEP)
$(CXXC) -c -o $@ $(RIBBONDLL_CXXFLAGS) $(srcdir)/src/ribbon/art_aui.cpp
+ribbondll_art_msw_flat.o: $(srcdir)/src/ribbon/art_msw_flat.cpp $(RIBBONDLL_ODEP)
+ $(CXXC) -c -o $@ $(RIBBONDLL_CXXFLAGS) $(srcdir)/src/ribbon/art_msw_flat.cpp
+
ribbondll_bar.o: $(srcdir)/src/ribbon/bar.cpp $(RIBBONDLL_ODEP)
$(CXXC) -c -o $@ $(RIBBONDLL_CXXFLAGS) $(srcdir)/src/ribbon/bar.cpp
@@ -34335,6 +34348,9 @@ ribbonlib_art_msw.o: $(srcdir)/src/ribbon/art_msw.cpp $(RIBBONLIB_ODEP)
ribbonlib_art_aui.o: $(srcdir)/src/ribbon/art_aui.cpp $(RIBBONLIB_ODEP)
$(CXXC) -c -o $@ $(RIBBONLIB_CXXFLAGS) $(srcdir)/src/ribbon/art_aui.cpp
+ribbonlib_art_msw_flat.o: $(srcdir)/src/ribbon/art_msw_flat.cpp $(RIBBONLIB_ODEP)
+ $(CXXC) -c -o $@ $(RIBBONLIB_CXXFLAGS) $(srcdir)/src/ribbon/art_msw_flat.cpp
+
ribbonlib_bar.o: $(srcdir)/src/ribbon/bar.cpp $(RIBBONLIB_ODEP)
$(CXXC) -c -o $@ $(RIBBONLIB_CXXFLAGS) $(srcdir)/src/ribbon/bar.cpp
diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl
index 9df77fa7a4..97c17c98d3 100644
--- a/build/bakefiles/files.bkl
+++ b/build/bakefiles/files.bkl
@@ -3067,6 +3067,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/ribbon/art_internal.cpp
src/ribbon/art_msw.cpp
src/ribbon/art_aui.cpp
+ src/ribbon/art_msw_flat.cpp
src/ribbon/bar.cpp
src/ribbon/buttonbar.cpp
src/ribbon/control.cpp
diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake
index c163c8752a..5be2db93e2 100644
--- a/build/cmake/files.cmake
+++ b/build/cmake/files.cmake
@@ -2798,6 +2798,7 @@ set(RIBBON_SRC
src/ribbon/art_internal.cpp
src/ribbon/art_msw.cpp
src/ribbon/art_aui.cpp
+ src/ribbon/art_msw_flat.cpp
src/ribbon/bar.cpp
src/ribbon/buttonbar.cpp
src/ribbon/control.cpp
diff --git a/build/files b/build/files
index 12357c3cdb..04b6561a60 100644
--- a/build/files
+++ b/build/files
@@ -2758,6 +2758,7 @@ RIBBON_SRC =
src/ribbon/art_internal.cpp
src/ribbon/art_msw.cpp
src/ribbon/art_aui.cpp
+ src/ribbon/art_msw_flat.cpp
src/ribbon/bar.cpp
src/ribbon/buttonbar.cpp
src/ribbon/control.cpp
diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc
index 64e511aafa..9a6b527414 100644
--- a/build/msw/makefile.gcc
+++ b/build/msw/makefile.gcc
@@ -1662,6 +1662,7 @@ RIBBONDLL_OBJECTS = \
$(OBJS)\ribbondll_art_internal.o \
$(OBJS)\ribbondll_art_msw.o \
$(OBJS)\ribbondll_art_aui.o \
+ $(OBJS)\ribbondll_art_msw_flat.o \
$(OBJS)\ribbondll_bar.o \
$(OBJS)\ribbondll_buttonbar.o \
$(OBJS)\ribbondll_control.o \
@@ -1683,6 +1684,7 @@ RIBBONLIB_OBJECTS = \
$(OBJS)\ribbonlib_art_internal.o \
$(OBJS)\ribbonlib_art_msw.o \
$(OBJS)\ribbonlib_art_aui.o \
+ $(OBJS)\ribbonlib_art_msw_flat.o \
$(OBJS)\ribbonlib_bar.o \
$(OBJS)\ribbonlib_buttonbar.o \
$(OBJS)\ribbonlib_control.o \
@@ -2048,6 +2050,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_art_internal.o \
$(OBJS)\monodll_art_msw.o \
$(OBJS)\monodll_art_aui.o \
+ $(OBJS)\monodll_art_msw_flat.o \
$(OBJS)\monodll_bar.o \
$(OBJS)\monodll_ribbon_buttonbar.o \
$(OBJS)\monodll_ribbon_control.o \
@@ -2915,6 +2918,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_art_internal.o \
$(OBJS)\monolib_art_msw.o \
$(OBJS)\monolib_art_aui.o \
+ $(OBJS)\monolib_art_msw_flat.o \
$(OBJS)\monolib_bar.o \
$(OBJS)\monolib_ribbon_buttonbar.o \
$(OBJS)\monolib_ribbon_control.o \
@@ -8854,6 +8858,9 @@ $(OBJS)\monodll_art_msw.o: ../../src/ribbon/art_msw.cpp
$(OBJS)\monodll_art_aui.o: ../../src/ribbon/art_aui.cpp
$(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\monodll_art_msw_flat.o: ../../src/ribbon/art_msw_flat.cpp
+ $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\monodll_bar.o: ../../src/ribbon/bar.cpp
$(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<
@@ -11474,6 +11481,9 @@ $(OBJS)\monolib_art_msw.o: ../../src/ribbon/art_msw.cpp
$(OBJS)\monolib_art_aui.o: ../../src/ribbon/art_aui.cpp
$(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\monolib_art_msw_flat.o: ../../src/ribbon/art_msw_flat.cpp
+ $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\monolib_bar.o: ../../src/ribbon/bar.cpp
$(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $<
@@ -18134,6 +18144,9 @@ $(OBJS)\ribbondll_art_msw.o: ../../src/ribbon/art_msw.cpp
$(OBJS)\ribbondll_art_aui.o: ../../src/ribbon/art_aui.cpp
$(CXX) -c -o $@ $(RIBBONDLL_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\ribbondll_art_msw_flat.o: ../../src/ribbon/art_msw_flat.cpp
+ $(CXX) -c -o $@ $(RIBBONDLL_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\ribbondll_bar.o: ../../src/ribbon/bar.cpp
$(CXX) -c -o $@ $(RIBBONDLL_CXXFLAGS) $(CPPDEPS) $<
@@ -18170,6 +18183,9 @@ $(OBJS)\ribbonlib_art_msw.o: ../../src/ribbon/art_msw.cpp
$(OBJS)\ribbonlib_art_aui.o: ../../src/ribbon/art_aui.cpp
$(CXX) -c -o $@ $(RIBBONLIB_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\ribbonlib_art_msw_flat.o: ../../src/ribbon/art_msw_flat.cpp
+ $(CXX) -c -o $@ $(RIBBONLIB_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\ribbonlib_bar.o: ../../src/ribbon/bar.cpp
$(CXX) -c -o $@ $(RIBBONLIB_CXXFLAGS) $(CPPDEPS) $<
diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc
index 7ddd306739..8303f0fbc2 100644
--- a/build/msw/makefile.vc
+++ b/build/msw/makefile.vc
@@ -1853,6 +1853,7 @@ RIBBONDLL_OBJECTS = \
$(OBJS)\ribbondll_art_internal.obj \
$(OBJS)\ribbondll_art_msw.obj \
$(OBJS)\ribbondll_art_aui.obj \
+ $(OBJS)\ribbondll_art_msw_flat.obj \
$(OBJS)\ribbondll_bar.obj \
$(OBJS)\ribbondll_buttonbar.obj \
$(OBJS)\ribbondll_control.obj \
@@ -1881,6 +1882,7 @@ RIBBONLIB_OBJECTS = \
$(OBJS)\ribbonlib_art_internal.obj \
$(OBJS)\ribbonlib_art_msw.obj \
$(OBJS)\ribbonlib_art_aui.obj \
+ $(OBJS)\ribbonlib_art_msw_flat.obj \
$(OBJS)\ribbonlib_bar.obj \
$(OBJS)\ribbonlib_buttonbar.obj \
$(OBJS)\ribbonlib_control.obj \
@@ -2435,6 +2437,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_art_internal.obj \
$(OBJS)\monodll_art_msw.obj \
$(OBJS)\monodll_art_aui.obj \
+ $(OBJS)\monodll_art_msw_flat.obj \
$(OBJS)\monodll_bar.obj \
$(OBJS)\monodll_ribbon_buttonbar.obj \
$(OBJS)\monodll_ribbon_control.obj \
@@ -3302,6 +3305,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_art_internal.obj \
$(OBJS)\monolib_art_msw.obj \
$(OBJS)\monolib_art_aui.obj \
+ $(OBJS)\monolib_art_msw_flat.obj \
$(OBJS)\monolib_bar.obj \
$(OBJS)\monolib_ribbon_buttonbar.obj \
$(OBJS)\monolib_ribbon_control.obj \
@@ -9356,6 +9360,9 @@ $(OBJS)\monodll_art_msw.obj: ..\..\src\ribbon\art_msw.cpp
$(OBJS)\monodll_art_aui.obj: ..\..\src\ribbon\art_aui.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\ribbon\art_aui.cpp
+$(OBJS)\monodll_art_msw_flat.obj: ..\..\src\ribbon\art_msw_flat.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\ribbon\art_msw_flat.cpp
+
$(OBJS)\monodll_bar.obj: ..\..\src\ribbon\bar.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\ribbon\bar.cpp
@@ -11976,6 +11983,9 @@ $(OBJS)\monolib_art_msw.obj: ..\..\src\ribbon\art_msw.cpp
$(OBJS)\monolib_art_aui.obj: ..\..\src\ribbon\art_aui.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\ribbon\art_aui.cpp
+$(OBJS)\monolib_art_msw_flat.obj: ..\..\src\ribbon\art_msw_flat.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\ribbon\art_msw_flat.cpp
+
$(OBJS)\monolib_bar.obj: ..\..\src\ribbon\bar.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\ribbon\bar.cpp
@@ -18636,6 +18646,9 @@ $(OBJS)\ribbondll_art_msw.obj: ..\..\src\ribbon\art_msw.cpp
$(OBJS)\ribbondll_art_aui.obj: ..\..\src\ribbon\art_aui.cpp
$(CXX) /c /nologo /TP /Fo$@ $(RIBBONDLL_CXXFLAGS) ..\..\src\ribbon\art_aui.cpp
+$(OBJS)\ribbondll_art_msw_flat.obj: ..\..\src\ribbon\art_msw_flat.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(RIBBONDLL_CXXFLAGS) ..\..\src\ribbon\art_msw_flat.cpp
+
$(OBJS)\ribbondll_bar.obj: ..\..\src\ribbon\bar.cpp
$(CXX) /c /nologo /TP /Fo$@ $(RIBBONDLL_CXXFLAGS) ..\..\src\ribbon\bar.cpp
@@ -18672,6 +18685,9 @@ $(OBJS)\ribbonlib_art_msw.obj: ..\..\src\ribbon\art_msw.cpp
$(OBJS)\ribbonlib_art_aui.obj: ..\..\src\ribbon\art_aui.cpp
$(CXX) /c /nologo /TP /Fo$@ $(RIBBONLIB_CXXFLAGS) ..\..\src\ribbon\art_aui.cpp
+$(OBJS)\ribbonlib_art_msw_flat.obj: ..\..\src\ribbon\art_msw_flat.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(RIBBONLIB_CXXFLAGS) ..\..\src\ribbon\art_msw_flat.cpp
+
$(OBJS)\ribbonlib_bar.obj: ..\..\src\ribbon\bar.cpp
$(CXX) /c /nologo /TP /Fo$@ $(RIBBONLIB_CXXFLAGS) ..\..\src\ribbon\bar.cpp
diff --git a/build/msw/wx_ribbon.vcxproj b/build/msw/wx_ribbon.vcxproj
index a797505c2e..73f6867d72 100644
--- a/build/msw/wx_ribbon.vcxproj
+++ b/build/msw/wx_ribbon.vcxproj
@@ -859,6 +859,7 @@
Create
+
diff --git a/build/msw/wx_ribbon.vcxproj.filters b/build/msw/wx_ribbon.vcxproj.filters
index 046fb494c9..36fadd1410 100644
--- a/build/msw/wx_ribbon.vcxproj.filters
+++ b/build/msw/wx_ribbon.vcxproj.filters
@@ -28,6 +28,9 @@
Source Files
+
+ Source Files
+
Source Files
diff --git a/build/osx/wxcocoa.xcodeproj/project.pbxproj b/build/osx/wxcocoa.xcodeproj/project.pbxproj
index 5c94bc69b0..68971c5274 100644
--- a/build/osx/wxcocoa.xcodeproj/project.pbxproj
+++ b/build/osx/wxcocoa.xcodeproj/project.pbxproj
@@ -282,6 +282,7 @@
AAABEE399008310A8BC9BE43 /* imagtga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7029BB5751398AA02D8C24 /* imagtga.cpp */; };
3C0EB1DDA5243E31B2D92CE2 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 02D9332D5C5632E981936E29 /* jquant2.c */; };
A0BA01A85C303C78A3130711 /* art_aui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5E8709C3BC3727BBC7B97A /* art_aui.cpp */; };
+ F1A2B3C4D5E63C78A3130711 /* art_msw_flat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F1A2B3C4D5E63727BBC7B97A /* art_msw_flat.cpp */; };
EBDEBA86AA7930EB86A02E67 /* ssim.c in Sources */ = {isa = PBXBuildFile; fileRef = 5CECF4A5F2D839E397B3143F /* ssim.c */; };
246B4FF96BA135258FE45F50 /* encconv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C269E9CA99DF3AE5B1BD6AFA /* encconv.cpp */; };
699D88EE2DAA3594B6606890 /* ViewStyle.cxx in Sources */ = {isa = PBXBuildFile; fileRef = C133B838193A35ABBB803151 /* ViewStyle.cxx */; };
@@ -1402,6 +1403,7 @@
95826E8528CC32D8934C36ED /* xh_frame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5A9B63746753EDFB2EC48D3 /* xh_frame.cpp */; };
EDD92822EBD93E86AE5A2ED2 /* slidercmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8072CA67D19346ABF4D465F /* slidercmn.cpp */; };
A0BA01A85C303C78A3130712 /* art_aui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5E8709C3BC3727BBC7B97A /* art_aui.cpp */; };
+ F1A2B3C4D5E63C78A3130712 /* art_msw_flat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F1A2B3C4D5E63727BBC7B97A /* art_msw_flat.cpp */; };
CF3082BA1ED232F4B904BD15 /* stdpbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 75BF90BEF2F83BF28EC0458D /* stdpbase.cpp */; };
D9EE059D3C3C3C13AE4419F2 /* stattextcmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 54BD19211DBD388AA0DEC7A1 /* stattextcmn.cpp */; };
FE5B7C7A84B83C17A38E8405 /* LexSML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 912B2982C9413F2FB40CA2D9 /* LexSML.cxx */; };
@@ -3100,6 +3102,7 @@
DC928C38CA8331F18FF00BCD /* tif_lzma.c in Sources */ = {isa = PBXBuildFile; fileRef = 3088384F07C63A5DB3581656 /* tif_lzma.c */; };
8AA341CCFB8E3F6AB3523597 /* splash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F8836E29C5A370E80CE070E /* splash.cpp */; };
A0BA01A85C303C78A3130713 /* art_aui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5E8709C3BC3727BBC7B97A /* art_aui.cpp */; };
+ F1A2B3C4D5E63C78A3130713 /* art_msw_flat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F1A2B3C4D5E63727BBC7B97A /* art_msw_flat.cpp */; };
CB078622E90F33BE9D131135 /* buttonbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5612DBC4125B379DA2B28824 /* buttonbar.cpp */; };
1BCC944F5E0936F5830F03EA /* windowid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9B9B85572D0312BBF2878DB /* windowid.cpp */; };
0FDDE8E193743F3A8CBDC67D /* richtextprint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C4C45D3C63AA37CEBCE83321 /* richtextprint.cpp */; };
@@ -5604,6 +5607,7 @@
A298576700C33F018616E7BD /* auibook.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = auibook.cpp; path = ../../src/aui/auibook.cpp; sourceTree = SOURCE_ROOT; };
5F555177554E398286DBC6FB /* xh_stlin.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = xh_stlin.cpp; path = ../../src/xrc/xh_stlin.cpp; sourceTree = SOURCE_ROOT; };
DD5E8709C3BC3727BBC7B97A /* art_aui.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = art_aui.cpp; path = ../../src/ribbon/art_aui.cpp; sourceTree = SOURCE_ROOT; };
+ F1A2B3C4D5E63727BBC7B97A /* art_msw_flat.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = art_msw_flat.cpp; path = ../../src/ribbon/art_msw_flat.cpp; sourceTree = SOURCE_ROOT; };
42040492AAA43A60BA8DE111 /* filter_enc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = filter_enc.c; path = ../../3rdparty/libwebp/src/enc/filter_enc.c; sourceTree = SOURCE_ROOT; };
23FC98E2305230E2990471E3 /* wxcrt.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = wxcrt.cpp; path = ../../src/common/wxcrt.cpp; sourceTree = SOURCE_ROOT; };
BACAA6CE4A0934459F26B27C /* graphicc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = graphicc.cpp; path = ../../src/generic/graphicc.cpp; sourceTree = SOURCE_ROOT; };
@@ -6140,6 +6144,7 @@
4C4649974D8B3A109D1BF145 /* art_internal.cpp */,
B540E18F9C91381CA175BABB /* art_msw.cpp */,
DD5E8709C3BC3727BBC7B97A /* art_aui.cpp */,
+ F1A2B3C4D5E63727BBC7B97A /* art_msw_flat.cpp */,
9FDDE855D9F83E4891362EB4 /* bar.cpp */,
5612DBC4125B379DA2B28824 /* buttonbar.cpp */,
12363D1F50FE301DAEE7F04B /* control.cpp */,
@@ -9451,6 +9456,7 @@
DE43350F6C9D3148A64F0AFB /* art_internal.cpp in Sources */,
7DC4A542372437ECA0790F89 /* art_msw.cpp in Sources */,
A0BA01A85C303C78A3130713 /* art_aui.cpp in Sources */,
+ F1A2B3C4D5E63C78A3130713 /* art_msw_flat.cpp in Sources */,
056CA84179433AA48D55DA67 /* bar.cpp in Sources */,
CB078622E90F33BE9D131134 /* buttonbar.cpp in Sources */,
EB52C6A91594381393294502 /* control.cpp in Sources */,
@@ -10108,6 +10114,7 @@
DE43350F6C9D3148A64F0AF9 /* art_internal.cpp in Sources */,
7DC4A542372437ECA0790F87 /* art_msw.cpp in Sources */,
A0BA01A85C303C78A3130711 /* art_aui.cpp in Sources */,
+ F1A2B3C4D5E63C78A3130711 /* art_msw_flat.cpp in Sources */,
056CA84179433AA48D55DA65 /* bar.cpp in Sources */,
CB078622E90F33BE9D131135 /* buttonbar.cpp in Sources */,
EB52C6A91594381393294500 /* control.cpp in Sources */,
@@ -11584,6 +11591,7 @@
DE43350F6C9D3148A64F0AFA /* art_internal.cpp in Sources */,
7DC4A542372437ECA0790F88 /* art_msw.cpp in Sources */,
A0BA01A85C303C78A3130712 /* art_aui.cpp in Sources */,
+ F1A2B3C4D5E63C78A3130712 /* art_msw_flat.cpp in Sources */,
056CA84179433AA48D55DA66 /* bar.cpp in Sources */,
CB078622E90F33BE9D131133 /* buttonbar.cpp in Sources */,
EB52C6A915943813932944FE /* control.cpp in Sources */,
diff --git a/build/osx/wxiphone.xcodeproj/project.pbxproj b/build/osx/wxiphone.xcodeproj/project.pbxproj
index 32787c97a3..d0ee1975c0 100644
--- a/build/osx/wxiphone.xcodeproj/project.pbxproj
+++ b/build/osx/wxiphone.xcodeproj/project.pbxproj
@@ -729,6 +729,7 @@
7F77E347E1243D77A666FB43 /* clipbrd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12453E271F2A3AC9969E62A4 /* clipbrd.cpp */; };
159E4248CB1333AD841D9F03 /* LexYAML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 9CC7C6FFD67233788EEDFC5E /* LexYAML.cxx */; };
A0BA01A85C303C78A3130711 /* art_aui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5E8709C3BC3727BBC7B97A /* art_aui.cpp */; };
+ F1A2B3C4D5E63C78A3130714 /* art_msw_flat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F1A2B3C4D5E63727BBC7B97A /* art_msw_flat.cpp */; };
0BB3BF0909A134BA93CF5620 /* xh_richtext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 88C2B895570936A3B4FAF3CF /* xh_richtext.cpp */; };
FBA19C939E1E33EDB05043FE /* cairo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DBE56B153AA3AC8A4BBE77C /* cairo.cpp */; };
8E674574343A3C009B1BCD00 /* tif_codec.c in Sources */ = {isa = PBXBuildFile; fileRef = 88FF67EB6E7D302A9CDEF660 /* tif_codec.c */; };
@@ -1448,6 +1449,7 @@
3720038D64CF3C0B8F642A90 /* tokenzr.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = tokenzr.cpp; path = ../../src/common/tokenzr.cpp; sourceTree = SOURCE_ROOT; };
5EB5FAE81851390D80798E73 /* rescaler_mips32.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = rescaler_mips32.c; path = ../../3rdparty/libwebp/src/dsp/rescaler_mips32.c; sourceTree = SOURCE_ROOT; };
DD5E8709C3BC3727BBC7B97A /* art_aui.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = art_aui.cpp; path = ../../src/ribbon/art_aui.cpp; sourceTree = SOURCE_ROOT; };
+ F1A2B3C4D5E63727BBC7B97A /* art_msw_flat.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = art_msw_flat.cpp; path = ../../src/ribbon/art_msw_flat.cpp; sourceTree = SOURCE_ROOT; };
4BA14FFC0F4B3AE0B4D6B185 /* jquant1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jquant1.c; path = ../../src/jpeg/jquant1.c; sourceTree = SOURCE_ROOT; };
8EB76F786D7F3FF286948D22 /* jcomapi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jcomapi.c; path = ../../src/jpeg/jcomapi.c; sourceTree = SOURCE_ROOT; };
082CA018FB883999839C1DCE /* m_tables.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = m_tables.cpp; path = ../../src/html/m_tables.cpp; sourceTree = SOURCE_ROOT; };
@@ -2636,6 +2638,7 @@
4C4649974D8B3A109D1BF145 /* art_internal.cpp */,
B540E18F9C91381CA175BABB /* art_msw.cpp */,
DD5E8709C3BC3727BBC7B97A /* art_aui.cpp */,
+ F1A2B3C4D5E63727BBC7B97A /* art_msw_flat.cpp */,
9FDDE855D9F83E4891362EB4 /* bar.cpp */,
5612DBC4125B379DA2B28824 /* buttonbar.cpp */,
12363D1F50FE301DAEE7F04B /* control.cpp */,
@@ -4072,6 +4075,7 @@
DE43350F6C9D3148A64F0AF9 /* art_internal.cpp in Sources */,
7DC4A542372437ECA0790F87 /* art_msw.cpp in Sources */,
A0BA01A85C303C78A3130711 /* art_aui.cpp in Sources */,
+ F1A2B3C4D5E63C78A3130714 /* art_msw_flat.cpp in Sources */,
056CA84179433AA48D55DA65 /* bar.cpp in Sources */,
CB078622E90F33BE9D131131 /* buttonbar.cpp in Sources */,
EB52C6A915943813932944FF /* control.cpp in Sources */,
diff --git a/include/wx/ribbon/art.h b/include/wx/ribbon/art.h
index 305c543fe6..034a48e36c 100644
--- a/include/wx/ribbon/art.h
+++ b/include/wx/ribbon/art.h
@@ -790,6 +790,108 @@ protected:
int m_help_button_offset;
};
+class WXDLLIMPEXP_RIBBON wxRibbonMSWFlatArtProvider : public wxRibbonMSWArtProvider
+{
+public:
+ wxRibbonMSWFlatArtProvider();
+ virtual ~wxRibbonMSWFlatArtProvider();
+
+ wxNODISCARD wxRibbonArtProvider* Clone() const override;
+
+ void DrawTab(wxDC& dc,
+ wxWindow* wnd,
+ const wxRibbonPageTabInfo& tab) override;
+
+ void DrawTabSeparator(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect,
+ double visibility) override;
+
+ void DrawPageBackground(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect) override;
+
+ void DrawScrollButton(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect,
+ long style) override;
+
+ void DrawPanelBackground(
+ wxDC& dc,
+ wxRibbonPanel* wnd,
+ const wxRect& rect) override;
+
+ void DrawGalleryBackground(
+ wxDC& dc,
+ wxRibbonGallery* wnd,
+ const wxRect& rect) override;
+
+ void DrawGalleryItemBackground(
+ wxDC& dc,
+ wxRibbonGallery* wnd,
+ const wxRect& rect,
+ wxRibbonGalleryItem* item) override;
+
+ void DrawMinimisedPanel(
+ wxDC& dc,
+ wxRibbonPanel* wnd,
+ const wxRect& rect,
+ wxBitmap& bitmap) override;
+
+ void DrawButtonBarBackground(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect) override;
+
+ void DrawButtonBarButton(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect,
+ wxRibbonButtonKind kind,
+ long state,
+ const wxString& label,
+ const wxBitmap& bitmap_large,
+ const wxBitmap& bitmap_small) override;
+
+ void DrawToolBarBackground(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect) override;
+
+ void DrawTool(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect,
+ const wxBitmap& bitmap,
+ wxRibbonButtonKind kind,
+ long state) override;
+
+ void DrawToggleButton(
+ wxDC& dc,
+ wxRibbonBar* wnd,
+ const wxRect& rect,
+ wxRibbonDisplayMode mode) override;
+
+ void DrawHelpButton(wxDC& dc,
+ wxRibbonBar* wnd,
+ const wxRect& rect) override;
+
+protected:
+ void DrawPartialPageBackground(wxDC& dc, wxWindow* wnd, const wxRect& r,
+ wxRibbonPage* page, wxPoint offset, bool hovered = false);
+ void DrawPartialPageBackground(wxDC& dc, wxWindow* wnd,
+ const wxRect& rect, bool allow_hovered = true);
+ void DrawGalleryButton(wxDC& dc, wxRect rect,
+ wxRibbonGalleryButtonState state, wxBitmap* bitmaps) override;
+ void DrawPanelBorder(wxDC& dc, const wxRect& rect, wxPen& primary_colour,
+ wxPen& secondary_colour);
+ void ReallyDrawTabSeparator(wxWindow* wnd, const wxRect& rect,
+ double visibility);
+};
+
class WXDLLIMPEXP_RIBBON wxRibbonAUIArtProvider : public wxRibbonMSWArtProvider
{
public:
diff --git a/interface/wx/ribbon/art.h b/interface/wx/ribbon/art.h
index e3e8324fb8..d99dbb6ea0 100644
--- a/interface/wx/ribbon/art.h
+++ b/interface/wx/ribbon/art.h
@@ -1071,6 +1071,19 @@ public:
+/**
+ @class wxRibbonMSWArtProvider
+
+ An art provider which draws a ribbon using gradients to mimic the
+ appearance of Microsoft Office 2007 and the Windows Vista / Aero
+ visual style. Tabs, panels, button bars, and toolbars all use
+ gradient fills to create a glossy, three-dimensional look.
+
+ @library{wxribbon}
+ @category{ribbon}
+
+ @see wxRibbonMSWFlatArtProvider, wxRibbonAUIArtProvider
+*/
class wxRibbonMSWArtProvider : public wxRibbonArtProvider
{
public:
@@ -1078,6 +1091,40 @@ public:
};
+/**
+ @class wxRibbonMSWFlatArtProvider
+
+ A flat variant of wxRibbonMSWArtProvider that uses solid colour fills
+ instead of gradients, providing a modern appearance consistent with
+ the Windows Metro / Fluent design language.
+
+ @since 3.3.3
+
+ @library{wxribbon}
+ @category{ribbon}
+
+ @see wxRibbonMSWArtProvider, wxRibbonAUIArtProvider
+*/
+class wxRibbonMSWFlatArtProvider : public wxRibbonMSWArtProvider
+{
+public:
+ wxRibbonMSWFlatArtProvider();
+};
+
+
+/**
+ @class wxRibbonAUIArtProvider
+
+ An art provider styled after the wxAUI docking framework. Like
+ wxRibbonMSWArtProvider it uses gradient fills, but differs in its
+ layout of panel labels (placed at the top rather than the bottom)
+ and general styling.
+
+ @library{wxribbon}
+ @category{ribbon}
+
+ @see wxRibbonMSWArtProvider, wxRibbonMSWFlatArtProvider
+*/
class wxRibbonAUIArtProvider : public wxRibbonMSWArtProvider
{
public:
diff --git a/samples/ribbon/ribbondemo.cpp b/samples/ribbon/ribbondemo.cpp
index 0cb1886951..3c685aa7f1 100644
--- a/samples/ribbon/ribbondemo.cpp
+++ b/samples/ribbon/ribbondemo.cpp
@@ -63,6 +63,7 @@ public:
ID_DEFAULT_PROVIDER,
ID_AUI_PROVIDER,
ID_MSW_PROVIDER,
+ ID_MSW_FLAT_PROVIDER,
ID_MAIN_TOOLBAR,
ID_POSITION_TOP,
ID_POSITION_TOP_ICONS,
@@ -119,6 +120,7 @@ public:
void OnDefaultProvider(wxRibbonButtonBarEvent& evt);
void OnAUIProvider(wxRibbonButtonBarEvent& evt);
void OnMSWProvider(wxRibbonButtonBarEvent& evt);
+ void OnMSWFlatProvider(wxRibbonButtonBarEvent& evt);
void OnJustify(wxRibbonToolBarEvent& evt);
void OnJustifyUpdateUI(wxUpdateUIEvent& evt);
void OnNew(wxRibbonToolBarEvent& evt);
@@ -210,6 +212,7 @@ EVT_UPDATE_UI(ID_UI_CHANGE_TEXT_UPDATED, MyFrame::OnChangeTextUpdateUI)
EVT_RIBBONBUTTONBAR_CLICKED(ID_DEFAULT_PROVIDER, MyFrame::OnDefaultProvider)
EVT_RIBBONBUTTONBAR_CLICKED(ID_AUI_PROVIDER, MyFrame::OnAUIProvider)
EVT_RIBBONBUTTONBAR_CLICKED(ID_MSW_PROVIDER, MyFrame::OnMSWProvider)
+EVT_RIBBONBUTTONBAR_CLICKED(ID_MSW_FLAT_PROVIDER, MyFrame::OnMSWFlatProvider)
EVT_RIBBONBUTTONBAR_CLICKED(ID_SELECTION_EXPAND_H, MyFrame::OnSelectionExpandHButton)
EVT_RIBBONBUTTONBAR_CLICKED(ID_SELECTION_EXPAND_V, MyFrame::OnSelectionExpandVButton)
EVT_RIBBONBUTTONBAR_CLICKED(ID_SELECTION_CONTRACT, MyFrame::OnSelectionContractButton)
@@ -406,6 +409,7 @@ MyFrame::MyFrame()
wxArtProvider::GetBitmap(wxART_QUESTION, wxART_OTHER, wxSize(32, 32)));
provider_bar->AddButton(ID_AUI_PROVIDER, "AUI Provider", aui_style_xpm);
provider_bar->AddButton(ID_MSW_PROVIDER, "MSW Provider", msw_style_xpm);
+ provider_bar->AddButton(ID_MSW_FLAT_PROVIDER, "MSW Flat Provider", msw_style_xpm);
wxRibbonPanel *primary_panel = new wxRibbonPanel(scheme, wxID_ANY,
"Primary Colour", colours_xpm);
m_primary_gallery = PopulateColoursPanel(primary_panel,
@@ -1075,6 +1079,12 @@ void MyFrame::OnMSWProvider(wxRibbonButtonBarEvent& WXUNUSED(evt))
SetArtProvider(new wxRibbonMSWArtProvider);
}
+void MyFrame::OnMSWFlatProvider(wxRibbonButtonBarEvent& WXUNUSED(evt))
+{
+ m_ribbon->DismissExpandedPanel();
+ SetArtProvider(new wxRibbonMSWFlatArtProvider);
+}
+
void MyFrame::SetArtProvider(wxRibbonArtProvider *prov)
{
m_ribbon->Freeze();
diff --git a/src/ribbon/art_aui.cpp b/src/ribbon/art_aui.cpp
index e7102023db..0fdd724f8b 100644
--- a/src/ribbon/art_aui.cpp
+++ b/src/ribbon/art_aui.cpp
@@ -501,8 +501,10 @@ void wxRibbonAUIArtProvider::DrawTab(wxDC& dc,
dc.DrawBitmap(icon, x - offset, tab.rect.y + (tab.rect.height -
icon.GetLogicalHeight()) / 2, true);
}
- dc.SetClippingRegion(x, tab.rect.y, width, tab.rect.height);
- dc.DrawText(label, x, y);
+ {
+ wxDCClipper clip(dc, x, tab.rect.y, width, tab.rect.height);
+ dc.DrawText(label, x, y);
+ }
}
}
diff --git a/src/ribbon/art_msw.cpp b/src/ribbon/art_msw.cpp
index 748c45a28c..00c4a4e91d 100644
--- a/src/ribbon/art_msw.cpp
+++ b/src/ribbon/art_msw.cpp
@@ -1449,6 +1449,9 @@ void wxRibbonMSWArtProvider::DrawTab(
}
}
+ if ( tab.page == nullptr )
+ return;
+
if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
{
wxBitmap icon = tab.page->GetIcon();
@@ -1502,7 +1505,7 @@ void wxRibbonMSWArtProvider::DrawTab(
if(width <= text_width)
{
- dc.SetClippingRegion(x, tab.rect.y, width, tab.rect.height);
+ wxDCClipper clip(dc, x, tab.rect.y, width, tab.rect.height);
dc.DrawText(label, x, y);
}
else
@@ -1948,7 +1951,7 @@ void wxRibbonMSWArtProvider::DrawPanelBackground(
{
// Room for some characters and ...
// Display as many characters as possible and append ...
- for(size_t len = label.Len() - 1; len >= 3; --len)
+ for( int len = wxSsize(label) - 1; len >= 3; --len )
{
new_label = label.Mid(0, len) + "...";
label_size = dc.GetTextExtent(new_label);
diff --git a/src/ribbon/art_msw_flat.cpp b/src/ribbon/art_msw_flat.cpp
new file mode 100644
index 0000000000..ee19b4a701
--- /dev/null
+++ b/src/ribbon/art_msw_flat.cpp
@@ -0,0 +1,1178 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: src/ribbon/art_msw_flat.cpp
+// Purpose: Flat MSW style art provider for ribbon interface
+// Author: wxWidgets team
+// Created: 2026-02-27
+// Copyright: (c) wxWidgets team
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#include "wx/wxprec.h"
+
+
+#if wxUSE_RIBBON
+
+#include "wx/ribbon/art.h"
+#include "wx/ribbon/art_internal.h"
+#include "wx/ribbon/bar.h"
+#include "wx/ribbon/buttonbar.h"
+#include "wx/ribbon/gallery.h"
+#include "wx/ribbon/toolbar.h"
+
+#ifndef WX_PRECOMP
+#include "wx/dcmemory.h"
+#endif
+
+#ifdef __WXMSW__
+#include "wx/msw/private.h"
+#endif
+
+wxRibbonMSWFlatArtProvider::wxRibbonMSWFlatArtProvider()
+ : wxRibbonMSWArtProvider()
+{
+}
+
+wxRibbonMSWFlatArtProvider::~wxRibbonMSWFlatArtProvider()
+{
+}
+
+wxRibbonArtProvider* wxRibbonMSWFlatArtProvider::Clone() const
+{
+ wxRibbonMSWFlatArtProvider *copy = new wxRibbonMSWFlatArtProvider;
+ CloneTo(copy);
+ return copy;
+}
+
+void wxRibbonMSWFlatArtProvider::DrawTab(
+ wxDC& dc,
+ wxWindow* WXUNUSED(wnd),
+ const wxRibbonPageTabInfo& tab)
+{
+ if ( tab.rect.height <= 2 )
+ return;
+
+ if ( tab.active || tab.hovered || tab.highlight )
+ {
+ if ( tab.active )
+ {
+ wxRect background(tab.rect);
+
+ background.x += 2;
+ background.y += 2;
+ background.width -= 4;
+ background.height -= 2;
+
+ if ( background.width > 0 && background.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(m_tab_active_background_colour));
+ dc.DrawRectangle(background.x, background.y,
+ background.width, background.height);
+ }
+ }
+ else if ( tab.hovered )
+ {
+ wxRect background(tab.rect);
+
+ background.x += 2;
+ background.y += 2;
+ background.width -= 4;
+ background.height -= 3;
+
+ if ( background.width > 0 && background.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(m_tab_hover_background_colour));
+ dc.DrawRectangle(background.x, background.y,
+ background.width, background.height);
+ }
+ }
+ else if ( tab.highlight )
+ {
+ wxRect background(tab.rect);
+
+ background.x += 2;
+ background.y += 2;
+ background.width -= 4;
+ background.height -= 3;
+
+ if ( background.width > 0 && background.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(m_tab_highlight_colour));
+ dc.DrawRectangle(background.x, background.y,
+ background.width, background.height);
+ }
+ }
+
+ wxPoint border_points[6];
+ border_points[0] = wxPoint(1, tab.rect.height - 2);
+ border_points[1] = wxPoint(1, 3);
+ border_points[2] = wxPoint(3, 1);
+ border_points[3] = wxPoint(tab.rect.width - 4, 1);
+ border_points[4] = wxPoint(tab.rect.width - 2, 3);
+ border_points[5] = wxPoint(tab.rect.width - 2, tab.rect.height - 1);
+
+ dc.SetPen(m_tab_border_pen);
+ dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points,
+ tab.rect.x, tab.rect.y);
+
+ if ( tab.active )
+ {
+ // Give the tab a curved outward border at the bottom
+ dc.DrawPoint(tab.rect.x, tab.rect.y + tab.rect.height - 2);
+ dc.DrawPoint(tab.rect.x + tab.rect.width - 1,
+ tab.rect.y + tab.rect.height - 2);
+
+ dc.SetPen(wxPen(m_tab_active_background_colour));
+
+ dc.DrawPoint(tab.rect.x + 1, tab.rect.y + tab.rect.height - 2);
+ dc.DrawPoint(tab.rect.x + tab.rect.width - 2,
+ tab.rect.y + tab.rect.height - 2);
+ dc.DrawPoint(tab.rect.x + 1, tab.rect.y + tab.rect.height - 1);
+ dc.DrawPoint(tab.rect.x, tab.rect.y + tab.rect.height - 1);
+ dc.DrawPoint(tab.rect.x + tab.rect.width - 2,
+ tab.rect.y + tab.rect.height - 1);
+ dc.DrawPoint(tab.rect.x + tab.rect.width - 1,
+ tab.rect.y + tab.rect.height - 1);
+ }
+ }
+
+ if ( tab.page == nullptr )
+ return;
+
+ if ( m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS )
+ {
+ wxBitmap icon = tab.page->GetIcon();
+ if ( icon.IsOk() )
+ {
+ int x = tab.rect.x + 4;
+ if ( (m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS) == 0 )
+ x = tab.rect.x + (tab.rect.width - icon.GetLogicalWidth()) / 2;
+ dc.DrawBitmap(icon, x, tab.rect.y + 1 + (tab.rect.height - 1 -
+ icon.GetLogicalHeight()) / 2, true);
+ }
+ }
+ if ( m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS )
+ {
+ wxString label = tab.page->GetLabel();
+ if ( !label.empty() )
+ {
+ dc.SetFont(m_tab_label_font);
+
+ if ( tab.active )
+ {
+ dc.SetTextForeground(m_tab_active_label_colour);
+ }
+ else if ( tab.hovered )
+ {
+ dc.SetTextForeground(m_tab_hover_label_colour);
+ }
+ else
+ {
+ dc.SetTextForeground(m_tab_label_colour);
+ }
+
+ dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
+
+ int text_height;
+ int text_width;
+ dc.GetTextExtent(label, &text_width, &text_height);
+ int width = tab.rect.width - 5;
+ int x = tab.rect.x + 3;
+ if ( m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS )
+ {
+ const wxBitmap& icon = tab.page->GetIcon();
+ if ( icon.IsOk() )
+ {
+ const int iconWidth = icon.GetLogicalWidth();
+ x += 3 + iconWidth;
+ width -= 3 + iconWidth;
+ }
+ }
+ int y = tab.rect.y + (tab.rect.height - text_height) / 2;
+
+ if ( width <= text_width )
+ {
+ wxDCClipper clip(dc, x, tab.rect.y, width, tab.rect.height);
+ dc.DrawText(label, x, y);
+ }
+ else
+ {
+ dc.DrawText(label, x + (width - text_width) / 2 + 1, y);
+ }
+ }
+ }
+}
+
+void wxRibbonMSWFlatArtProvider::ReallyDrawTabSeparator(wxWindow* wnd,
+ const wxRect& rect, double visibility)
+{
+ if ( !m_cached_tab_separator.IsOk()
+ || m_cached_tab_separator.GetLogicalSize() != rect.GetSize() )
+ {
+ m_cached_tab_separator = wxBitmap(rect.GetSize());
+ }
+
+ wxMemoryDC dc(m_cached_tab_separator);
+ DrawTabCtrlBackground(dc, wnd, rect);
+
+ wxCoord x = rect.x + rect.width / 2;
+
+ unsigned char r = (unsigned char)(m_tab_separator_colour.Red() * visibility
+ + m_tab_ctrl_background_brush.GetColour().Red() * (1.0 - visibility)
+ + 0.5);
+ unsigned char g = (unsigned char)(m_tab_separator_colour.Green() * visibility
+ + m_tab_ctrl_background_brush.GetColour().Green() * (1.0 - visibility)
+ + 0.5);
+ unsigned char b = (unsigned char)(m_tab_separator_colour.Blue() * visibility
+ + m_tab_ctrl_background_brush.GetColour().Blue() * (1.0 - visibility)
+ + 0.5);
+
+ dc.SetPen(wxPen(wxColour(r, g, b)));
+ dc.DrawLine(x, rect.y, x, rect.y + rect.height - 1);
+
+ m_cached_tab_separator_visibility = visibility;
+}
+
+void wxRibbonMSWFlatArtProvider::DrawPartialPageBackground(wxDC& dc,
+ wxWindow* wnd, const wxRect& r, wxRibbonPage* page,
+ wxPoint offset, bool hovered)
+{
+ wxRect background;
+
+ if ( wnd->GetSizer() && wnd->GetParent() != page )
+ {
+ background = wnd->GetParent()->GetSize();
+ offset = wxPoint(0, 0);
+ }
+ else
+ {
+ background = page->GetSize();
+ page->AdjustRectToIncludeScrollButtons(&background);
+ background.height -= 2;
+ }
+ wxRect paint_rect(r);
+ paint_rect.x += offset.x;
+ paint_rect.y += offset.y;
+
+ // Clamp vertically to the background but allow full width, as expanded
+ // panels can be wider than the page.
+ wxRect rect(paint_rect);
+ if ( rect.y < background.y )
+ {
+ rect.height -= (background.y - rect.y);
+ rect.y = background.y;
+ }
+ if ( rect.GetBottom() > background.GetBottom() )
+ rect.SetBottom(background.GetBottom());
+ rect.x -= offset.x;
+ rect.y -= offset.y;
+
+ if ( rect.width > 0 && rect.height > 0 )
+ {
+ wxColour bg_colour;
+ if ( hovered )
+ bg_colour = m_page_hover_background_colour;
+ else
+ bg_colour = m_page_background_colour;
+
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(bg_colour));
+ dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
+ }
+}
+
+void wxRibbonMSWFlatArtProvider::DrawPageBackground(
+ wxDC& dc,
+ wxWindow* WXUNUSED(wnd),
+ const wxRect& rect)
+{
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(m_tab_ctrl_background_brush);
+
+ {
+ wxRect edge(rect);
+
+ edge.width = 2;
+ dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
+
+ edge.x += rect.width - 2;
+ dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
+
+ edge = rect;
+ edge.height = 2;
+ edge.y += (rect.height - edge.height);
+ dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
+ }
+
+ {
+ wxRect background(rect);
+ background.x += 2;
+ background.width -= 4;
+ background.height -= 2;
+
+ if ( background.width > 0 && background.height > 0 )
+ {
+ dc.SetBrush(wxBrush(m_page_background_colour));
+ dc.DrawRectangle(background.x, background.y,
+ background.width, background.height);
+ }
+ }
+
+ {
+ wxPoint border_points[8];
+ border_points[0] = wxPoint(2, 0);
+ border_points[1] = wxPoint(1, 1);
+ border_points[2] = wxPoint(1, rect.height - 4);
+ border_points[3] = wxPoint(3, rect.height - 2);
+ border_points[4] = wxPoint(rect.width - 4, rect.height - 2);
+ border_points[5] = wxPoint(rect.width - 2, rect.height - 4);
+ border_points[6] = wxPoint(rect.width - 2, 1);
+ border_points[7] = wxPoint(rect.width - 4, -1);
+
+ dc.SetPen(m_page_border_pen);
+ dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points,
+ rect.x, rect.y);
+ }
+}
+
+void wxRibbonMSWFlatArtProvider::DrawScrollButton(
+ wxDC& dc,
+ wxWindow* WXUNUSED(wnd),
+ const wxRect& rect_,
+ long style)
+{
+ wxRect rect(rect_);
+
+ if ( (style & wxRIBBON_SCROLL_BTN_FOR_MASK) == wxRIBBON_SCROLL_BTN_FOR_PAGE )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(m_tab_ctrl_background_brush);
+ dc.DrawRectangle(rect);
+ dc.SetClippingRegion(rect);
+ switch ( style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK )
+ {
+ case wxRIBBON_SCROLL_BTN_LEFT:
+ rect.x++;
+ wxFALLTHROUGH;
+ case wxRIBBON_SCROLL_BTN_RIGHT:
+ rect.y--;
+ rect.width--;
+ break;
+ case wxRIBBON_SCROLL_BTN_UP:
+ rect.x++;
+ rect.y--;
+ rect.width -= 2;
+ rect.height++;
+ break;
+ case wxRIBBON_SCROLL_BTN_DOWN:
+ rect.x++;
+ rect.width -= 2;
+ rect.height--;
+ break;
+ }
+ }
+
+ {
+ wxRect background(rect);
+ background.x++;
+ background.y++;
+ background.width -= 2;
+ background.height -= 2;
+
+ if ( background.width > 0 && background.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(m_page_background_colour));
+ dc.DrawRectangle(background.x, background.y,
+ background.width, background.height);
+ }
+ }
+
+ {
+ wxPoint border_points[7];
+ switch ( style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK )
+ {
+ case wxRIBBON_SCROLL_BTN_LEFT:
+ border_points[0] = wxPoint(2, 0);
+ border_points[1] = wxPoint(rect.width - 1, 0);
+ border_points[2] = wxPoint(rect.width - 1, rect.height - 1);
+ border_points[3] = wxPoint(2, rect.height - 1);
+ border_points[4] = wxPoint(0, rect.height - 3);
+ border_points[5] = wxPoint(0, 2);
+ break;
+ case wxRIBBON_SCROLL_BTN_RIGHT:
+ border_points[0] = wxPoint(0, 0);
+ border_points[1] = wxPoint(rect.width - 3, 0);
+ border_points[2] = wxPoint(rect.width - 1, 2);
+ border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
+ border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
+ border_points[5] = wxPoint(0, rect.height - 1);
+ break;
+ case wxRIBBON_SCROLL_BTN_UP:
+ border_points[0] = wxPoint(2, 0);
+ border_points[1] = wxPoint(rect.width - 3, 0);
+ border_points[2] = wxPoint(rect.width - 1, 2);
+ border_points[3] = wxPoint(rect.width - 1, rect.height - 1);
+ border_points[4] = wxPoint(0, rect.height - 1);
+ border_points[5] = wxPoint(0, 2);
+ break;
+ case wxRIBBON_SCROLL_BTN_DOWN:
+ border_points[0] = wxPoint(0, 0);
+ border_points[1] = wxPoint(rect.width - 1, 0);
+ border_points[2] = wxPoint(rect.width - 1, rect.height - 3);
+ border_points[3] = wxPoint(rect.width - 3, rect.height - 1);
+ border_points[4] = wxPoint(2, rect.height - 1);
+ border_points[5] = wxPoint(0, rect.height - 3);
+ break;
+ }
+ border_points[6] = border_points[0];
+
+ dc.SetPen(m_page_border_pen);
+ dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points,
+ rect.x, rect.y);
+ }
+
+ {
+ // NB: Code for handling hovered/active state is temporary
+ wxPoint arrow_points[3];
+ switch ( style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK )
+ {
+ case wxRIBBON_SCROLL_BTN_LEFT:
+ arrow_points[0] = wxPoint(rect.width / 2 - 2, rect.height / 2);
+ if ( style & wxRIBBON_SCROLL_BTN_ACTIVE )
+ arrow_points[0].y += 1;
+ arrow_points[1] = arrow_points[0] + wxPoint(3, -3);
+ arrow_points[2] = arrow_points[0] + wxPoint(3, 3);
+ break;
+ case wxRIBBON_SCROLL_BTN_RIGHT:
+ arrow_points[0] = wxPoint(rect.width / 2 + 2, rect.height / 2);
+ if ( style & wxRIBBON_SCROLL_BTN_ACTIVE )
+ arrow_points[0].y += 1;
+ arrow_points[1] = arrow_points[0] - wxPoint(3, 3);
+ arrow_points[2] = arrow_points[0] - wxPoint(3, -3);
+ break;
+ case wxRIBBON_SCROLL_BTN_UP:
+ arrow_points[0] = wxPoint(rect.width / 2, rect.height / 2 - 2);
+ if ( style & wxRIBBON_SCROLL_BTN_ACTIVE )
+ arrow_points[0].y += 1;
+ arrow_points[1] = arrow_points[0] + wxPoint( 3, 3);
+ arrow_points[2] = arrow_points[0] + wxPoint(-3, 3);
+ break;
+ case wxRIBBON_SCROLL_BTN_DOWN:
+ arrow_points[0] = wxPoint(rect.width / 2, rect.height / 2 + 2);
+ if ( style & wxRIBBON_SCROLL_BTN_ACTIVE )
+ arrow_points[0].y += 1;
+ arrow_points[1] = arrow_points[0] - wxPoint( 3, 3);
+ arrow_points[2] = arrow_points[0] - wxPoint(-3, 3);
+ break;
+ }
+
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ wxBrush brush(style & wxRIBBON_SCROLL_BTN_HOVERED
+ ? m_tab_active_background_colour : m_tab_label_colour);
+ dc.SetBrush(brush);
+ dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points,
+ rect.x, rect.y);
+ }
+}
+
+void wxRibbonMSWFlatArtProvider::DrawGalleryButton(wxDC& dc,
+ wxRect rect,
+ wxRibbonGalleryButtonState state,
+ wxBitmap* bitmaps)
+{
+ wxBitmap btn_bitmap;
+ wxColour btn_colour;
+ switch ( state )
+ {
+ case wxRIBBON_GALLERY_BUTTON_NORMAL:
+ btn_colour = m_gallery_button_background_colour;
+ btn_bitmap = bitmaps[0];
+ break;
+ case wxRIBBON_GALLERY_BUTTON_HOVERED:
+ btn_colour = m_gallery_button_hover_background_colour;
+ btn_bitmap = bitmaps[1];
+ break;
+ case wxRIBBON_GALLERY_BUTTON_ACTIVE:
+ btn_colour = m_gallery_button_active_background_colour;
+ btn_bitmap = bitmaps[2];
+ break;
+ case wxRIBBON_GALLERY_BUTTON_DISABLED:
+ btn_colour = m_gallery_button_disabled_background_colour;
+ btn_bitmap = bitmaps[3];
+ break;
+ }
+
+ rect.x++;
+ rect.y++;
+ if ( m_flags & wxRIBBON_BAR_FLOW_VERTICAL )
+ {
+ rect.width--;
+ rect.height -= 2;
+ }
+ else
+ {
+ rect.width -= 2;
+ rect.height--;
+ }
+
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(btn_colour));
+ dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
+
+ dc.DrawBitmap(btn_bitmap, rect.x + rect.width / 2 - 2,
+ rect.y + (rect.height / 2) - 2, true);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawGalleryItemBackground(
+ wxDC& dc,
+ wxRibbonGallery* wnd,
+ const wxRect& rect,
+ wxRibbonGalleryItem* item)
+{
+ if ( wnd->GetHoveredItem() != item && wnd->GetActiveItem() != item &&
+ wnd->GetSelection() != item )
+ return;
+
+ dc.SetPen(m_gallery_item_border_pen);
+ dc.DrawLine(rect.x + 1, rect.y, rect.x + rect.width - 1, rect.y);
+ dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
+ dc.DrawLine(rect.x + 1, rect.y + rect.height - 1, rect.x + rect.width - 1,
+ rect.y + rect.height - 1);
+ dc.DrawLine(rect.x + rect.width - 1, rect.y + 1, rect.x + rect.width - 1,
+ rect.y + rect.height - 1);
+
+ wxColour bg_colour;
+
+ if ( wnd->GetActiveItem() == item || wnd->GetSelection() == item )
+ bg_colour = m_gallery_button_active_background_colour;
+ else
+ bg_colour = m_gallery_button_hover_background_colour;
+
+ wxRect inner(rect);
+ inner.x += 1;
+ inner.width -= 2;
+ inner.y += 1;
+ inner.height -= 2;
+ if ( inner.width > 0 && inner.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(bg_colour));
+ dc.DrawRectangle(inner.x, inner.y, inner.width, inner.height);
+ }
+}
+
+void wxRibbonMSWFlatArtProvider::DrawPanelBorder(wxDC& dc, const wxRect& rect,
+ wxPen& primary_colour,
+ wxPen& secondary_colour)
+{
+ wxUnusedVar(secondary_colour);
+
+ const wxPoint border_points[] = {
+ {2, 0},
+ {rect.width - 3, 0},
+ {rect.width - 1, 2},
+ {rect.width - 1, rect.height - 3},
+ {rect.width - 3, rect.height - 1},
+ {2, rect.height - 1},
+ {0, rect.height - 3},
+ {0, 2},
+ {2, 0},
+ };
+
+ dc.SetPen(primary_colour);
+ dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points,
+ rect.x, rect.y);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawMinimisedPanel(
+ wxDC& dc,
+ wxRibbonPanel* wnd,
+ const wxRect& rect,
+ wxBitmap& bitmap)
+{
+ DrawPartialPageBackground(dc, wnd, rect, false);
+
+ wxRect true_rect(rect);
+ RemovePanelPadding(&true_rect);
+
+ if ( wnd->GetExpandedPanel() != nullptr )
+ {
+ wxRect client_rect(true_rect);
+ client_rect.x++;
+ client_rect.width -= 2;
+ client_rect.y++;
+ client_rect.height = (true_rect.y + true_rect.height) - client_rect.y;
+
+ if ( client_rect.width > 0 && client_rect.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(m_panel_active_background_colour));
+ dc.DrawRectangle(client_rect.x, client_rect.y,
+ client_rect.width, client_rect.height);
+ }
+ }
+ else if ( wnd->IsHovered() )
+ {
+ wxRect client_rect(true_rect);
+ client_rect.x++;
+ client_rect.width -= 2;
+ client_rect.y++;
+ client_rect.height -= 2;
+ if ( client_rect.width > 0 && client_rect.height > 0 )
+ DrawPartialPageBackground(dc, wnd, client_rect, true);
+ }
+
+ wxRect preview;
+ DrawMinimisedPanelCommon(dc, wnd, true_rect, &preview);
+
+ dc.SetBrush(m_panel_hover_label_background_brush);
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.DrawRectangle(preview.x + 1, preview.y + preview.height - 8,
+ preview.width - 2, 7);
+
+ {
+ wxRect full_rect(preview);
+ full_rect.x += 1;
+ full_rect.y += 1;
+ full_rect.width -= 2;
+ full_rect.height -= 9;
+
+ if ( full_rect.width > 0 && full_rect.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(m_page_hover_background_colour));
+ dc.DrawRectangle(full_rect.x, full_rect.y,
+ full_rect.width, full_rect.height);
+ }
+ }
+
+ if ( bitmap.IsOk() )
+ {
+ dc.DrawBitmap(bitmap, preview.x + (preview.width -
+ bitmap.GetLogicalWidth()) / 2,
+ preview.y + (preview.height - 7 -
+ bitmap.GetLogicalHeight()) / 2, true);
+ }
+
+ if ( !wnd->IsHovered() )
+ DrawPanelBorder(dc, preview, m_panel_border_pen,
+ m_panel_border_gradient_pen);
+ else
+ DrawPanelBorder(dc, preview, m_panel_hover_border_pen,
+ m_panel_hover_border_gradient_pen);
+
+ DrawPanelBorder(dc, true_rect, m_panel_minimised_border_pen,
+ m_panel_minimised_border_gradient_pen);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawButtonBarButton(
+ wxDC& dc,
+ wxWindow* WXUNUSED(wnd),
+ const wxRect& rect,
+ wxRibbonButtonKind kind,
+ long state,
+ const wxString& label,
+ const wxBitmap& bitmap_large,
+ const wxBitmap& bitmap_small)
+{
+ if ( kind == wxRIBBON_BUTTON_TOGGLE )
+ {
+ kind = wxRIBBON_BUTTON_NORMAL;
+ if ( state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED )
+ state ^= wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
+ }
+
+ if ( state & (wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK |
+ wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK) )
+ {
+ if ( state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK )
+ dc.SetPen(m_button_bar_active_border_pen);
+ else
+ dc.SetPen(m_button_bar_hover_border_pen);
+
+ wxRect bg_rect(rect);
+ bg_rect.x++;
+ bg_rect.y++;
+ bg_rect.width -= 2;
+ bg_rect.height -= 2;
+
+ if ( kind == wxRIBBON_BUTTON_HYBRID )
+ {
+ switch ( state & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK )
+ {
+ case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
+ {
+ int iYBorder = rect.y + bitmap_large.GetLogicalHeight() + 4;
+ wxRect partial_bg(rect);
+ if ( state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED )
+ {
+ partial_bg.SetBottom(iYBorder - 1);
+ }
+ else
+ {
+ partial_bg.height -= (iYBorder - partial_bg.y + 1);
+ partial_bg.y = iYBorder + 1;
+ }
+ dc.DrawLine(rect.x, iYBorder, rect.x + rect.width,
+ iYBorder);
+ bg_rect.Intersect(partial_bg);
+ }
+ break;
+ case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
+ {
+ int iArrowWidth = 9;
+ if ( state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED )
+ {
+ bg_rect.width -= iArrowWidth;
+ dc.DrawLine(bg_rect.x + bg_rect.width,
+ rect.y, bg_rect.x + bg_rect.width,
+ rect.y + rect.height);
+ }
+ else
+ {
+ --iArrowWidth;
+ bg_rect.x += bg_rect.width - iArrowWidth;
+ bg_rect.width = iArrowWidth;
+ dc.DrawLine(bg_rect.x - 1, rect.y,
+ bg_rect.x - 1, rect.y + rect.height);
+ }
+ }
+ break;
+ case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
+ break;
+ }
+ }
+
+ wxColour bg_colour;
+ if ( state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK )
+ bg_colour = m_button_bar_active_background_colour;
+ else
+ bg_colour = m_button_bar_hover_background_colour;
+
+ if ( bg_rect.width > 0 && bg_rect.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(bg_colour));
+ dc.DrawRectangle(bg_rect.x, bg_rect.y,
+ bg_rect.width, bg_rect.height);
+ }
+
+ const wxPoint border_points[] = {
+ {2, 0},
+ {rect.width - 3, 0},
+ {rect.width - 1, 2},
+ {rect.width - 1, rect.height - 3},
+ {rect.width - 3, rect.height - 1},
+ {2, rect.height - 1},
+ {0, rect.height - 3},
+ {0, 2},
+ {2, 0},
+ };
+
+ if ( state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK )
+ dc.SetPen(m_button_bar_active_border_pen);
+ else
+ dc.SetPen(m_button_bar_hover_border_pen);
+
+ dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points,
+ rect.x, rect.y);
+ }
+
+ dc.SetFont(m_button_bar_label_font);
+ dc.SetTextForeground(state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED
+ ? m_button_bar_label_disabled_colour
+ : m_button_bar_label_colour);
+ DrawButtonBarButtonForeground(dc, rect, kind, state, label, bitmap_large,
+ bitmap_small);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawTabSeparator(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect,
+ double visibility)
+{
+ if ( visibility <= 0.0 )
+ {
+ return;
+ }
+ if ( visibility > 1.0 )
+ {
+ visibility = 1.0;
+ }
+
+ if ( !m_cached_tab_separator.IsOk() || m_cached_tab_separator.GetLogicalSize() != rect.GetSize() || visibility != m_cached_tab_separator_visibility )
+ {
+ wxRect size(rect.GetSize());
+ ReallyDrawTabSeparator(wnd, size, visibility);
+ }
+ dc.DrawBitmap(m_cached_tab_separator, rect.x, rect.y, false);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawPartialPageBackground(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect,
+ bool allow_hovered)
+{
+ // Assume the window is a child of a ribbon page, and also check for a
+ // hovered panel somewhere between the window and the page, as it causes
+ // the background to change.
+ wxPoint offset(wnd->GetPosition());
+ wxRibbonPage* page = nullptr;
+ wxWindow* parent = wnd->GetParent();
+ wxRibbonPanel* panel = wxDynamicCast(wnd, wxRibbonPanel);
+ bool hovered = false;
+
+ if ( panel != nullptr )
+ {
+ hovered = allow_hovered && panel->IsHovered();
+ if ( panel->GetExpandedDummy() != nullptr )
+ {
+ offset = panel->GetExpandedDummy()->GetPosition();
+ parent = panel->GetExpandedDummy()->GetParent();
+ }
+ }
+ for ( ; parent; parent = parent->GetParent() )
+ {
+ if ( panel == nullptr )
+ {
+ panel = wxDynamicCast(parent, wxRibbonPanel);
+ if ( panel != nullptr )
+ {
+ hovered = allow_hovered && panel->IsHovered();
+ if ( panel->GetExpandedDummy() != nullptr )
+ {
+ parent = panel->GetExpandedDummy();
+ }
+ }
+ }
+ page = wxDynamicCast(parent, wxRibbonPage);
+ if ( page != nullptr )
+ {
+ break;
+ }
+ offset += parent->GetPosition();
+ }
+ if ( page != nullptr )
+ {
+ DrawPartialPageBackground(dc, wnd, rect, page, offset, hovered);
+ return;
+ }
+
+ // No page found - fallback to painting with a stock brush
+ dc.SetBrush(*wxWHITE_BRUSH);
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawPanelBackground(
+ wxDC& dc,
+ wxRibbonPanel* wnd,
+ const wxRect& rect)
+{
+ DrawPartialPageBackground(dc, wnd, rect, false);
+
+ wxRect true_rect(rect);
+ RemovePanelPadding(&true_rect);
+ bool has_ext_button = wnd->HasExtButton();
+
+ int label_height;
+ {
+ dc.SetFont(m_panel_label_font);
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ if ( wnd->IsHovered() )
+ {
+ dc.SetBrush(m_panel_hover_label_background_brush);
+ dc.SetTextForeground(m_panel_hover_label_colour);
+ }
+ else
+ {
+ dc.SetBrush(m_panel_label_background_brush);
+ dc.SetTextForeground(m_panel_label_colour);
+ }
+
+ wxRect label_rect(true_rect);
+ wxString label = wnd->GetLabel();
+ bool clip_label = false;
+ wxSize label_size(dc.GetTextExtent(label));
+
+ label_rect.SetX(label_rect.GetX() + 1);
+ label_rect.SetWidth(label_rect.GetWidth() - 2);
+ label_rect.SetHeight(label_size.GetHeight() + 2);
+ label_rect.SetY(true_rect.GetBottom() - label_rect.GetHeight());
+ label_height = label_rect.GetHeight();
+
+ wxRect label_bg_rect = label_rect;
+
+ if ( has_ext_button )
+ label_rect.SetWidth(label_rect.GetWidth() - 13);
+
+ if ( label_size.GetWidth() > label_rect.GetWidth() )
+ {
+ // Test if there is enough length for 3 letters and ...
+ wxString new_label = label.Mid(0, 3) + "...";
+ label_size = dc.GetTextExtent(new_label);
+ if ( label_size.GetWidth() > label_rect.GetWidth() )
+ {
+ // Not enough room for three characters and ...
+ // Display the entire label and just crop it
+ clip_label = true;
+ }
+ else
+ {
+ // Room for some characters and ...
+ // Display as many characters as possible and append ...
+ for ( int len = static_cast(label.Len()) - 1; len >= 3; --len )
+ {
+ new_label = label.Mid(0, len) + "...";
+ label_size = dc.GetTextExtent(new_label);
+ if ( label_size.GetWidth() <= label_rect.GetWidth() )
+ {
+ label = new_label;
+ break;
+ }
+ }
+ }
+ }
+
+ dc.DrawRectangle(label_bg_rect);
+ if ( clip_label )
+ {
+ wxDCClipper clip(dc, label_rect);
+ dc.DrawText(label, label_rect.x, label_rect.y +
+ (label_rect.GetHeight() - label_size.GetHeight()) / 2);
+ }
+ else
+ {
+ dc.DrawText(label, label_rect.x +
+ (label_rect.GetWidth() - label_size.GetWidth()) / 2,
+ label_rect.y +
+ (label_rect.GetHeight() - label_size.GetHeight()) / 2);
+ }
+
+ if ( has_ext_button )
+ {
+ if ( wnd->IsExtButtonHovered() )
+ {
+ dc.SetPen(m_panel_hover_button_border_pen);
+ dc.SetBrush(m_panel_hover_button_background_brush);
+ dc.DrawRoundedRectangle(label_rect.GetRight(), label_rect.GetBottom() - 13, 13, 13, 1.0);
+ dc.DrawBitmap(m_panel_extension_bitmap[1], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true);
+ }
+ else
+ dc.DrawBitmap(m_panel_extension_bitmap[0], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true);
+ }
+ }
+
+ if ( wnd->IsHovered() )
+ {
+ wxRect client_rect(true_rect);
+ client_rect.x++;
+ client_rect.width -= 2;
+ client_rect.y++;
+ client_rect.height -= 2 + label_height;
+ if ( client_rect.width > 0 && client_rect.height > 0 )
+ DrawPartialPageBackground(dc, wnd, client_rect, true);
+ }
+
+ if ( !wnd->IsHovered() )
+ DrawPanelBorder(dc, true_rect, m_panel_border_pen, m_panel_border_gradient_pen);
+ else
+ DrawPanelBorder(dc, true_rect, m_panel_hover_border_pen, m_panel_hover_border_gradient_pen);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawGalleryBackground(
+ wxDC& dc,
+ wxRibbonGallery* wnd,
+ const wxRect& rect)
+{
+ DrawPartialPageBackground(dc, wnd, rect);
+
+ if ( wnd->IsHovered() )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(m_gallery_hover_background_brush);
+ if ( m_flags & wxRIBBON_BAR_FLOW_VERTICAL )
+ {
+ dc.DrawRectangle(rect.x + 1, rect.y + 1, rect.width - 2,
+ rect.height - 16);
+ }
+ else
+ {
+ dc.DrawRectangle(rect.x + 1, rect.y + 1, rect.width - 16,
+ rect.height - 2);
+ }
+ }
+
+ dc.SetPen(m_gallery_border_pen);
+ // Outline
+ dc.DrawLine(rect.x + 1, rect.y, rect.x + rect.width - 1, rect.y);
+ dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
+ dc.DrawLine(rect.x + 1, rect.y + rect.height - 1, rect.x + rect.width - 1,
+ rect.y + rect.height - 1);
+ dc.DrawLine(rect.x + rect.width - 1, rect.y + 1, rect.x + rect.width - 1,
+ rect.y + rect.height - 1);
+
+ DrawGalleryBackgroundCommon(dc, wnd, rect);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawButtonBarBackground(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect)
+{
+ DrawPartialPageBackground(dc, wnd, rect, true);
+}
+
+void wxRibbonMSWFlatArtProvider::DrawToolBarBackground(
+ wxDC& dc,
+ wxWindow* wnd,
+ const wxRect& rect)
+{
+ DrawPartialPageBackground(dc, wnd, rect);
+}
+
+void
+wxRibbonMSWFlatArtProvider::DrawToggleButton(wxDC& dc,
+ wxRibbonBar* wnd,
+ const wxRect& rect,
+ wxRibbonDisplayMode mode)
+{
+ int bindex = 0;
+ DrawPartialPageBackground(dc, wnd, rect, false);
+
+ dc.DestroyClippingRegion();
+ dc.SetClippingRegion(rect);
+
+ if ( wnd->IsToggleButtonHovered() )
+ {
+ dc.SetPen(m_ribbon_toggle_pen);
+ dc.SetBrush(m_ribbon_toggle_brush);
+ dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 20, 20, 1.0);
+ bindex = 1;
+ }
+ switch ( mode )
+ {
+ case wxRIBBON_BAR_PINNED:
+ dc.DrawBitmap(m_ribbon_toggle_up_bitmap[bindex], rect.GetX()+7, rect.GetY()+6, true);
+ break;
+ case wxRIBBON_BAR_MINIMIZED:
+ dc.DrawBitmap(m_ribbon_toggle_down_bitmap[bindex], rect.GetX()+7, rect.GetY()+6, true);
+ break;
+ case wxRIBBON_BAR_EXPANDED:
+ dc.DrawBitmap(m_ribbon_toggle_pin_bitmap[bindex], rect.GetX()+4, rect.GetY()+5, true);
+ break;
+ }
+}
+
+void wxRibbonMSWFlatArtProvider::DrawHelpButton(wxDC& dc,
+ wxRibbonBar* wnd,
+ const wxRect& rect)
+{
+ DrawPartialPageBackground(dc, wnd, rect, false);
+
+ dc.DestroyClippingRegion();
+ dc.SetClippingRegion(rect);
+
+ if ( wnd->IsHelpButtonHovered() )
+ {
+ dc.SetPen(m_ribbon_toggle_pen);
+ dc.SetBrush(m_ribbon_toggle_brush);
+ dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 20, 20, 1.0);
+ dc.DrawBitmap(m_ribbon_bar_help_button_bitmap[1], rect.GetX()+4, rect.GetY()+5, true);
+ }
+ else
+ {
+ dc.DrawBitmap(m_ribbon_bar_help_button_bitmap[0], rect.GetX()+4, rect.GetY()+5, true);
+ }
+}
+
+void wxRibbonMSWFlatArtProvider::DrawTool(
+ wxDC& dc,
+ wxWindow* WXUNUSED(wnd),
+ const wxRect& rect,
+ const wxBitmap& bitmap,
+ wxRibbonButtonKind kind,
+ long state)
+{
+ if ( kind == wxRIBBON_BUTTON_TOGGLE )
+ {
+ if ( state & wxRIBBON_TOOLBAR_TOOL_TOGGLED )
+ state ^= wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
+ }
+
+ wxRect bg_rect(rect);
+ bg_rect.Deflate(1);
+ if ( (state & wxRIBBON_TOOLBAR_TOOL_LAST) == 0 )
+ bg_rect.width++;
+ bool is_split_hybrid = (kind == wxRIBBON_BUTTON_HYBRID && (state &
+ (wxRIBBON_TOOLBAR_TOOL_HOVER_MASK | wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK)));
+
+ // Background - single solid fill
+ wxColour bg_colour = m_tool_background_colour;
+ if ( state & wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK )
+ bg_colour = m_tool_active_background_colour;
+ else if ( state & wxRIBBON_TOOLBAR_TOOL_HOVER_MASK )
+ bg_colour = m_tool_hover_background_colour;
+
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(bg_colour));
+ dc.DrawRectangle(bg_rect.x, bg_rect.y, bg_rect.width, bg_rect.height);
+
+ if ( is_split_hybrid )
+ {
+ wxRect nonrect(bg_rect);
+ if ( state & (wxRIBBON_TOOLBAR_TOOL_DROPDOWN_HOVERED |
+ wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE) )
+ {
+ nonrect.width -= 8;
+ }
+ else
+ {
+ nonrect.x += nonrect.width - 8;
+ nonrect.width = 8;
+ }
+ wxBrush B(m_tool_hover_background_top_colour);
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(B);
+ dc.DrawRectangle(nonrect.x, nonrect.y, nonrect.width, nonrect.height);
+ }
+
+ // Border
+ dc.SetPen(m_toolbar_border_pen);
+ if ( state & wxRIBBON_TOOLBAR_TOOL_FIRST )
+ {
+ dc.DrawPoint(rect.x + 1, rect.y + 1);
+ dc.DrawPoint(rect.x + 1, rect.y + rect.height - 2);
+ }
+ else
+ dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
+
+ if ( state & wxRIBBON_TOOLBAR_TOOL_LAST )
+ {
+ dc.DrawPoint(rect.x + rect.width - 2, rect.y + 1);
+ dc.DrawPoint(rect.x + rect.width - 2, rect.y + rect.height - 2);
+ }
+
+ // Foreground
+ int avail_width = bg_rect.GetWidth();
+ if ( kind & wxRIBBON_BUTTON_DROPDOWN )
+ {
+ avail_width -= 8;
+ if ( is_split_hybrid )
+ {
+ dc.DrawLine(rect.x + avail_width + 1, rect.y,
+ rect.x + avail_width + 1, rect.y + rect.height);
+ }
+ dc.DrawBitmap(m_toolbar_drop_bitmap, bg_rect.x + avail_width + 2,
+ bg_rect.y + (bg_rect.height / 2) - 2, true);
+ }
+ dc.DrawBitmap(bitmap, bg_rect.x + (avail_width - bitmap.GetLogicalWidth()) / 2,
+ bg_rect.y + (bg_rect.height - bitmap.GetLogicalHeight()) / 2, true);
+}
+
+#endif // wxUSE_RIBBON
diff --git a/src/ribbon/descrip.mms b/src/ribbon/descrip.mms
index 3d5f93f7a7..31ee4118b0 100644
--- a/src/ribbon/descrip.mms
+++ b/src/ribbon/descrip.mms
@@ -43,11 +43,11 @@ CC_DEFINE =
.c.obj :
cc $(CFLAGS)$(CC_DEFINE) $(MMS$TARGET_NAME).c
-OBJECTS=art_aui.obj,art_internal.obj,art_msw.obj,bar.obj,buttonbar.obj,\
+OBJECTS=art_aui.obj,art_internal.obj,art_msw.obj,art_msw_flat.obj,bar.obj,buttonbar.obj,\
control_ribbon.obj,gallery.obj,page.obj,panel.obj,\
toolbar_ribbon.obj
-SOURCES=art_aui.cpp art_internal.cpp art_msw.cpp bar.cpp buttonbar.cpp\
+SOURCES=art_aui.cpp art_internal.cpp art_msw.cpp art_msw_flat.cpp bar.cpp buttonbar.cpp\
control.cpp gallery.cpp page.cpp panel.cpp toolbar.cpp
all : $(SOURCES)
@@ -73,6 +73,7 @@ $(OBJECTS) : [--.include.wx]setup.h
art_aui.obj : art_aui.cpp
art_internal.obj : art_internal.cpp
art_msw.obj : art_msw.cpp
+art_msw_flat.obj : art_msw_flat.cpp
bar.obj : bar.cpp
buttonbar.obj : buttonbar.cpp
control_ribbon.obj : control.cpp