diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h index 0c676c36fe..42fb8f73d4 100644 --- a/docs/doxygen/overviews/xrc_format.h +++ b/docs/doxygen/overviews/xrc_format.h @@ -340,8 +340,9 @@ or translations are done. @subsection overview_xrcformat_type_bitmap Bitmap -Bitmap properties contain specification of a single bitmap or icon. In the most -basic form, their text value is simply a relative URL of the bitmap to use. +Bitmap properties contain specification of a single bitmap, icon, a set of bitmaps +or SVG file. In the most basic form, their text value is simply a relative URL of +the bitmap to use. For example: @code @@ -363,6 +364,31 @@ percent-encoded, e.g. here is the correct way to specify a bitmap with the path Bitmap file paths can include environment variables that are expanded if wxXRC_USE_ENVVARS was passed to the wxXmlResource constructor. +It is possible to specify the multi-resolution bitmap by a set of bitmaps or +an SVG file, which are mutually exclusive. The set of bitmaps should contain +one or more relative URLs of a bitmap, separated by @c ';'. +For example, to specify two bitmaps, to be used in standard and 200% DPI +scaling respectively, you could write: +@code +new.png;new_2x.png +@endcode + +Here the first bitmap is special, as its size determines the logical size of +the bitmap. In other words, this bitmap is the one used when DPI scaling +is not in effect. Any subsequent bitmaps can come in any order and will be used +when the DPI scaling factor is equal, or at least close, to the ratio of their +size to the size of the first bitmap. Using @c _2x naming convention here is common, +but @e not required, the names of the bitmaps can be arbitrary, e.g. +@code +new_32x32.png;new_64x64.png +@endcode +would work just as well. +When using SVG file you must also specify @c default_size attribute +(even if the size is specified in SVG file, it may be different from the size needed here): +@code +new.svg +@endcode + Alternatively, it is possible to specify the bitmap using wxArtProvider IDs. In this case, the property element has no textual value (filename) and instead has the @c stock_id XML attribute that contains stock art ID as accepted by diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h index 603b35eff4..85be98a649 100644 --- a/include/wx/xrc/xmlres.h +++ b/include/wx/xrc/xmlres.h @@ -583,6 +583,11 @@ public: const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), wxSize size = wxDefaultSize) wxOVERRIDE; + // Gets a bitmap bundle. + wxBitmapBundle GetBitmapBundle(const wxString& param = wxT("bitmap"), + const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), + wxSize size = wxDefaultSize) wxOVERRIDE; + // Gets an icon. wxIcon GetIcon(const wxString& param = wxT("icon"), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), diff --git a/include/wx/xrc/xmlreshandler.h b/include/wx/xrc/xmlreshandler.h index 7f132b99a9..531630dd7b 100644 --- a/include/wx/xrc/xmlreshandler.h +++ b/include/wx/xrc/xmlreshandler.h @@ -90,6 +90,9 @@ public: virtual wxBitmap GetBitmap(const wxXmlNode* node, const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), wxSize size = wxDefaultSize) = 0; + virtual wxBitmapBundle GetBitmapBundle(const wxString& param = wxT("bitmap"), + const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), + wxSize size = wxDefaultSize) = 0; virtual wxIcon GetIcon(const wxString& param = wxT("icon"), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), wxSize size = wxDefaultSize) = 0; @@ -332,6 +335,12 @@ protected: { return GetImpl()->GetBitmap(node, defaultArtClient, size); } + wxBitmapBundle GetBitmapBundle(const wxString& param = wxT("bitmap"), + const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), + wxSize size = wxDefaultSize) + { + return GetImpl()->GetBitmapBundle(param, defaultArtClient, size); + } wxIcon GetIcon(const wxString& param = wxT("icon"), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), wxSize size = wxDefaultSize) diff --git a/misc/schema/xrc_schema.rnc b/misc/schema/xrc_schema.rnc index 742190bc0c..49f56405f8 100644 --- a/misc/schema/xrc_schema.rnc +++ b/misc/schema/xrc_schema.rnc @@ -467,7 +467,8 @@ t_bitmap = t_url?, ( attribute stock_id { t_identifier}, attribute stock_client { t_identifier}? - )? + )?, + attribute default_size { t_size}? t_font = ( [xrc:p="o"] element size {_, t_float }* & diff --git a/samples/xrc/rc/controls.xrc b/samples/xrc/rc/controls.xrc index 13f0d85e4a..16853bffa9 100644 --- a/samples/xrc/rc/controls.xrc +++ b/samples/xrc/rc/controls.xrc @@ -994,12 +994,19 @@ lay them out using wxSizers, absolute positioning, everything you like! - 1 + 2 0 0 0 - 0 - 0 + 0,1 + 0,1 + + wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + + wxALIGN_CENTRE|wxALL 5 @@ -1007,6 +1014,20 @@ lay them out using wxSizers, absolute positioning, everything you like! stop.xpm + + wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + + + + wxALIGN_CENTRE|wxALL + 5 + + stop.xpm;stop_2x.xpm + + diff --git a/samples/xrc/rc/stop_2x.xpm b/samples/xrc/rc/stop_2x.xpm new file mode 100644 index 0000000000..ffef18dac0 --- /dev/null +++ b/samples/xrc/rc/stop_2x.xpm @@ -0,0 +1,196 @@ +/* XPM */ +static const char *const stop_xpm[] = { +"64 64 129 2", +" c None", +". c #C9CBC8", +"+ c #C3C4C1", +"@ c #C4C6C3", +"# c #C1C3C0", +"$ c #C3C5C2", +"% c #C3C3C0", +"& c #C4C4C1", +"* c #C2C4C1", +"= c #C6C6C3", +"- c #C0C2BF", +"; c #C7C9C6", +"> c #636662", +", c #201F1B", +"' c #242621", +") c #171B16", +"! c #1F221E", +"~ c #1E1B17", +"{ c #222621", +"] c #221F1B", +"^ c #1B1F1A", +"/ c #292622", +"( c #141713", +"_ c #5D605C", +": c #050904", +"< c #60635F", +"[ c #0F0904", +"} c #B50701", +"| c #E40600", +"1 c #850702", +"2 c #C8CAC7", +"3 c #616460", +"4 c #060A05", +"5 c #0E0904", +"6 c #A30701", +"7 c #FF0600", +"8 c #BB0701", +"9 c #0C0904", +"0 c #BC0701", +"a c #8E0702", +"b c #646763", +"c c #676A66", +"d c #AB0701", +"e c #FC0600", +"f c #9B0702", +"g c #5F625E", +"h c #0B0904", +"i c #B30701", +"j c #686B67", +"k c #5B5E5A", +"l c #090904", +"m c #9D0702", +"n c #FA0A04", +"o c #6C6F6B", +"p c #BABCB9", +"q c #AD0701", +"r c #F91B15", +"s c #E35651", +"t c #ED0600", +"u c #FE0802", +"v c #E95753", +"w c #EE211B", +"x c #CC6A66", +"y c #DA3630", +"z c #950702", +"A c #323631", +"B c #EC0600", +"C c #FE0903", +"D c #CAC8C5", +"E c #F23732", +"F c #EA524E", +"G c #CFB4B1", +"H c #FB150F", +"I c #E11D18", +"J c #EB4D48", +"K c #E85A55", +"L c #F62621", +"M c #F42D27", +"N c #E60903", +"O c #F2241E", +"P c #FA140E", +"Q c #EE433E", +"R c #EE1C16", +"S c #F50600", +"T c #FD0D07", +"U c #E6625D", +"V c #C48581", +"W c #F20B05", +"X c #CD6762", +"Y c #F03C36", +"Z c #FD0F09", +"` c #EF302A", +" . c #F62822", +".. c #E56661", +"+. c #FC100A", +"@. c #FA1A14", +"#. c #F91C16", +"$. c #F62823", +"%. c #F91D17", +"&. c #E70600", +"*. c #F03E39", +"=. c #FD0E08", +"-. c #DB534E", +";. c #BEC0BD", +">. c #10140F", +",. c #FD0C06", +"'. c #F90802", +"). c #D26A66", +"!. c #FB1510", +"~. c #FF0701", +"{. c #FE0600", +"]. c #110904", +"^. c #C50701", +"/. c #8A0702", +"(. c #1A0904", +"_. c #BF0701", +":. c #B60701", +"<. c #A40701", +"[. c #BA0701", +"}. c #080C07", +"|. c #1B0904", +"1. c #C70701", +"2. c #FD0600", +"3. c #920702", +"4. c #70736F", +"5. c #380803", +"6. c #340803", +"7. c #5C5F5B", +"8. c #BCBEBB", +". . . . . . . . . . . . . . . . . . . . + + @ @ # # $ $ $ $ % % @ @ & & * * = = - - * * . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . + + @ @ # # $ $ $ $ % % @ @ & & * * = = - - * * . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . ; ; > > , , ' ' ) ) ! ! ! ! ~ ~ { { ] ] ^ ^ / / ( ( ^ ^ > > ; ; . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . ; ; > > , , ' ' ) ) ! ! ! ! ~ ~ { { ] ] ^ ^ / / ( ( ^ ^ > > ; ; . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . _ _ : : : : : : : : : : : : : : : : : : : : : : : : : : : : _ _ . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . _ _ : : : : : : : : : : : : : : : : : : : : : : : : : : : : _ _ . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . < < : : [ [ } } | | | | | | | | | | | | | | | | | | | | 1 1 [ [ : : < < . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . < < : : [ [ } } | | | | | | | | | | | | | | | | | | | | 1 1 [ [ : : < < . . . . . . . . . . . . . . ", +". . . . . . . . . . 2 2 3 3 4 4 5 5 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 9 9 4 4 3 3 2 2 . . . . . . . . . . ", +". . . . . . . . . . 2 2 3 3 4 4 5 5 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 9 9 4 4 3 3 2 2 . . . . . . . . . . ", +". . . . . . . . 2 2 > > : : : : 0 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 a a : : : : > > 2 2 . . . . . . . . ", +". . . . . . . . 2 2 > > : : : : 0 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 a a : : : : > > 2 2 . . . . . . . . ", +". . . . . . . . b b : : : : 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 a a [ [ : : b b . . . . . . . . ", +". . . . . . . . b b : : : : 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 a a [ [ : : b b . . . . . . . . ", +". . . . . . c c : : 5 5 d d e e 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 f f 5 5 : : c c . . . . . . ", +". . . . . . c c : : 5 5 d d e e 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 f f 5 5 : : c c . . . . . . ", +". . - - g g 4 4 h h f f 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 i i h h 4 4 j j . . . . ", +". . - - g g 4 4 h h f f 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 i i h h 4 4 j j . . . . ", +"$ $ k k : : l l m m 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 n n 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 l l : : o o . . ", +"$ $ k k : : l l m m 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 n n 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 l l : : o o . . ", +"p p : : : : q q 7 7 r r . . . . s s t t . . . . . . . . . . . . u u v v . . . . w w 7 7 7 7 . . . . . . x x y y z z : : A A . . ", +"p p : : : : q q 7 7 r r . . . . s s t t . . . . . . . . . . . . u u v v . . . . w w 7 7 7 7 . . . . . . x x y y z z : : A A . . ", +"p p : : : : B B C C . . . . . . D D E E . . . . . . . . . . . . F F . . . . . . . . 7 7 7 7 . . . . . . . . G G B B : : A A . . ", +"p p : : : : B B C C . . . . . . D D E E . . . . . . . . . . . . F F . . . . . . . . 7 7 7 7 . . . . . . . . G G B B : : A A . . ", +"p p : : : : B B H H . . . . I I . . . . J J K K . . . . K K L L . . . . . . . . . . . . 7 7 . . . . K K . . . . B B : : A A . . ", +"p p : : : : B B H H . . . . I I . . . . J J K K . . . . K K L L . . . . . . . . . . . . 7 7 . . . . K K . . . . B B : : A A . . ", +"p p : : : : B B H H . . . . 7 7 . . . . 7 7 7 7 . . . . 7 7 M M . . . . 7 7 N N . . . . 7 7 . . . . 7 7 O O . . B B : : A A . . ", +"p p : : : : B B H H . . . . 7 7 . . . . 7 7 7 7 . . . . 7 7 M M . . . . 7 7 N N . . . . 7 7 . . . . 7 7 O O . . B B : : A A . . ", +"p p : : : : B B P P . . . . . . 7 7 7 7 7 7 7 7 . . . . 7 7 Q Q . . . . 7 7 7 7 . . . . 7 7 . . . . 7 7 R R . . B B : : A A . . ", +"p p : : : : B B P P . . . . . . 7 7 7 7 7 7 7 7 . . . . 7 7 Q Q . . . . 7 7 7 7 . . . . 7 7 . . . . 7 7 R R . . B B : : A A . . ", +"p p : : : : B B S S . . . . . . . . T T 7 7 7 7 . . . . 7 7 Q Q . . . . 7 7 7 7 . . . . 7 7 . . . . U U V V . . B B : : A A . . ", +"p p : : : : B B S S . . . . . . . . T T 7 7 7 7 . . . . 7 7 Q Q . . . . 7 7 7 7 . . . . 7 7 . . . . U U V V . . B B : : A A . . ", +"p p : : : : B B 7 7 W W X X . . . . . . 7 7 7 7 . . . . 7 7 Q Q . . . . 7 7 7 7 . . . . 7 7 . . . . . . . . . . B B : : A A . . ", +"p p : : : : B B 7 7 W W X X . . . . . . 7 7 7 7 . . . . 7 7 Q Q . . . . 7 7 7 7 . . . . 7 7 . . . . . . . . . . B B : : A A . . ", +"p p : : : : B B 7 7 7 7 7 7 Y Y . . . . Z Z 7 7 . . . . 7 7 Q Q . . . . 7 7 7 7 . . . . 7 7 . . . . . . . . ` ` B B : : A A . . ", +"p p : : : : B B 7 7 7 7 7 7 Y Y . . . . Z Z 7 7 . . . . 7 7 Q Q . . . . 7 7 7 7 . . . . 7 7 . . . . . . . . ` ` B B : : A A . . ", +"p p : : : : B B . .. . . . 7 7 ..... . +.+.7 7 . . . . 7 7 @.@.. . . . 7 7 #.#.. . . . 7 7 . . . . 7 7 7 7 7 7 B B : : A A . . ", +"p p : : : : B B . .. . . . 7 7 ..... . +.+.7 7 . . . . 7 7 @.@.. . . . 7 7 #.#.. . . . 7 7 . . . . 7 7 7 7 7 7 B B : : A A . . ", +"p p : : : : B B $.$.. . . . %.%.. . . . 7 7 7 7 . . . . 7 7 &.&.* * . . . . . . . . *.*.7 7 . . . . 7 7 7 7 7 7 B B : : A A . . ", +"p p : : : : B B $.$.. . . . %.%.. . . . 7 7 7 7 . . . . 7 7 &.&.* * . . . . . . . . *.*.7 7 . . . . 7 7 7 7 7 7 B B : : A A . . ", +"p p : : : : B B =.=.. . . . . . . . . . 7 7 7 7 . . . . 7 7 7 7 -.-.. . . . . . . . 7 7 7 7 . . . . 7 7 7 7 7 7 B B : : A A . . ", +"p p : : : : B B =.=.. . . . . . . . . . 7 7 7 7 . . . . 7 7 7 7 -.-.. . . . . . . . 7 7 7 7 . . . . 7 7 7 7 7 7 B B : : A A . . ", +";.;.>.>.: : q q 7 7 r r . . . . . . ,.,.7 7 7 7 . . . . 7 7 7 7 '.'.).).. . . . !.!.7 7 7 7 . . . . 7 7 7 7 7 7 z z : : A A . . ", +";.;.>.>.: : q q 7 7 r r . . . . . . ,.,.7 7 7 7 . . . . 7 7 7 7 '.'.).).. . . . !.!.7 7 7 7 . . . . 7 7 7 7 7 7 z z : : A A . . ", +". . o o : : l l } } 7 7 7 7 n n 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 C C ~.~.7 7 7 7 7 7 7 7 7 7 7 7 {.{.m m l l : : o o . . ", +". . o o : : l l } } 7 7 7 7 n n 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 C C ~.~.7 7 7 7 7 7 7 7 7 7 7 7 {.{.m m l l : : o o . . ", +". . . . j j 4 4 ].].^.^.7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 /./.: : 4 4 j j . . . . ", +". . . . j j 4 4 ].].^.^.7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 /./.: : 4 4 j j . . . . ", +". . . . . . c c : : (.(._._.7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 e e d d 5 5 : : c c . . . . . . ", +". . . . . . c c : : (.(._._.7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 e e d d 5 5 : : c c . . . . . . ", +". . . . . . . . b b : : [ [ :.:.7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 f f : : : : b b . . . . . . . . ", +". . . . . . . . b b : : [ [ :.:.7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 f f : : : : b b . . . . . . . . ", +". . . . . . . . 2 2 > > : : 9 9 0 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 <.<.9 9 : : > > 2 2 . . . . . . . . ", +". . . . . . . . 2 2 > > : : 9 9 0 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 <.<.9 9 : : > > 2 2 . . . . . . . . ", +". . . . . . . . . . 2 2 3 3 4 4 5 5 8 8 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 {.{.[.[.5 5 }.}.3 3 2 2 . . . . . . . . . . ", +". . . . . . . . . . 2 2 3 3 4 4 5 5 8 8 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 {.{.[.[.5 5 }.}.3 3 2 2 . . . . . . . . . . ", +". . . . . . . . . . . . . . < < : : |.|.1.1.7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 2.2.3.3.: : : : 4.4.. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . < < : : |.|.1.1.7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 2.2.3.3.: : : : 4.4.. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . _ _ : : ].].5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.6.6.: : : : _ _ . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . _ _ : : ].].5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.6.6.: : : : _ _ . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . ; ; 7.7.: : : : : : : : : : : : : : : : : : : : : : : : 7.7.; ; . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . ; ; 7.7.: : : : : : : : : : : : : : : : : : : : : : : : 7.7.; ; . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . ; ; 8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.; ; . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . ; ; 8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.8.; ; . . . . . . . . . . . . . . . . . . "}; diff --git a/src/xrc/xh_bttn.cpp b/src/xrc/xh_bttn.cpp index 5fa3b8867d..033eab2a57 100644 --- a/src/xrc/xh_bttn.cpp +++ b/src/xrc/xh_bttn.cpp @@ -49,7 +49,7 @@ wxObject *wxButtonXmlHandler::DoCreateResource() if ( GetParamNode("bitmap") ) { - button->SetBitmap(GetBitmap("bitmap", wxART_BUTTON), + button->SetBitmap(GetBitmapBundle("bitmap", wxART_BUTTON), GetDirection("bitmapposition")); } diff --git a/src/xrc/xh_cmdlinkbn.cpp b/src/xrc/xh_cmdlinkbn.cpp index 06b8a65744..d4e3654a0d 100644 --- a/src/xrc/xh_cmdlinkbn.cpp +++ b/src/xrc/xh_cmdlinkbn.cpp @@ -48,7 +48,7 @@ wxObject *wxCommandLinkButtonXmlHandler::DoCreateResource() if ( GetParamNode("bitmap") ) { - button->SetBitmap(GetBitmap("bitmap", wxART_BUTTON), + button->SetBitmap(GetBitmapBundle("bitmap", wxART_BUTTON), GetDirection("bitmapposition")); } diff --git a/src/xrc/xh_stbmp.cpp b/src/xrc/xh_stbmp.cpp index 2cb248b24c..230d7e5718 100644 --- a/src/xrc/xh_stbmp.cpp +++ b/src/xrc/xh_stbmp.cpp @@ -33,7 +33,7 @@ wxObject *wxStaticBitmapXmlHandler::DoCreateResource() bmp->Create(m_parentAsWindow, GetID(), - GetBitmap(wxT("bitmap"), wxART_OTHER, GetSize()), + GetBitmapBundle(wxT("bitmap"), wxART_OTHER, GetSize()), GetPosition(), GetSize(), GetStyle(), GetName()); diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 046b0004c4..e83229b612 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -1852,6 +1852,52 @@ bool GetStockArtAttrs(const wxXmlNode *paramNode, return false; } +// Load a bitmap from a file system element. +wxBitmap LoadBitmapFromFS(wxXmlResourceHandlerImpl* impl, + const wxString& path, + wxSize size, + const wxString& nodeName) +{ + if (path.empty()) return wxNullBitmap; +#if wxUSE_FILESYSTEM + wxFSFile *fsfile = impl->GetCurFileSystem().OpenFile(path, wxFS_READ | wxFS_SEEKABLE); + if (fsfile == NULL) + { + impl->ReportParamError + ( + nodeName, + wxString::Format("cannot open bitmap resource \"%s\"", path) + ); + return wxNullBitmap; + } + wxImage img(*(fsfile->GetStream())); + delete fsfile; +#else + wxImage img(name); +#endif + + if (!img.IsOk()) + { + impl->ReportParamError + ( + nodeName, + wxString::Format("cannot create bitmap from \"%s\"", path) + ); + return wxNullBitmap; + } + if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y); + return wxBitmap(img); +} + +// forward declaration +template +T +ParseStringInPixels(wxXmlResourceHandlerImpl* impl, + const wxString& param, + const wxString& str, + const T& defaultValue, + wxWindow *windowToUse = NULL); + } // anonymous namespace wxBitmap wxXmlResourceHandlerImpl::GetBitmap(const wxString& param, @@ -1892,36 +1938,126 @@ wxBitmap wxXmlResourceHandlerImpl::GetBitmap(const wxXmlNode* node, } /* ...or load the bitmap from file: */ - wxString name = GetFilePath(node); - if (name.empty()) return wxNullBitmap; -#if wxUSE_FILESYSTEM - wxFSFile *fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE); - if (fsfile == NULL) - { - ReportParamError - ( - node->GetName(), - wxString::Format("cannot open bitmap resource \"%s\"", name) - ); - return wxNullBitmap; - } - wxImage img(*(fsfile->GetStream())); - delete fsfile; -#else - wxImage img(name); -#endif + return LoadBitmapFromFS(this, GetFilePath(node), size, node->GetName()); +} - if (!img.IsOk()) + +wxBitmapBundle wxXmlResourceHandlerImpl::GetBitmapBundle(const wxString& param, + const wxArtClient& defaultArtClient, + wxSize size) +{ + wxASSERT_MSG( !param.empty(), "bitmap parameter name can't be empty" ); + + const wxXmlNode* const node = GetParamNode(param); + + if ( !node ) { - ReportParamError - ( - node->GetName(), - wxString::Format("cannot create bitmap from \"%s\"", name) - ); + // this is not an error as bitmap parameter could be optional return wxNullBitmap; } - if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y); - return wxBitmap(img); + + /* If the bitmap is specified as stock item, query wxArtProvider for it: */ + wxString art_id, art_client; + if ( GetStockArtAttrs(node, defaultArtClient, + art_id, art_client) ) + { + wxBitmapBundle stockArt(wxArtProvider::GetBitmapBundle(art_id, art_client, size)); + if ( stockArt.IsOk() ) + return stockArt; + } + + wxBitmapBundle bitmapBundle; + wxString paramValue = GetParamValue(node); + if ( paramValue.EndsWith(".svg") ) + { + if ( paramValue.Contains(";") ) + { + ReportParamError + ( + param, + "may contain either one SVG file or a list of files separated by ';'" + ); + return bitmapBundle; + } + + // it is a bundle from svg file + wxString svgDefaultSizeAttr = node->GetAttribute("default_size", ""); + if ( svgDefaultSizeAttr.empty() ) + { + ReportParamError + ( + param, + "'default_size' attribute required with svg file" + ); + } + else + { +#ifdef wxHAS_SVG + wxSize svgDefaultSize = ParseStringInPixels(this, param, svgDefaultSizeAttr, wxDefaultSize); +#if wxUSE_FILESYSTEM + wxFSFile* fsfile = GetCurFileSystem().OpenFile(paramValue, wxFS_READ | wxFS_SEEKABLE); + if (fsfile == NULL) + { + ReportParamError + ( + param, + wxString::Format("cannot open SVG resource \"%s\"", paramValue) + ); + } + else + { + wxInputStream* s = fsfile->GetStream(); + const size_t len = static_cast(s->GetLength()); + wxCharBuffer buf(len); + char* const ptr = buf.data(); + + if (s->ReadAll(ptr, len)) + { + bitmapBundle = wxBitmapBundle::FromSVG(ptr, svgDefaultSize); + } + delete fsfile; + } +#else + bitmapBundle = wxBitmapBundle::FromSVGFile(paramValue, svgDefaultSize); +#endif +#else // !wxHAS_SVG + ReportParamError + ( + param, + "SVG bitmaps are not supported in this build of the library" + ); +#endif // wxHAS_SVG/!wxHAS_SVG + } + } + else + { + if ( paramValue.Contains(".svg;") ) + { + ReportParamError + ( + param, + "may contain either one SVG file or a list of files separated by ';'" + ); + return bitmapBundle; + } + + // it is a bundle from bitmaps + wxVector bitmaps; + wxArrayString paths = wxSplit(paramValue, ';', '\0'); + for ( wxArrayString::const_iterator i = paths.begin(); i != paths.end(); ++i ) + { + wxBitmap bmpNext = LoadBitmapFromFS(this, *i, size, param); + if ( !bmpNext.IsOk() ) + { + // error in loading wxBitmap, return invalid wxBitmapBundle + return bitmapBundle; + } + bitmaps.push_back(bmpNext); + } + bitmapBundle = wxBitmapBundle::FromBitmaps(bitmaps); + } + + return bitmapBundle; } @@ -2182,17 +2318,17 @@ void XRCConvertFromDLU(wxWindow* w, T& value) value = w->ConvertDialogToPixels(value); } -// Helper for parsing values (of type T, for which XRCConvertFromAbsValue() and -// XRCConvertFromDLU() functions must be defined) which can be expressed either -// in pixels or dialog units. +// Helper for parsing strings which contain values (of type T, for which +// XRCConvertFromAbsValue() and XRCConvertFromDLU() functions must be defined) +// which can be expressed either in pixels or dialog units. template T -ParseValueInPixels(wxXmlResourceHandlerImpl* impl, +ParseStringInPixels(wxXmlResourceHandlerImpl* impl, const wxString& param, + const wxString& s, const T& defaultValue, - wxWindow *windowToUse = NULL) + wxWindow *windowToUse) { - const wxString s = impl->GetParamValue(param); if ( s.empty() ) return defaultValue; @@ -2235,6 +2371,17 @@ ParseValueInPixels(wxXmlResourceHandlerImpl* impl, return value; } +// Helper for parsing values which uses ParseStringInPixels() above. +template +T +ParseValueInPixels(wxXmlResourceHandlerImpl* impl, + const wxString& param, + const T& defaultValue, + wxWindow *windowToUse = NULL) +{ + return ParseStringInPixels(impl, param, impl->GetParamValue(param), defaultValue, windowToUse); +} + } // anonymous namespace wxSize wxXmlResourceHandlerImpl::GetSize(const wxString& param,